From 1833e1e095539c2d2e444b12bcdf1e6d2e70ebcb Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 12 Nov 2023 21:44:36 +0100 Subject: [PATCH 001/215] Canvas for a new FixMath paradigm --- FixMath2.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 FixMath2.h diff --git a/FixMath2.h b/FixMath2.h new file mode 100644 index 000000000..48849d599 --- /dev/null +++ b/FixMath2.h @@ -0,0 +1,36 @@ +/* + * FixMath2.h + * + * Copyright 2012 Tim Barrass + * + * This file is part of Mozzi. + * + * Mozzi is licensed under a Creative Commons + * Attribution-NonCommercial-ShareAlike 4.0 International License. + * + */ + + +#ifndef FIXMATH2_H_ +#define FIXMATH2_H_ + +#include "IntegerType.h" + +#define SHIFTR(x,bits) (bits > 0 ? (x) >> (bits) : (x) << (-bits)) // shift right for positive shift numbers, and left for negative ones. + +template +class FixMath2 +{ + public: + + private: + // use of the IntegerType for that? +}; + + + + + + + +#endif From bcd202ed8bddd393d640aa3864c72e09ab2f422c Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 13 Nov 2023 22:29:12 +0100 Subject: [PATCH 002/215] Added initial constructors (untested) for FixMath2 --- FixMath2.h | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 48849d599..a5f176c51 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -18,19 +18,25 @@ #define SHIFTR(x,bits) (bits > 0 ? (x) >> (bits) : (x) << (-bits)) // shift right for positive shift numbers, and left for negative ones. -template -class FixMath2 +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +class UFixMath2 { public: + /** Constructor + */ + UFixMath2() {;} + UfixMath2(float fl) {internal_value = static_cast>3)> > (fl * (1 << NF));} + UfixMath2(typename IntegerType<((NI)>>3)> integral_part, typename IntegerType<((NF)>>3)>fractionnal_part) + { + internal_value = (integral_part << NI) + fractionnal_part; + } // probably a more confusing than anything constructor! + + float asFloat() { return (static_cast(internal_value)) / (1<>3) >::unsigned_type getInt() { return internal_value; } private: - // use of the IntegerType for that? + typename IntegerType< ((NI+NF)>>3) >::unsigned_type internal_value; + }; - - - - - - #endif From cb2ee4fe9661da6582096c0031c5cce8a3112e71 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 13 Nov 2023 22:49:34 +0100 Subject: [PATCH 003/215] Fixed usage of IntegerType --- FixMath2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index a5f176c51..851076096 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -25,8 +25,8 @@ class UFixMath2 /** Constructor */ UFixMath2() {;} - UfixMath2(float fl) {internal_value = static_cast>3)> > (fl * (1 << NF));} - UfixMath2(typename IntegerType<((NI)>>3)> integral_part, typename IntegerType<((NF)>>3)>fractionnal_part) + UfixMath2(float fl) {internal_value = static_cast>3)>::unsigned_type > (fl * (1 << NF));} + UfixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) { internal_value = (integral_part << NI) + fractionnal_part; } // probably a more confusing than anything constructor! From 5f4ad47e6b4fc183b9a0673d2b99700cc26f89e6 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 14 Nov 2023 21:11:22 +0100 Subject: [PATCH 004/215] BugFix for conversion to/from float. More readable --- FixMath2.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 851076096..03afea551 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -21,21 +21,22 @@ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath2 { + typedef typename IntegerType< ((NI+NF)>>3) >::unsigned_type internal_type ; public: /** Constructor */ UFixMath2() {;} - UfixMath2(float fl) {internal_value = static_cast>3)>::unsigned_type > (fl * (1 << NF));} - UfixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) + UFixMath2(float fl) {internal_value = static_cast (fl * (internal_type(1) << NF));} + UFixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) { internal_value = (integral_part << NI) + fractionnal_part; } // probably a more confusing than anything constructor! - float asFloat() { return (static_cast(internal_value)) / (1<>3) >::unsigned_type getInt() { return internal_value; } + float asFloat() { return (static_cast(internal_value)) / (internal_type(1)<>3) >::unsigned_type internal_value; + internal_type internal_value; }; From 69388cdb028d6bcaec8568b3498b5c6b3037a683 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 14 Nov 2023 21:52:58 +0100 Subject: [PATCH 005/215] Multiplication overload of FixMath2 --- FixMath2.h | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 03afea551..a0b951929 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -22,7 +22,7 @@ template // NI and NF being the number of bits for the integra class UFixMath2 { typedef typename IntegerType< ((NI+NF)>>3) >::unsigned_type internal_type ; - public: +public: /** Constructor */ UFixMath2() {;} @@ -32,10 +32,37 @@ class UFixMath2 internal_value = (integral_part << NI) + fractionnal_part; } // probably a more confusing than anything constructor! + + // Constructor from another fixed type + template + UFixMath2(UFixMath2<_NI,_NF> uf) {internal_value = SHIFTR((internal_type) uf.getInt(),(_NF-NF));} + + // Multiplication overload + template + internal_type operator* (const UFixMath2<_NI,_NF> op) + { + byte sub = (NF+_NF)>>1; + Serial.println(sub); + return (internal_value>>sub) * (op.getInt() >> (NF+_NF-sub)); + + } float asFloat() { return (static_cast(internal_value)) / (internal_type(1)<>1; + return (internal_value>>sub) * (op.getInt() >> (NF+op.getNF()-sub)); + + }*/ + + + byte getNI(){return NI;} + byte getNF(){return NF;} + +private: internal_type internal_value; }; From 48f827f0ba2746252d5a23bb5f5032d00c27dcc0 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 14 Nov 2023 21:54:51 +0100 Subject: [PATCH 006/215] Small optimisation on const --- FixMath2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index a0b951929..2cb24b4a5 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -35,11 +35,11 @@ class UFixMath2 // Constructor from another fixed type template - UFixMath2(UFixMath2<_NI,_NF> uf) {internal_value = SHIFTR((internal_type) uf.getInt(),(_NF-NF));} + UFixMath2(const UFixMath2<_NI,_NF>& uf) {internal_value = SHIFTR((internal_type) uf.getInt(),(_NF-NF));} // Multiplication overload template - internal_type operator* (const UFixMath2<_NI,_NF> op) + internal_type operator* (const UFixMath2<_NI,_NF>& op) { byte sub = (NF+_NF)>>1; Serial.println(sub); From c3466d145a5dcbf553c549310da48d98299c643f Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 15 Nov 2023 00:06:24 +0100 Subject: [PATCH 007/215] Fixed multiplication, doc --- FixMath2.h | 60 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 2cb24b4a5..41d4a0c97 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -17,51 +17,73 @@ #include "IntegerType.h" #define SHIFTR(x,bits) (bits > 0 ? (x) >> (bits) : (x) << (-bits)) // shift right for positive shift numbers, and left for negative ones. +#define MAX(N1,N2) (N1 > N2 ? N1 : N2) template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath2 { typedef typename IntegerType< ((NI+NF)>>3) >::unsigned_type internal_type ; + public: /** Constructor */ UFixMath2() {;} + + /* Float and double constructor specialization */ UFixMath2(float fl) {internal_value = static_cast (fl * (internal_type(1) << NF));} + UFixMath2(double fl) {internal_value = static_cast (fl * (internal_type(1) << NF));} + + /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ + template + UFixMath2(T value,bool as_frac=false) + { + if (as_frac) internal_value = value; + else internal_value = (internal_type(value) << NF); + } + + /* Constructor from different integer and fractionnal part, to remove? */ UFixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) { internal_value = (integral_part << NI) + fractionnal_part; - } // probably a more confusing than anything constructor! + } // probably a more confusing than anything constructor! TO REMOVE - // Constructor from another fixed type + /* Constructor from another fixed type */ template - UFixMath2(const UFixMath2<_NI,_NF>& uf) {internal_value = SHIFTR((internal_type) uf.getInt(),(_NF-NF));} + UFixMath2(const UFixMath2<_NI,_NF>& uf) {internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type) uf.getInt(),(_NF-NF));} + // Multiplication overload template - internal_type operator* (const UFixMath2<_NI,_NF>& op) + UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) { - byte sub = (NF+_NF)>>1; - Serial.println(sub); - return (internal_value>>sub) * (op.getInt() >> (NF+_NF-sub)); + + + /* version 1, prior promotion/demotion to return type, safe */ + /* byte sub = NF>>1; + internal_type tt = (internal_value>>sub) * (UFixMath2(op).getInt() >> (sub)); + return UFixMath2(tt,true);*/ + + /* version 2, optimisation (?) of the former: one shift instead of two (at cast and here) + Keeps the bigger type for the operand, shift it by the appropriate number, cast it to the final type (which might be the same) and multiply by the internal_value, shifted of course */ + byte sub = NF>>1; + internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); + return UFixMath2(tt,true); + + /* version 3, post shifting, unsafe, but precise... If you do not overload it */ + /* internal_type tt = (internal_value * internal_type(op.getInt())) >> _NF; + return UFixMath2(tt,true);*/ + } + float asFloat() { return (static_cast(internal_value)) / (internal_type(1)<>1; - return (internal_value>>sub) * (op.getInt() >> (NF+op.getNF()-sub)); - - }*/ - byte getNI(){return NI;} - byte getNF(){return NF;} - + /* byte getNI(){return NI;} + byte getNF(){return NF;} + */ private: internal_type internal_value; From 7377cdc4286f4af0d22586439c5da93828f542d6 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 15 Nov 2023 22:11:37 +0100 Subject: [PATCH 008/215] Switched to multiply returns compound fix type --- FixMath2.h | 103 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 41d4a0c97..a4774699e 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -22,7 +22,8 @@ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath2 { - typedef typename IntegerType< ((NI+NF)>>3) >::unsigned_type internal_type ; + typedef typename IntegerType<((NI+NF)>>3)>::unsigned_type internal_type ; + typedef typename IntegerType<((NI+NF)>>3)+1>::unsigned_type next_greater_type ; public: /** Constructor @@ -30,9 +31,14 @@ class UFixMath2 UFixMath2() {;} /* Float and double constructor specialization */ - UFixMath2(float fl) {internal_value = static_cast (fl * (internal_type(1) << NF));} - UFixMath2(double fl) {internal_value = static_cast (fl * (internal_type(1) << NF));} + /* UFixMath2(float fl) {internal_value = static_cast (fl * (internal_type(1) << NF));} + UFixMath2(double fl) {internal_value = static_cast (fl * (internal_type(1) << NF));} + */ + UFixMath2(float fl) {internal_value = static_cast(fl * (next_greater_type(1) << NF));} + + UFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } + /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ template UFixMath2(T value,bool as_frac=false) @@ -53,31 +59,86 @@ class UFixMath2 UFixMath2(const UFixMath2<_NI,_NF>& uf) {internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type) uf.getInt(),(_NF-NF));} - // Multiplication overload + // Multiplication overload, returns the compound type template - UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) + UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) { + typedef typename IntegerType< ((NI+_NI+NF+_NF)>>3) >::unsigned_type return_type ; + return_type tt = return_type(internal_value)*op.getInt(); + return UFixMath2(tt,true); + + } + /* template + UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) + {*/ - /* version 1, prior promotion/demotion to return type, safe */ - /* byte sub = NF>>1; - internal_type tt = (internal_value>>sub) * (UFixMath2(op).getInt() >> (sub)); - return UFixMath2(tt,true);*/ - - /* version 2, optimisation (?) of the former: one shift instead of two (at cast and here) - Keeps the bigger type for the operand, shift it by the appropriate number, cast it to the final type (which might be the same) and multiply by the internal_value, shifted of course */ - byte sub = NF>>1; - internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); - return UFixMath2(tt,true); - - /* version 3, post shifting, unsafe, but precise... If you do not overload it */ - /* internal_type tt = (internal_value * internal_type(op.getInt())) >> _NF; - return UFixMath2(tt,true);*/ + /* version 1, prior promotion/demotion to return type, safe */ + /* byte sub = NF>>1; + internal_type tt = (internal_value>>sub) * (UFixMath2(op).getInt() >> (sub)); + return UFixMath2(tt,true);*/ + + /* version 2, optimisation (?) of the former: one shift instead of two (at cast and here) + Keeps the bigger type for the operand, shift it by the appropriate number, cast it to the final type (which might be the same) and multiply by the internal_value, shifted of course */ + /* byte sub = NF>>1; + internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); + return UFixMath2(tt,true);*/ + + /* version 3, post shifting, unsafe, but precise... If you do not overload it */ + /* internal_type tt = (internal_value * internal_type(op.getInt())) >> _NF; + return UFixMath2(tt,true);*/ + + /* version 4, tries to keep maximum precision by */ + /* if (NF+NI <= _NF+_NI) // Is that optimized away??? + { + byte sub = (NF+NI)>>1; + internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NI+_NF-sub)))); + return UFixMath2(tt,true); + } + else + { + byte sub = _NF+_NI; + internal_type tt = (internal_value>>sub) * internal_type(op.getInt()); + //((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); + return UFixMath2(tt,true); + }*/ + + /* if (NF+NI>_NF+NI) + { + byte sub = _NF; + //internal_type tt = (internal_value >> (_NF+_NI)) * internal_type(op.getInt()); + internal_type tt = (internal_value >>(sub) * internal_type(op.getInt())); + return UFixMath2(tt,true); + } + else if (NF+NI==_NF+NI) + { + byte sub = (_NF + _NI)>>2; + //internal_type tt = (internal_value >> (_NF+_NI)) * internal_type(op.getInt()); + internal_type tt = (internal_value >>sub) * (internal_type(op.getInt())>>sub); + Serial.print(" "); + Serial.println(tt); + return UFixMath2(tt,true); + } + return 0;*/ - } + /* Keep it simple */ + + + ///////////// TODO, PROMOTE TO THE BIGGEST ONE? + // Ou plutot, ramener les deux au bon nombre de virgule/2, puis multiplier ? En fait c'est ma version 1/2... + // Working, more or less, except for multiplying a small with a big (and expecting a big) + + //internal_type tt = ((internal_value>>sub) * (UFixMath2(op).getInt())>>sub); + /* byte sub = (_NF+NF)>>1; + internal_type tt = ((internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub))))); + return UFixMath2(tt,true); + + + }*/ + - float asFloat() { return (static_cast(internal_value)) / (internal_type(1)<(internal_value)) / (typename IntegerType<((NI+NF)>>3)+1>::unsigned_type(1)< Date: Wed, 15 Nov 2023 22:44:36 +0100 Subject: [PATCH 009/215] Cleaning --- FixMath2.h | 88 +++++++++++------------------------------------------- 1 file changed, 17 insertions(+), 71 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index a4774699e..fde651117 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -16,27 +16,24 @@ #include "IntegerType.h" -#define SHIFTR(x,bits) (bits > 0 ? (x) >> (bits) : (x) << (-bits)) // shift right for positive shift numbers, and left for negative ones. +#define SHIFTR(x,bits) (bits > 0 ? x >> (bits) : x << (-bits)) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) (N1 > N2 ? N1 : N2) template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath2 { - typedef typename IntegerType<((NI+NF)>>3)>::unsigned_type internal_type ; - typedef typename IntegerType<((NI+NF)>>3)+1>::unsigned_type next_greater_type ; + typedef typename IntegerType<((NI+NF-1)>>3)+1>::unsigned_type internal_type ; // smallest size that fits our internal integer + typedef typename IntegerType<((NI+NF)>>3)+1>::unsigned_type next_greater_type ; // smallest size that fits 1< (fl * (internal_type(1) << NF));} - UFixMath2(double fl) {internal_value = static_cast (fl * (internal_type(1) << NF));} - */ - UFixMath2(float fl) {internal_value = static_cast(fl * (next_greater_type(1) << NF));} - + /* Constructor from float */ + UFixMath2(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} + + /* Constructor from double */ UFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ @@ -48,29 +45,29 @@ class UFixMath2 } /* Constructor from different integer and fractionnal part, to remove? */ - UFixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) - { - internal_value = (integral_part << NI) + fractionnal_part; - } // probably a more confusing than anything constructor! TO REMOVE + /* UFixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) + { + internal_value = (integral_part << NI) + fractionnal_part; + }*/ + // probably a more confusing than anything constructor! TO REMOVE /* Constructor from another fixed type */ template - UFixMath2(const UFixMath2<_NI,_NF>& uf) {internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type) uf.getInt(),(_NF-NF));} + UFixMath2(const UFixMath2<_NI,_NF>& uf) { + internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.getInt(),(_NF-NF)); + } // Multiplication overload, returns the compound type template UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) { - typedef typename IntegerType< ((NI+_NI+NF+_NF)>>3) >::unsigned_type return_type ; + typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.getInt(); return UFixMath2(tt,true); } - /* template - UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) - {*/ /* version 1, prior promotion/demotion to return type, safe */ @@ -84,61 +81,10 @@ class UFixMath2 internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); return UFixMath2(tt,true);*/ - /* version 3, post shifting, unsafe, but precise... If you do not overload it */ - /* internal_type tt = (internal_value * internal_type(op.getInt())) >> _NF; - return UFixMath2(tt,true);*/ - - /* version 4, tries to keep maximum precision by */ - /* if (NF+NI <= _NF+_NI) // Is that optimized away??? - { - byte sub = (NF+NI)>>1; - internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NI+_NF-sub)))); - return UFixMath2(tt,true); - } - else - { - byte sub = _NF+_NI; - internal_type tt = (internal_value>>sub) * internal_type(op.getInt()); - //((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); - return UFixMath2(tt,true); - }*/ - - /* if (NF+NI>_NF+NI) - { - byte sub = _NF; - //internal_type tt = (internal_value >> (_NF+_NI)) * internal_type(op.getInt()); - internal_type tt = (internal_value >>(sub) * internal_type(op.getInt())); - return UFixMath2(tt,true); - } - else if (NF+NI==_NF+NI) - { - byte sub = (_NF + _NI)>>2; - //internal_type tt = (internal_value >> (_NF+_NI)) * internal_type(op.getInt()); - internal_type tt = (internal_value >>sub) * (internal_type(op.getInt())>>sub); - Serial.print(" "); - Serial.println(tt); - return UFixMath2(tt,true); - } - return 0;*/ - - /* Keep it simple */ - - - ///////////// TODO, PROMOTE TO THE BIGGEST ONE? - // Ou plutot, ramener les deux au bon nombre de virgule/2, puis multiplier ? En fait c'est ma version 1/2... - // Working, more or less, except for multiplying a small with a big (and expecting a big) - - //internal_type tt = ((internal_value>>sub) * (UFixMath2(op).getInt())>>sub); - /* byte sub = (_NF+NF)>>1; - internal_type tt = ((internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub))))); - return UFixMath2(tt,true); - - - }*/ - float asFloat() { return (static_cast(internal_value)) / (typename IntegerType<((NI+NF)>>3)+1>::unsigned_type(1)<(internal_value)) / (next_greater_type(1)< Date: Wed, 15 Nov 2023 23:04:03 +0100 Subject: [PATCH 010/215] Fixed compiler warning --- FixMath2.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index fde651117..0b4285362 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -16,7 +16,7 @@ #include "IntegerType.h" -#define SHIFTR(x,bits) (bits > 0 ? x >> (bits) : x << (-bits)) // shift right for positive shift numbers, and left for negative ones. +#define SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) (N1 > N2 ? N1 : N2) template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. @@ -60,13 +60,20 @@ class UFixMath2 // Multiplication overload, returns the compound type - template - UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) + /* template + const UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) { typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.getInt(); return UFixMath2(tt,true); + }*/ + template + UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const + { + typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; + return_type tt = return_type(internal_value)*op.getInt(); + return UFixMath2(tt,true); } @@ -85,7 +92,7 @@ class UFixMath2 float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)< Date: Thu, 16 Nov 2023 01:16:27 +0100 Subject: [PATCH 011/215] Added division, untested --- FixMath2.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 0b4285362..e64a3491b 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -61,12 +61,12 @@ class UFixMath2 // Multiplication overload, returns the compound type /* template - const UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) - { - typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; - return_type tt = return_type(internal_value)*op.getInt(); - return UFixMath2(tt,true); - }*/ + const UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) + { + typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; + return_type tt = return_type(internal_value)*op.getInt(); + return UFixMath2(tt,true); + }*/ template UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const @@ -88,7 +88,13 @@ class UFixMath2 internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); return UFixMath2(tt,true);*/ - + template + UFixMath2 operator/(const UFixMath2& op1, const UFixMath2& op2) + { + typedef typename IntegerType< ((NI1-NI2+NF1-NF2+1)>>3)+1>::unsigned_type return_type ; + return_type tt = (return_type(op1.getInt())<<(NF1-NF2))/op2.getInt(); + return UFixMath2(tt,true); + } float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)< Date: Fri, 17 Nov 2023 21:39:44 +0100 Subject: [PATCH 012/215] Cleared syntax. Added mul for other types --- FixMath2.h | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index e64a3491b..82e77e61b 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -40,10 +40,17 @@ class UFixMath2 template UFixMath2(T value,bool as_frac=false) { - if (as_frac) internal_value = value; + // if (as_frac) internal_value = value; + if (as_frac) fromRaw(value); else internal_value = (internal_type(value) << NF); } + /* + + */ + template + void fromRaw(T raw) { internal_value = raw; } + /* Constructor from different integer and fractionnal part, to remove? */ /* UFixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) { @@ -55,26 +62,27 @@ class UFixMath2 /* Constructor from another fixed type */ template UFixMath2(const UFixMath2<_NI,_NF>& uf) { - internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.getInt(),(_NF-NF)); + internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } - // Multiplication overload, returns the compound type - /* template - const UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) - { - typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; - return_type tt = return_type(internal_value)*op.getInt(); - return UFixMath2(tt,true); - }*/ - + //////// MULTIPLICATION OVERLOADS + + // Multiplication overload between fixed type, returns the compound type template UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const { typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; - return_type tt = return_type(internal_value)*op.getInt(); + return_type tt = return_type(internal_value)*op.asRaw(); return UFixMath2(tt,true); } + + // Multiplication with any other type: directly to the internal_value + template + UFixMath2 operator* (const T op) const + { + return UFixMath2(internal_value*op,true); + } /* version 1, prior promotion/demotion to return type, safe */ @@ -87,7 +95,7 @@ class UFixMath2 /* byte sub = NF>>1; internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); return UFixMath2(tt,true);*/ - + /* template UFixMath2 operator/(const UFixMath2& op1, const UFixMath2& op2) { @@ -95,10 +103,10 @@ class UFixMath2 return_type tt = (return_type(op1.getInt())<<(NF1-NF2))/op2.getInt(); return UFixMath2(tt,true); } - + */ float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)< Date: Fri, 17 Nov 2023 22:22:57 +0100 Subject: [PATCH 013/215] Added reverse multiplication overloading --- FixMath2.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 82e77e61b..8efe89233 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -78,12 +78,18 @@ class UFixMath2 } // Multiplication with any other type: directly to the internal_value - template + template UFixMath2 operator* (const T op) const { return UFixMath2(internal_value*op,true); - } - + } + + /* template + UFixMath2 operator* (const T op, const UFixMath2& uf) + { + return UFixMath2(uf.asRaw()*op,true); + } + */ /* version 1, prior promotion/demotion to return type, safe */ /* byte sub = NF>>1; @@ -117,4 +123,15 @@ class UFixMath2 }; + +/// Reverse overloadings, making a template here leads to an ambiguity, forcing us to specify them one by one?? + +template +UFixMath2 operator*(int op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*op;} + + + + + #endif From 9a4d04c53278b83f939fd77951e50b395acf3a23 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Fri, 17 Nov 2023 22:36:24 +0100 Subject: [PATCH 014/215] Forgot a template --- FixMath2.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/FixMath2.h b/FixMath2.h index 8efe89233..72e7b586a 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -128,8 +128,15 @@ class UFixMath2 template UFixMath2 operator*(int op, const UFixMath2& uf) {return uf*op;} -UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*op;} +template +UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*op;} +/* +template + UFixMath2 operator* (const T op, const UFixMath2& uf) + { + return UFixMath2(uf.asRaw()*op,true); + }*/ From 6275ada2939f33b7aeeccb705cfea7e0f817a2f6 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 18 Nov 2023 13:41:25 +0100 Subject: [PATCH 015/215] Added reverse mul to UFixMath2 --- FixMath2.h | 53 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 72e7b586a..a7f16edba 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -38,18 +38,18 @@ class UFixMath2 /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ template - UFixMath2(T value,bool as_frac=false) + UFixMath2(T value,bool as_raw=false) { // if (as_frac) internal_value = value; - if (as_frac) fromRaw(value); + if (as_raw) fromRaw(value); else internal_value = (internal_type(value) << NF); } + + template + void fromRaw(T raw) { internal_value = raw; } - /* - + /* Constructors from signed types */ - template - void fromRaw(T raw) { internal_value = raw; } /* Constructor from different integer and fractionnal part, to remove? */ /* UFixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) @@ -78,17 +78,17 @@ class UFixMath2 } // Multiplication with any other type: directly to the internal_value - template + template UFixMath2 operator* (const T op) const { return UFixMath2(internal_value*op,true); - } + } /* template - UFixMath2 operator* (const T op, const UFixMath2& uf) - { - return UFixMath2(uf.asRaw()*op,true); - } + UFixMath2 operator* (const T op, const UFixMath2& uf) + { + return UFixMath2(uf.asRaw()*op,true); + } */ /* version 1, prior promotion/demotion to return type, safe */ @@ -102,13 +102,13 @@ class UFixMath2 internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); return UFixMath2(tt,true);*/ /* - template - UFixMath2 operator/(const UFixMath2& op1, const UFixMath2& op2) - { + template + UFixMath2 operator/(const UFixMath2& op1, const UFixMath2& op2) + { typedef typename IntegerType< ((NI1-NI2+NF1-NF2+1)>>3)+1>::unsigned_type return_type ; return_type tt = (return_type(op1.getInt())<<(NF1-NF2))/op2.getInt(); return UFixMath2(tt,true); - } + } */ float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)< +UFixMath2 operator*(uint8_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator*(uint16_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator*(uint32_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator*(uint64_t op, const UFixMath2& uf) {return uf*op;} template -UFixMath2 operator*(int op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator*(float op, const UFixMath2& uf) {return uf*op;} template UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*op;} /* -template - UFixMath2 operator* (const T op, const UFixMath2& uf) + template + UFixMath2 operator* (const T op, const UFixMath2& uf) { - return UFixMath2(uf.asRaw()*op,true); - }*/ + return UFixMath2(uf.asRaw()*op,true); + }*/ From da904428624695c75ff5b1cf6dc43b68be0b0412 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 18 Nov 2023 13:55:43 +0100 Subject: [PATCH 016/215] Added shift operators --- FixMath2.h | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index a7f16edba..ac3ad824e 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -48,6 +48,13 @@ class UFixMath2 template void fromRaw(T raw) { internal_value = raw; } + /* template + static UFixMath2fromRaw(T raw) { + UFixMath2 ret; + ret.internal_value = raw; + return ret; + }*/ + /* Constructors from signed types */ @@ -84,23 +91,20 @@ class UFixMath2 return UFixMath2(internal_value*op,true); } - /* template - UFixMath2 operator* (const T op, const UFixMath2& uf) - { - return UFixMath2(uf.asRaw()*op,true); - } - */ - - /* version 1, prior promotion/demotion to return type, safe */ - /* byte sub = NF>>1; - internal_type tt = (internal_value>>sub) * (UFixMath2(op).getInt() >> (sub)); - return UFixMath2(tt,true);*/ - - /* version 2, optimisation (?) of the former: one shift instead of two (at cast and here) - Keeps the bigger type for the operand, shift it by the appropriate number, cast it to the final type (which might be the same) and multiply by the internal_value, shifted of course */ - /* byte sub = NF>>1; - internal_type tt = (internal_value>>sub) * internal_type((SHIFTR(typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)>::unsigned_type(op.getInt()), (_NF-sub)))); - return UFixMath2(tt,true);*/ + + // Right shift operator + UFixMath2 operator>> (const byte op) const + { + return UFixMath2(internal_value>>op,true); + } + + // Left shift operator + UFixMath2 operator<< (const byte op) const + { + return UFixMath2(internal_value< UFixMath2 operator/(const UFixMath2& op1, const UFixMath2& op2) From bb95183c403e01841607520fa6e46bb0b21b064f Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 18 Nov 2023 14:13:42 +0100 Subject: [PATCH 017/215] Implemented main functions for Signed Fix type --- FixMath2.h | 100 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index ac3ad824e..f356dfd5f 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -49,11 +49,11 @@ class UFixMath2 void fromRaw(T raw) { internal_value = raw; } /* template - static UFixMath2fromRaw(T raw) { - UFixMath2 ret; - ret.internal_value = raw; - return ret; - }*/ + static UFixMath2fromRaw(T raw) { + UFixMath2 ret; + ret.internal_value = raw; + return ret; + }*/ /* Constructors from signed types */ @@ -146,12 +146,92 @@ UFixMath2 operator*(float op, const UFixMath2& uf) {return uf*op template UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*op;} -/* - template - UFixMath2 operator* (const T op, const UFixMath2& uf) + + + + + +///////////// SIGNED TYPE + +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +class SFixMath2 +{ + typedef typename IntegerType<((NI+NF-1)>>3)+1>::signed_type internal_type ; // smallest size that fits our internal integer + typedef typename IntegerType<((NI+NF)>>3)+1>::signed_type next_greater_type ; // smallest size that fits 1<*/(fl * (next_greater_type(1) << NF));} + + /* Constructor from double */ + SFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } + + + /* Constructor from other types (int)*/ + template + SFixMath2(T value,bool as_raw=false) + { + // if (as_frac) internal_value = value; + if (as_raw) fromRaw(value); + else internal_value = (internal_type(value) << NF); + } + + template + void fromRaw(T raw) { internal_value = raw; } + + + + + //////// MULTIPLICATION OVERLOADS + + // Multiplication overload between fixed type, returns the compound type + template + SFixMath2 operator* (const SFixMath2<_NI,_NF>& op) const + { + typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::signed_type return_type ; + return_type tt = return_type(internal_value)*op.asRaw(); + return SFixMath2(tt,true); + } + + // Multiplication with any other type: directly to the internal_value + template + SFixMath2 operator* (const T op) const + { + return SFixMath2(internal_value*op,true); + } + + + // Right shift operator + SFixMath2 operator>> (const byte op) const + { + return SFixMath2(internal_value>>op,true); + } + + // Left shift operator + SFixMath2 operator<< (const byte op) const { - return UFixMath2(uf.asRaw()*op,true); - }*/ + return SFixMath2(internal_value<(internal_value)) / (next_greater_type(1)< Date: Sat, 18 Nov 2023 14:56:19 +0100 Subject: [PATCH 018/215] Implemented SFixMath2, and mul between UFix and SFix --- FixMath2.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index f356dfd5f..e6f731956 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -22,6 +22,7 @@ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath2 { + static_assert(NI+NF<=64, "The total width of a UFixMath2 cannot exceed 64bits"); typedef typename IntegerType<((NI+NF-1)>>3)+1>::unsigned_type internal_type ; // smallest size that fits our internal integer typedef typename IntegerType<((NI+NF)>>3)+1>::unsigned_type next_greater_type ; // smallest size that fits 1< UFixMath2(T value,bool as_raw=false) { - // if (as_frac) internal_value = value; if (as_raw) fromRaw(value); else internal_value = (internal_type(value) << NF); } @@ -75,7 +75,7 @@ class UFixMath2 //////// MULTIPLICATION OVERLOADS - // Multiplication overload between fixed type, returns the compound type + // Multiplication overload between Ufixed type, returns the compound type template UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const { @@ -84,6 +84,8 @@ class UFixMath2 return UFixMath2(tt,true); } + + // Multiplication with any other type: directly to the internal_value template UFixMath2 operator* (const T op) const @@ -104,7 +106,9 @@ class UFixMath2 return UFixMath2(internal_value< UFixMath2 operator/(const UFixMath2& op1, const UFixMath2& op2) @@ -129,6 +133,8 @@ class UFixMath2 /// Reverse overloadings, making a template here leads to an ambiguity, forcing us to specify them one by one?? + + template UFixMath2 operator*(uint8_t op, const UFixMath2& uf) {return uf*op;} @@ -141,6 +147,19 @@ UFixMath2 operator*(uint32_t op, const UFixMath2& uf) {return uf template UFixMath2 operator*(uint64_t op, const UFixMath2& uf) {return uf*op;} +template +UFixMath2 operator*(int8_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator*(int16_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator*(int32_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator*(int64_t op, const UFixMath2& uf) {return uf*op;} + + template UFixMath2 operator*(float op, const UFixMath2& uf) {return uf*op;} @@ -156,6 +175,7 @@ UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*o template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class SFixMath2 { + static_assert(NI+NF<64, "The total width of a SFixMath2 cannot exceed 63bits"); typedef typename IntegerType<((NI+NF-1)>>3)+1>::signed_type internal_type ; // smallest size that fits our internal integer typedef typename IntegerType<((NI+NF)>>3)+1>::signed_type next_greater_type ; // smallest size that fits 1< +SFixMath2 operator*(uint8_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator*(uint16_t op, const SFixMath2& uf) {return uf*op;} +template +SFixMath2 operator*(uint32_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator*(uint64_t op, const SFixMath2& uf) {return uf*op;} +template +SFixMath2 operator*(int8_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator*(int16_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator*(int32_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator*(int64_t op, const SFixMath2& uf) {return uf*op;} + + +template +SFixMath2 operator*(float op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator*(double op, const SFixMath2& uf) {return uf*op;} + + + + + + + + +// Multiplications between SFixMath2 and UFixMath2 + +template +SFixMath2 operator* (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +{ + typedef typename IntegerType< ((NI+_NI+1+NF+_NF-1)>>3)+1>::signed_type return_type ; + return_type tt = return_type(op1.asRaw())*op2.asRaw(); + return SFixMath2(tt,true); +} + +template +SFixMath2 operator* (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +{ + typedef typename IntegerType< ((NI+_NI+1+NF+_NF-1)>>3)+1>::signed_type return_type ; + return_type tt = return_type(op1.asRaw())*op2.asRaw(); + return SFixMath2(tt,true); +} From 67e227ceec52cf0b57b5f48de21776ff75be0647 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 18 Nov 2023 15:22:59 +0100 Subject: [PATCH 019/215] Added overloads for add and sub between UFix --- FixMath2.h | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index e6f731956..bfc969bea 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -71,11 +71,43 @@ class UFixMath2 UFixMath2(const UFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } - + + + //////// ADDITION OVERLOADS + // Between UFix + template + UFixMath2 operator+ (const UFixMath2<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI) + 1; + constexpr byte new_NF = MAX(NF, _NF); + typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; + UFixMath2 left(*this); + UFixMath2 right(op); + + return_type tt = return_type(left.asRaw()) + right.asRaw(); + return UFixMath2(tt,true); + } + + + + //////// SUBSTRACTION OVERLOADS + // Between UFix + template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the bigger of the two. + UFixMath2 operator- (const UFixMath2<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; + UFixMath2 left(*this); + UFixMath2 right(op); + + return_type tt = return_type(left.asRaw()) - right.asRaw(); + return UFixMath2(tt,true); + } //////// MULTIPLICATION OVERLOADS - // Multiplication overload between Ufixed type, returns the compound type + // Multiplication overload between Ufixed type, returns the compound type, safe template UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const { @@ -84,9 +116,7 @@ class UFixMath2 return UFixMath2(tt,true); } - - - // Multiplication with any other type: directly to the internal_value + // Multiplication with any other type: directly to the internal_value, potential overflow template UFixMath2 operator* (const T op) const { From 385f033bb5f2f7af9382d4504670221bbdb3c78c Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 18 Nov 2023 15:37:25 +0100 Subject: [PATCH 020/215] Added sub/add between SFix --- FixMath2.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/FixMath2.h b/FixMath2.h index bfc969bea..411c7b391 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -88,6 +88,12 @@ class UFixMath2 return UFixMath2(tt,true); } + // With other types: add to integer part, unsafe + template + UFixMath2 operator+ (const T op) const + { + return UFixMath2(internal_value+(op<(tt,true); } + + // With other types: add to integer part, unsafe + template + UFixMath2 operator- (const T op) const + { + return UFixMath2(internal_value+(op< + SFixMath2(const SFixMath2<_NI,_NF>& uf) { + internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + } + + //////// ADDITION OVERLOADS + // Between SFix + template + SFixMath2 operator+ (const SFixMath2<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI) + 1; + constexpr byte new_NF = MAX(NF, _NF); + typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; + SFixMath2 left(*this); + SFixMath2 right(op); + + return_type tt = return_type(left.asRaw()) + right.asRaw(); + return SFixMath2(tt,true); + } + + // With other types: add to integer part, unsafe + template + SFixMath2 operator+ (const T op) const + { + return SFixMath2(internal_value+(op< // We do not have the +1 after MAX(NI, _NI) because the substraction between two SFix should fit in the bigger of the two. + SFixMath2 operator- (const SFixMath2<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; + SFixMath2 left(*this); + SFixMath2 right(op); + + return_type tt = return_type(left.asRaw()) - right.asRaw(); + return SFixMath2(tt,true); + } + + + // With other types: add to integer part, unsafe + template + SFixMath2 operator- (const T op) const + { + return SFixMath2(internal_value+(op< Date: Sun, 19 Nov 2023 14:53:25 +0100 Subject: [PATCH 021/215] Addition and subtraction between all --- FixMath2.h | 286 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 265 insertions(+), 21 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 411c7b391..8c8aea339 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -18,8 +18,31 @@ #define SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) (N1 > N2 ? N1 : N2) +/*#define NBITSREAL(X,N) (abs(X) < (1<(X))*/ +//#define UFixAuto(X) (UFixMath2(X)) -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +/* + template + constexpr byte nBitsReal(T x, byte n=0) { + if (abs(x) < ((T)1 << n)) { + return n; + } else { + return nBitsReal(x, n + 1); + } + } + + #define UFixAuto(X) (UFixMath2(X)) +*/ + +// Forward declaration +template +class SFixMath2; + + + +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath2 { static_assert(NI+NF<=64, "The total width of a UFixMath2 cannot exceed 64bits"); @@ -44,16 +67,22 @@ class UFixMath2 if (as_raw) fromRaw(value); else internal_value = (internal_type(value) << NF); } + + + template void fromRaw(T raw) { internal_value = raw; } - /* template - static UFixMath2fromRaw(T raw) { - UFixMath2 ret; - ret.internal_value = raw; - return ret; - }*/ + + + /* + template + static UFixMath2fromRawt(T raw) { + UFixMath2 ret; + ret.internal_value = raw; + return ret; + }*/ /* Constructors from signed types */ @@ -66,12 +95,18 @@ class UFixMath2 // probably a more confusing than anything constructor! TO REMOVE - /* Constructor from another fixed type */ + /* Constructor from another Ufixed type */ template UFixMath2(const UFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } + /* Constructor from Sfixed type */ + template + UFixMath2(const SFixMath2<_NI,_NF>& uf) { + internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + } + //////// ADDITION OVERLOADS // Between UFix @@ -92,7 +127,7 @@ class UFixMath2 template UFixMath2 operator+ (const T op) const { - return UFixMath2(internal_value+(op<(internal_value+((internal_type)op< UFixMath2 operator- (const T op) const { - return UFixMath2(internal_value+(op<(internal_value+((internal_type)op< UFixMath2 operator*(uint8_t op, const UFixMath2& uf) {return uf*op;} @@ -203,14 +238,104 @@ UFixMath2 operator*(int32_t op, const UFixMath2& uf) {return uf* template UFixMath2 operator*(int64_t op, const UFixMath2& uf) {return uf*op;} - template UFixMath2 operator*(float op, const UFixMath2& uf) {return uf*op;} template UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*op;} +// Addition +template +UFixMath2 operator+(uint8_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator+(uint16_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator+(uint32_t op, const UFixMath2& uf) {return uf*op;} +template +UFixMath2 operator+(uint64_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator+(int8_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator+(int16_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator+(int32_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator+(int64_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator+(float op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator+(double op, const UFixMath2& uf) {return uf*op;} + +// Substraction +template +UFixMath2 operator-(uint8_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(uint16_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(uint32_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(uint64_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(int8_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(int16_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(int32_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(int64_t op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(float op, const UFixMath2& uf) {return uf*op;} + +template +UFixMath2 operator-(double op, const UFixMath2& uf) {return uf*op;} + + + +/* + template + constexpr byte nBitsReal(T x,byte n=0) { (abs(x)<(1< + constexpr byte nBitsReal(T x, byte n=0) { + if (abs(x) < ((T)1 << n)) { + return n; + } else { + return nBitsReal(x, n + 1); + } + } + + template + constexpr auto UFixAuto(T x) -> UFixMath2 + { + constexpr byte n = nBitsReal(x); + return UFixMath2(x); + } +*/ + +/* + template + auto UFixAuto(x){ + return UFixMath2(x); + }*/ @@ -248,12 +373,18 @@ class SFixMath2 void fromRaw(T raw) { internal_value = raw; } - /* Constructor from another fixed type */ + /* Constructor from another Sfixed type */ template SFixMath2(const SFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } + /* Constructor from another Sfixed type */ + template + SFixMath2(const UFixMath2<_NI,_NF>& uf) { + internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + } + //////// ADDITION OVERLOADS // Between SFix template @@ -339,6 +470,10 @@ class SFixMath2 float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)< SFixMath2 operator*(uint8_t op, const SFixMath2& uf) {return uf*op;} @@ -371,13 +506,73 @@ SFixMath2 operator*(int32_t op, const SFixMath2& uf) {return uf* template SFixMath2 operator*(int64_t op, const SFixMath2& uf) {return uf*op;} - template SFixMath2 operator*(float op, const SFixMath2& uf) {return uf*op;} template SFixMath2 operator*(double op, const SFixMath2& uf) {return uf*op;} +// Addition +template +SFixMath2 operator+(uint8_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(uint16_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(uint32_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(uint64_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(int8_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(int16_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(int32_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(int64_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(float op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator+(double op, const SFixMath2& uf) {return uf*op;} + +// Substraction +template +SFixMath2 operator-(uint8_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(uint16_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(uint32_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(uint64_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(int8_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(int16_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(int32_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(int64_t op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(float op, const SFixMath2& uf) {return uf*op;} + +template +SFixMath2 operator-(double op, const SFixMath2& uf) {return uf*op;} @@ -398,12 +593,61 @@ SFixMath2 operator* (const SFixMath2& op1, const UFixMat template SFixMath2 operator* (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { - typedef typename IntegerType< ((NI+_NI+1+NF+_NF-1)>>3)+1>::signed_type return_type ; - return_type tt = return_type(op1.asRaw())*op2.asRaw(); - return SFixMath2(tt,true); + /* typedef typename IntegerType< ((NI+_NI+1+NF+_NF-1)>>3)+1>::signed_type return_type ; + return_type tt = return_type(op1.asRaw())*op2.asRaw(); + return SFixMath2(tt,true);*/ + return op2*op1; +} + + +// Addition between SFixMath2 and UFixMath2 (promotion to SFixMath2) + +template +SFixMath2 operator+ (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +{ + constexpr byte new_NI = MAX(NI, _NI) + 1; + constexpr byte new_NF = MAX(NF, _NF); + + typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; + SFixMath2 left(op1); + SFixMath2 right(op2); + return_type tt = return_type(left.asRaw()) + right.asRaw(); + return SFixMath2(tt,true); +} + +template +SFixMath2 operator+ (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +{ + return op2+op1; } +// Substraction between SFixMath2 and UFixMath2 (promotion to SFixMath2) +template +SFixMath2 operator- (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +{ + constexpr byte new_NI = MAX(NI, _NI) + 1; + constexpr byte new_NF = MAX(NF, _NF); + + typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; + SFixMath2 left(op1); + SFixMath2 right(op2); + return_type tt = return_type(left.asRaw()) - right.asRaw(); + return SFixMath2(tt,true); +} + +template +SFixMath2 operator- (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +{ + constexpr byte new_NI = MAX(NI, _NI) + 1; + constexpr byte new_NF = MAX(NF, _NF); + + typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; + SFixMath2 left(op1); + SFixMath2 right(op2); + return_type tt = return_type(left.asRaw()) - right.asRaw(); + return SFixMath2(tt,true); +} #endif From 7349ac425276d4d92b7565e92315dd52b5bb657b Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 19 Nov 2023 16:50:24 +0100 Subject: [PATCH 022/215] Fix sub (this one is not symetric). Added neg of fixed types --- FixMath2.h | 103 +++++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 8c8aea339..9b0c69501 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -102,10 +102,10 @@ class UFixMath2 } /* Constructor from Sfixed type */ - template + template UFixMath2(const SFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); - } + } //////// ADDITION OVERLOADS @@ -151,9 +151,15 @@ class UFixMath2 template UFixMath2 operator- (const T op) const { - return UFixMath2(internal_value+((internal_type)op<(internal_value-((internal_type)op< operator-() const + { + return SFixMath2( -(typename IntegerType<((NI+NF-1+1)>>3)+1>::signed_type)(internal_value),true); + } + //////// MULTIPLICATION OVERLOADS // Multiplication overload between Ufixed type, returns the compound type, safe @@ -246,68 +252,65 @@ UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*o // Addition template -UFixMath2 operator+(uint8_t op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(uint8_t op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(uint16_t op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(uint16_t op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(uint32_t op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(uint32_t op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(uint64_t op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(uint64_t op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(int8_t op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(int8_t op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(int16_t op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(int16_t op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(int32_t op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(int32_t op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(int64_t op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(int64_t op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(float op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(float op, const UFixMath2& uf) {return uf+op;} template -UFixMath2 operator+(double op, const UFixMath2& uf) {return uf*op;} +UFixMath2 operator+(double op, const UFixMath2& uf) {return uf+op;} // Substraction template -UFixMath2 operator-(uint8_t op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(uint8_t op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(uint16_t op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(uint16_t op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(uint32_t op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(uint32_t op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(uint64_t op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(uint64_t op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(int8_t op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(int8_t op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(int16_t op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(int16_t op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(int32_t op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(int32_t op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(int64_t op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(int64_t op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(float op, const UFixMath2& uf) {return uf*op;} +SFixMath2 operator-(float op, const UFixMath2& uf) {return -uf+op;} template -UFixMath2 operator-(double op, const UFixMath2& uf) {return uf*op;} - - - +SFixMath2 operator-(double op, const UFixMath2& uf) {return -uf+op;} /* template constexpr byte nBitsReal(T x,byte n=0) { (abs(x)<(1< SFixMath2 operator- (const T op) const { - return SFixMath2(internal_value+(op<(internal_value-(op< operator-() const + { + return SFixMath2(-internal_value,true); + } //////// MULTIPLICATION OVERLOADS @@ -514,65 +523,65 @@ SFixMath2 operator*(double op, const SFixMath2& uf) {return uf*o // Addition template -SFixMath2 operator+(uint8_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(uint8_t op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(uint16_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(uint16_t op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(uint32_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(uint32_t op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(uint64_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(uint64_t op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(int8_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(int8_t op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(int16_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(int16_t op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(int32_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(int32_t op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(int64_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(int64_t op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(float op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(float op, const SFixMath2& uf) {return uf+op;} template -SFixMath2 operator+(double op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator+(double op, const SFixMath2& uf) {return uf+op;} // Substraction template -SFixMath2 operator-(uint8_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(uint8_t op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(uint16_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(uint16_t op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(uint32_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(uint32_t op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(uint64_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(uint64_t op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(int8_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(int8_t op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(int16_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(int16_t op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(int32_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(int32_t op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(int64_t op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(int64_t op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(float op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(float op, const SFixMath2& uf) {return (-uf)+op;} template -SFixMath2 operator-(double op, const SFixMath2& uf) {return uf*op;} +SFixMath2 operator-(double op, const SFixMath2& uf) {return (-uf)+op;} From b6ae357c63d28fd428a4b9efcf1ec575dbca6881 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 19 Nov 2023 17:06:21 +0100 Subject: [PATCH 023/215] Small cleanup --- FixMath2.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 9b0c69501..a00ea99eb 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -19,9 +19,9 @@ #define SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) (N1 > N2 ? N1 : N2) /*#define NBITSREAL(X,N) (abs(X) < (1<(X))*/ -//#define UFixAuto(X) (UFixMath2(X)) + #define NBITSREAL2(X,N) (abs(X) < (1<(X)) + #define UFixAuto(X) (UFixMath2(X))*/ /* template @@ -102,10 +102,10 @@ class UFixMath2 } /* Constructor from Sfixed type */ - template + template UFixMath2(const SFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); - } + } //////// ADDITION OVERLOADS @@ -154,11 +154,11 @@ class UFixMath2 return UFixMath2(internal_value-((internal_type)op< operator-() const + /////// Negative overload + SFixMath2 operator-() const { - return SFixMath2( -(typename IntegerType<((NI+NF-1+1)>>3)+1>::signed_type)(internal_value),true); - } + return SFixMath2( -(typename IntegerType<((NI+NF-1+1)>>3)+1>::signed_type)(internal_value),true); + } //////// MULTIPLICATION OVERLOADS @@ -609,7 +609,7 @@ SFixMath2 operator* (const UFixMath2& op1, const SFixMat } -// Addition between SFixMath2 and UFixMath2 (promotion to SFixMath2) +// Addition between SFixMath2 and UFixMath2 (promotion to next SFixMath2) template SFixMath2 operator+ (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) @@ -630,7 +630,7 @@ SFixMath2 operator+ (const UFixMath2& op1, con return op2+op1; } -// Substraction between SFixMath2 and UFixMath2 (promotion to SFixMath2) +// Substraction between SFixMath2 and UFixMath2 (promotion to next SFixMath2) template SFixMath2 operator- (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) From f51bb38afc4d97ca892b6da69a98a32d1ee4842e Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 19 Nov 2023 17:35:14 +0100 Subject: [PATCH 024/215] Corrected shifts --- FixMath2.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index a00ea99eb..f7fa7aca0 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -180,15 +180,15 @@ class UFixMath2 // Right shift operator - UFixMath2 operator>> (const byte op) const + UFixMath2 operator>> (const byte op) const { - return UFixMath2(internal_value>>op,true); + return UFixMath2(internal_value>>op,true); } // Left shift operator - UFixMath2 operator<< (const byte op) const + UFixMath2 operator<< (const byte op) const { - return UFixMath2(internal_value<(internal_value< operator>> (const byte op) const + SFixMath2 operator>> (const byte op) const { - return SFixMath2(internal_value>>op,true); + return SFixMath2(internal_value>>op,true); } // Left shift operator - SFixMath2 operator<< (const byte op) const + SFixMath2 operator<< (const byte op) const { - return SFixMath2(internal_value<(internal_value<(internal_value)) / (next_greater_type(1)< Date: Sun, 19 Nov 2023 21:13:19 +0100 Subject: [PATCH 025/215] Added safe (and optimizing to lower type) shiftsP --- FixMath2.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/FixMath2.h b/FixMath2.h index f7fa7aca0..2e46062a3 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -191,6 +191,18 @@ class UFixMath2 return UFixMath2(internal_value< + UFixMath2 sR() + { + return UFixMath2(internal_value>>op,true); + } + + template + UFixMath2 sL() + { + return UFixMath2((typename IntegerType<((NI+op+NF-1)>>3)+1>::unsigned_type) internal_value<(internal_value< + SFixMath2 sR() + { + return SFixMath2(internal_value>>op,true); + } + + template + SFixMath2 sL() + { + return SFixMath2((typename IntegerType<((NI+op+NF-1)>>3)+1>::signed_type) internal_value<(internal_value)) / (next_greater_type(1)< Date: Mon, 20 Nov 2023 21:48:45 +0100 Subject: [PATCH 026/215] Documentation --- FixMath2.h | 338 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 250 insertions(+), 88 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 2e46062a3..85eb97585 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -1,7 +1,7 @@ /* * FixMath2.h * - * Copyright 2012 Tim Barrass + * Copyright 2023, Thomas Combriat and the Mozzi consortsium * * This file is part of Mozzi. * @@ -11,6 +11,27 @@ */ +/** This file implements two fixed point number classes. These numbers can have a fractional +part but are actually standard integers under the hood which makes calculations with them +efficient on platforms which do not have a FPU like most micro-controllers. These numbers can be +signed (SFixMath2) or unsigned (UFixMath2). + +A fixed point number has its range defined by the number of bits encoding the integer part (NI +in the following) and its precision by the number of bits encoding the fractional part (NF). + +Like standard C(++) types, the fixed point numbers defined here are following some rules: + - any fixed type can be converted to another *as long as the value can be represented in the destination type*. Casting to a bigger type in term of NI and NF is safe, but reducing NI can lead to an overflow if the new type cannot hold the integer value and reducing NF leads to a loss of precision. + - all operations between fixed point number is safe (it won't overflow) and preserve the precision. In particular: + - only addition, subtraction and multiplication are implemented + - any operation between a signed and an unsigned leads to a signed number + - resulting numbers will be casted to a type big enough to store the expected values. It follows that it is worth starting with types that are as small as possible to hold the initial value. + - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. + - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. +*/ + + + + #ifndef FIXMATH2_H_ #define FIXMATH2_H_ @@ -18,6 +39,8 @@ #define SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) (N1 > N2 ? N1 : N2) + +// Experiments /*#define NBITSREAL(X,N) (abs(X) < (1<(X)) @@ -33,15 +56,24 @@ } } - #define UFixAuto(X) (UFixMath2(X)) + #define UFixAuto(X) (UFixMath2(X)) */ + + + + + // Forward declaration template class SFixMath2; +/** Instanciate an unsigned fixed point math number. +@param NI The number of bits encoding the integer part +@param NF The number of bits encoding the fractional part +*/ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath2 { @@ -53,14 +85,27 @@ class UFixMath2 /** Constructor */ UFixMath2() {;} - - /* Constructor from float */ + + /** Constructor from a positive floating point value. +@param fl Floating point value +@return An unsigned fixed point number + */ UFixMath2(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} - /* Constructor from double */ + /** Constructor from a floating point value. +@param fl Floating point value +@return An unsigned fixed point number + */ UFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ + + /** Constructor from an integer value which can be interpreted as both a resulting fixed point +math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number. +@param value Integer value +@param as_raw=false with false value will be interpreted as an integer, with true it will be interpreted as a number with decimals. +@return An unsigned fixed point number + */ template UFixMath2(T value,bool as_raw=false) { @@ -69,39 +114,29 @@ class UFixMath2 } - - + /** Set the internal value of the fixed point math number. +@param raw The new internal value. + */ template void fromRaw(T raw) { internal_value = raw; } - /* - template - static UFixMath2fromRawt(T raw) { - UFixMath2 ret; - ret.internal_value = raw; - return ret; - }*/ - - /* Constructors from signed types - */ - - /* Constructor from different integer and fractionnal part, to remove? */ - /* UFixMath2(typename IntegerType<((NI)>>3)>::unsigned_type integral_part, typename IntegerType<((NF)>>3)>::unsigned_type fractionnal_part) - { - internal_value = (integral_part << NI) + fractionnal_part; - }*/ - // probably a more confusing than anything constructor! TO REMOVE - /* Constructor from another Ufixed type */ + /** Constructor from another UFixMath2. +@param uf An unsigned fixed type number which value can be represented in this type. +@return A unsigned fixed type number + */ template UFixMath2(const UFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } - /* Constructor from Sfixed type */ + /** Constructor from another SFixMath2. +@param uf An signed fixed type number which value can be represented in this type. +@return A unsigned fixed type number + */ template UFixMath2(const SFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); @@ -109,7 +144,11 @@ class UFixMath2 //////// ADDITION OVERLOADS - // Between UFix + + /** Addition with another UFixMath2. Safe. +@param op The UFixMath2 to be added. +@return The result of the addition as a UFixMath2. + */ template UFixMath2 operator+ (const UFixMath2<_NI,_NF>& op) const { @@ -123,7 +162,10 @@ class UFixMath2 return UFixMath2(tt,true); } - // With other types: add to integer part, unsafe + /** Addition with another type. Unsafe +@param op The number to be added. +@return The result of the addition as a UFixMath2. + */ template UFixMath2 operator+ (const T op) const { @@ -132,7 +174,11 @@ class UFixMath2 //////// SUBSTRACTION OVERLOADS - // Between UFix + + /** Subtraction with another UFixMath2. Safe. +@param op The UFixMath2 to be subtracted. +@return The result of the subtraction as a UFixMath2. + */ template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the bigger of the two. UFixMath2 operator- (const UFixMath2<_NI,_NF>& op) const { @@ -147,14 +193,19 @@ class UFixMath2 } - // With other types: add to integer part, unsafe + /** Subtraction with another type. Unsafe +@param op The number to be subtracted. +@return The result of the subtraction as a UFixMath2. + */ template UFixMath2 operator- (const T op) const { return UFixMath2(internal_value-((internal_type)op< operator-() const { return SFixMath2( -(typename IntegerType<((NI+NF-1+1)>>3)+1>::signed_type)(internal_value),true); @@ -162,7 +213,10 @@ class UFixMath2 //////// MULTIPLICATION OVERLOADS - // Multiplication overload between Ufixed type, returns the compound type, safe + /** Multiplication with another UFixMath2. Safe. +@param op The UFixMath2 to be multiplied. +@return The result of the multiplication as a UFixMath2. + */ template UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const { @@ -171,7 +225,10 @@ class UFixMath2 return UFixMath2(tt,true); } - // Multiplication with any other type: directly to the internal_value, potential overflow + /** Multiplication with another type. Unsafe. +@param op The number to be multiplied. +@return The result of the multiplication as a UFixMath2. + */ template UFixMath2 operator* (const T op) const { @@ -179,24 +236,40 @@ class UFixMath2 } - // Right shift operator + /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. +Better to use .sR() if possible instead. +@param op The shift number +@return The result of the shift as a UFixMath2. + */ UFixMath2 operator>> (const byte op) const { return UFixMath2(internal_value>>op,true); } - // Left shift operator + /** Left shift. This can overflow if you shift to a value that cannot be represented. +Better to use .sL() if possible instead. +@param op The shift number +@return The result of the shift as a UFixMath2. + */ UFixMath2 operator<< (const byte op) const { return UFixMath2(internal_value< UFixMath2 sR() { return UFixMath2(internal_value>>op,true); } + /** Safe and optimal left shift. The returned type will be adjusted accordingly +@param op The shift number +@return The result of the shift as a UFixMath2 of bigger size. + */ template UFixMath2 sL() { @@ -215,12 +288,26 @@ class UFixMath2 return UFixMath2(tt,true); } */ - + + + /** Returns the value as floating point number. +@return The floating point value. + */ float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)< operator-(float op, const UFixMath2& uf) {return -uf template SFixMath2 operator-(double op, const UFixMath2& uf) {return -uf+op;} -/* - template - constexpr byte nBitsReal(T x,byte n=0) { (abs(x)<(1< - constexpr byte nBitsReal(T x, byte n=0) { - if (abs(x) < ((T)1 << n)) { - return n; - } else { - return nBitsReal(x, n + 1); - } - } - template - constexpr auto UFixAuto(T x) -> UFixMath2 - { - constexpr byte n = nBitsReal(x); - return UFixMath2(x); - } -*/ -/* - template - auto UFixAuto(x){ - return UFixMath2(x); - }*/ - -///////////// SIGNED TYPE - +/** Instanciate an signed fixed point math number. +@param NI The number of bits encoding the integer part +@param NF The number of bits encoding the fractional part +*/ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class SFixMath2 { @@ -368,14 +430,25 @@ class SFixMath2 */ SFixMath2() {;} - /* Constructor from float */ + /** Constructor from a floating point value. +@param fl Floating point value +@return An signed fixed point number + */ SFixMath2(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} - /* Constructor from double */ + /** Constructor from a floating point value. +@param fl Floating point value +@return An signed fixed point number + */ SFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } - /* Constructor from other types (int)*/ + /** Constructor from an integer value which can be interpreted as both a resulting fixed point +math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number. +@param value Integer value +@param as_raw=false with false value will be interpreted as an integer, with true it will be interpreted as a number with decimals. +@return An signed fixed point number + */ template SFixMath2(T value,bool as_raw=false) { @@ -383,25 +456,38 @@ class SFixMath2 if (as_raw) fromRaw(value); else internal_value = (internal_type(value) << NF); } - + + /** Set the internal value of the fixed point math number. +@param raw The new internal value. + */ template void fromRaw(T raw) { internal_value = raw; } - /* Constructor from another Sfixed type */ + /** Constructor from another sFixMath2. +@param uf A signed fixed type number which value can be represented in this type. +@return A signed fixed type number + */ template SFixMath2(const SFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } - /* Constructor from another Sfixed type */ + /** Constructor from another UFixMath2. +@param uf A unsigned fixed type number. +@return A signed fixed type number + */ template SFixMath2(const UFixMath2<_NI,_NF>& uf) { internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS - // Between SFix + + /** Addition with another SFixMath2. Safe. +@param op The SFixMath2 to be added. +@return The result of the addition as a SFixMath2. + */ template SFixMath2 operator+ (const SFixMath2<_NI,_NF>& op) const { @@ -415,7 +501,10 @@ class SFixMath2 return SFixMath2(tt,true); } - // With other types: add to integer part, unsafe + /** Addition with another type. Unsafe +@param op The number to be added. +@return The result of the addition as a UFixMath2. + */ template SFixMath2 operator+ (const T op) const { @@ -424,7 +513,11 @@ class SFixMath2 //////// SUBSTRACTION OVERLOADS - // Between SFix + + /** Subtraction with another SFixMath2. Safe. +@param op The SFixMath2 to be subtracted. +@return The result of the subtraction as a SFixMath2. + */ template // We do not have the +1 after MAX(NI, _NI) because the substraction between two SFix should fit in the bigger of the two. SFixMath2 operator- (const SFixMath2<_NI,_NF>& op) const { @@ -439,7 +532,10 @@ class SFixMath2 } - // With other types: add to integer part, unsafe + /** Subtraction with another type. Unsafe +@param op The number to be subtracted. +@return The result of the subtraction as a SFixMath2. + */ template SFixMath2 operator- (const T op) const { @@ -447,7 +543,9 @@ class SFixMath2 } - /////// Negative overload + /** Opposite of the number. +@return The opposite numberas a SFixMath2. + */ SFixMath2 operator-() const { return SFixMath2(-internal_value,true); @@ -455,7 +553,10 @@ class SFixMath2 //////// MULTIPLICATION OVERLOADS - // Multiplication overload between fixed type, returns the compound type + /** Multiplication with another SFixMath2. Safe. +@param op The SFixMath2 to be multiplied. +@return The result of the multiplication as a SFixMath2. + */ template SFixMath2 operator* (const SFixMath2<_NI,_NF>& op) const { @@ -464,7 +565,10 @@ class SFixMath2 return SFixMath2(tt,true); } - // Multiplication with any other type: directly to the internal_value + /** Multiplication with another type. Unsafe. +@param op The number to be multiplied. +@return The result of the multiplication as a UFixMath2. + */ template SFixMath2 operator* (const T op) const { @@ -472,35 +576,64 @@ class SFixMath2 } - // Right shift operator + /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. +Better to use .sR() if possible instead. +@param op The shift number +@return The result of the shift as a SFixMath2. + */ SFixMath2 operator>> (const byte op) const { return SFixMath2(internal_value>>op,true); } - // Left shift operator + /** Left shift. This can overflow if you shift to a value that cannot be represented. +Better to use .sL() if possible instead. +@param op The shift number +@return The result of the shift as a UFixMath2. + */ SFixMath2 operator<< (const byte op) const { return SFixMath2(internal_value< SFixMath2 sR() { return SFixMath2(internal_value>>op,true); } + /** Safe and optimal left shift. The returned type will be adjusted accordingly +@param op The shift number +@return The result of the shift as a UFixMath2 of bigger size. + */ template SFixMath2 sL() { return SFixMath2((typename IntegerType<((NI+op+NF-1)>>3)+1>::signed_type) internal_value<(internal_value)) / (next_greater_type(1)< operator-(double op, const SFixMath2& uf) {return (-uf -// Multiplications between SFixMath2 and UFixMath2 + + /** Multiplication between a SFixMath2 and a UFixMath2. Safe. +@param op1 A SFixMath2 +@param op2 A UFixMath2 +@return The result of the multiplication of op1 and op2. As a SFixMath2 + */ template SFixMath2 operator* (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { @@ -620,18 +758,26 @@ SFixMath2 operator* (const SFixMath2& op1, const UFixMat return SFixMath2(tt,true); } + /** Multiplication between a UFixMath2 and a SFixMath2. Safe. +@param op1 A UFixMath2 +@param op2 A SFixMath2 +@return The result of the multiplication of op1 and op2. As a SFixMath2 + */ template SFixMath2 operator* (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { - /* typedef typename IntegerType< ((NI+_NI+1+NF+_NF-1)>>3)+1>::signed_type return_type ; - return_type tt = return_type(op1.asRaw())*op2.asRaw(); - return SFixMath2(tt,true);*/ return op2*op1; } // Addition between SFixMath2 and UFixMath2 (promotion to next SFixMath2) + + /** Addition between a SFixMath2 and a UFixMath2. Safe. +@param op1 A SFixMath2 +@param op2 A UFixMath2 +@return The result of the addition of op1 and op2. As a SFixMath2 + */ template SFixMath2 operator+ (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { @@ -645,6 +791,11 @@ SFixMath2 operator+ (const SFixMath2& op1, con return SFixMath2(tt,true); } + /** Addition between a UFixMath2 and a SFixMath2. Safe. +@param op1 A UFixMath2 +@param op2 A SFixMath2 +@return The result of the addition of op1 and op2. As a SFixMath2 + */ template SFixMath2 operator+ (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { @@ -653,6 +804,11 @@ SFixMath2 operator+ (const UFixMath2& op1, con // Substraction between SFixMath2 and UFixMath2 (promotion to next SFixMath2) + /** Subtraction between a SFixMath2 and a UFixMath2. Safe. +@param op1 A SFixMath2 +@param op2 A UFixMath2 +@return The result of the subtraction of op1 by op2. As a SFixMath2 + */ template SFixMath2 operator- (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { @@ -666,17 +822,23 @@ SFixMath2 operator- (const SFixMath2& op1, con return SFixMath2(tt,true); } + /** Subtraction between a UFixMath2 and a SFixMath2. Safe. +@param op1 A UFixMath2 +@param op2 A SFixMath2 +@return The result of the subtraction of op1 by op2. As a SFixMath2 + */ template SFixMath2 operator- (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI) + 1; + return -op2+op1; + /* constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; SFixMath2 left(op1); SFixMath2 right(op2); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath2(tt,true); + return SFixMath2(tt,true);*/ } From 6f3256e8770410305302860d32966a56585c6411 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 25 Nov 2023 22:50:01 +0100 Subject: [PATCH 027/215] Corrected wrong algebra for add and sub between UFix and SFix --- FixMath2.h | 353 ++++++++++++++++++++++++++--------------------------- 1 file changed, 173 insertions(+), 180 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 85eb97585..81b614a15 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -1,7 +1,7 @@ /* * FixMath2.h * - * Copyright 2023, Thomas Combriat and the Mozzi consortsium + * Copyright 2023, Thomas Combriat and the Mozzi team * * This file is part of Mozzi. * @@ -12,21 +12,21 @@ /** This file implements two fixed point number classes. These numbers can have a fractional -part but are actually standard integers under the hood which makes calculations with them -efficient on platforms which do not have a FPU like most micro-controllers. These numbers can be -signed (SFixMath2) or unsigned (UFixMath2). - -A fixed point number has its range defined by the number of bits encoding the integer part (NI -in the following) and its precision by the number of bits encoding the fractional part (NF). - -Like standard C(++) types, the fixed point numbers defined here are following some rules: - - any fixed type can be converted to another *as long as the value can be represented in the destination type*. Casting to a bigger type in term of NI and NF is safe, but reducing NI can lead to an overflow if the new type cannot hold the integer value and reducing NF leads to a loss of precision. - - all operations between fixed point number is safe (it won't overflow) and preserve the precision. In particular: - - only addition, subtraction and multiplication are implemented - - any operation between a signed and an unsigned leads to a signed number - - resulting numbers will be casted to a type big enough to store the expected values. It follows that it is worth starting with types that are as small as possible to hold the initial value. - - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. - - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. + part but are actually standard integers under the hood which makes calculations with them + efficient on platforms which do not have a FPU like most micro-controllers. These numbers can be + signed (SFixMath2) or unsigned (UFixMath2). + + A fixed point number has its range defined by the number of bits encoding the integer part (NI + in the following) and its precision by the number of bits encoding the fractional part (NF). + + Like standard C(++) types, the fixed point numbers defined here are following some rules: + - any fixed type can be converted to another *as long as the value can be represented in the destination type*. Casting to a bigger type in term of NI and NF is safe, but reducing NI can lead to an overflow if the new type cannot hold the integer value and reducing NF leads to a loss of precision. + - all operations between fixed point number is safe (it won't overflow) and preserve the precision. In particular: + - only addition, subtraction and multiplication are implemented + - any operation between a signed and an unsigned leads to a signed number + - resulting numbers will be casted to a type big enough to store the expected values. It follows that it is worth starting with types that are as small as possible to hold the initial value. + - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. + - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. */ @@ -37,7 +37,7 @@ Like standard C(++) types, the fixed point numbers defined here are following so #include "IntegerType.h" -#define SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. +#define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) (N1 > N2 ? N1 : N2) // Experiments @@ -56,7 +56,7 @@ Like standard C(++) types, the fixed point numbers defined here are following so } } - #define UFixAuto(X) (UFixMath2(X)) + #define UFixAuto(X) (UFixMath2(X)) */ @@ -71,10 +71,10 @@ class SFixMath2; /** Instanciate an unsigned fixed point math number. -@param NI The number of bits encoding the integer part -@param NF The number of bits encoding the fractional part + @param NI The number of bits encoding the integer part + @param NF The number of bits encoding the fractional part */ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath2 { static_assert(NI+NF<=64, "The total width of a UFixMath2 cannot exceed 64bits"); @@ -87,67 +87,68 @@ class UFixMath2 UFixMath2() {;} /** Constructor from a positive floating point value. -@param fl Floating point value -@return An unsigned fixed point number + @param fl Floating point value + @return An unsigned fixed point number */ UFixMath2(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} /** Constructor from a floating point value. -@param fl Floating point value -@return An unsigned fixed point number + @param fl Floating point value + @return An unsigned fixed point number */ UFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ - /** Constructor from an integer value which can be interpreted as both a resulting fixed point -math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number. -@param value Integer value -@param as_raw=false with false value will be interpreted as an integer, with true it will be interpreted as a number with decimals. -@return An unsigned fixed point number + /** Constructor from an integer value which can be interpreted as both a resulting fixed point + math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number. + @param value Integer value + @param as_raw=false with false value will be interpreted as an integer, with true it will be interpreted as a number with decimals. + @return An unsigned fixed point number */ template UFixMath2(T value,bool as_raw=false) { - if (as_raw) fromRaw(value); + if (as_raw) internal_value = value; else internal_value = (internal_type(value) << NF); } /** Set the internal value of the fixed point math number. -@param raw The new internal value. + @param raw The new internal value. + @return An UFixMath2x */ template - void fromRaw(T raw) { internal_value = raw; } + static UFixMath2 fromRaw(T raw){return UFixMath2(raw,true);} /** Constructor from another UFixMath2. -@param uf An unsigned fixed type number which value can be represented in this type. -@return A unsigned fixed type number + @param uf An unsigned fixed type number which value can be represented in this type. + @return A unsigned fixed type number */ template UFixMath2(const UFixMath2<_NI,_NF>& uf) { - internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } /** Constructor from another SFixMath2. -@param uf An signed fixed type number which value can be represented in this type. -@return A unsigned fixed type number + @param uf An signed fixed type number which value can be represented in this type: sign is thus discarded. + @return A unsigned fixed type number */ template UFixMath2(const SFixMath2<_NI,_NF>& uf) { - internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS /** Addition with another UFixMath2. Safe. -@param op The UFixMath2 to be added. -@return The result of the addition as a UFixMath2. + @param op The UFixMath2 to be added. + @return The result of the addition as a UFixMath2. */ template UFixMath2 operator+ (const UFixMath2<_NI,_NF>& op) const @@ -163,8 +164,8 @@ math number with a fractional part equals to 0, or as a number with decimal, ie } /** Addition with another type. Unsafe -@param op The number to be added. -@return The result of the addition as a UFixMath2. + @param op The number to be added. + @return The result of the addition as a UFixMath2. */ template UFixMath2 operator+ (const T op) const @@ -175,11 +176,11 @@ math number with a fractional part equals to 0, or as a number with decimal, ie //////// SUBSTRACTION OVERLOADS - /** Subtraction with another UFixMath2. Safe. -@param op The UFixMath2 to be subtracted. -@return The result of the subtraction as a UFixMath2. + /** Subtraction with another UFixMath2. Safe. + @param op The UFixMath2 to be subtracted. + @return The result of the subtraction as a UFixMath2. */ - template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the bigger of the two. + template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. UFixMath2 operator- (const UFixMath2<_NI,_NF>& op) const { constexpr byte new_NI = MAX(NI, _NI); @@ -193,9 +194,9 @@ math number with a fractional part equals to 0, or as a number with decimal, ie } - /** Subtraction with another type. Unsafe -@param op The number to be subtracted. -@return The result of the subtraction as a UFixMath2. + /** Subtraction with another type. Unsafe + @param op The number to be subtracted. + @return The result of the subtraction as a UFixMath2. */ template UFixMath2 operator- (const T op) const @@ -203,8 +204,8 @@ math number with a fractional part equals to 0, or as a number with decimal, ie return UFixMath2(internal_value-((internal_type)op< operator-() const { @@ -214,8 +215,8 @@ math number with a fractional part equals to 0, or as a number with decimal, ie //////// MULTIPLICATION OVERLOADS /** Multiplication with another UFixMath2. Safe. -@param op The UFixMath2 to be multiplied. -@return The result of the multiplication as a UFixMath2. + @param op The UFixMath2 to be multiplied. + @return The result of the multiplication as a UFixMath2. */ template UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const @@ -226,8 +227,8 @@ math number with a fractional part equals to 0, or as a number with decimal, ie } /** Multiplication with another type. Unsafe. -@param op The number to be multiplied. -@return The result of the multiplication as a UFixMath2. + @param op The number to be multiplied. + @return The result of the multiplication as a UFixMath2. */ template UFixMath2 operator* (const T op) const @@ -237,9 +238,9 @@ math number with a fractional part equals to 0, or as a number with decimal, ie /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. -Better to use .sR() if possible instead. -@param op The shift number -@return The result of the shift as a UFixMath2. + Better to use .sR() if possible instead. + @param op The shift number + @return The result of the shift as a UFixMath2. */ UFixMath2 operator>> (const byte op) const { @@ -247,9 +248,9 @@ Better to use .sR() if possible instead. } /** Left shift. This can overflow if you shift to a value that cannot be represented. -Better to use .sL() if possible instead. -@param op The shift number -@return The result of the shift as a UFixMath2. + Better to use .sL() if possible instead. + @param op The shift number + @return The result of the shift as a UFixMath2. */ UFixMath2 operator<< (const byte op) const { @@ -257,8 +258,8 @@ Better to use .sL() if possible instead. } /** Safe and optimal right shift. The returned type will be adjusted accordingly -@param op The shift number -@return The result of the shift as a UFixMath2 of smaller size. + @param op The shift number + @return The result of the shift as a UFixMath2 of smaller size. */ template UFixMath2 sR() @@ -266,9 +267,9 @@ Better to use .sL() if possible instead. return UFixMath2(internal_value>>op,true); } - /** Safe and optimal left shift. The returned type will be adjusted accordingly -@param op The shift number -@return The result of the shift as a UFixMath2 of bigger size. + /** Safe and optimal left shift. The returned type will be adjusted accordingly + @param op The shift number + @return The result of the shift as a UFixMath2 of bigger size. */ template UFixMath2 sL() @@ -291,22 +292,22 @@ Better to use .sL() if possible instead. /** Returns the value as floating point number. -@return The floating point value. + @return The floating point value. */ float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)< operator-(double op, const UFixMath2& uf) {return -u /** Instanciate an signed fixed point math number. -@param NI The number of bits encoding the integer part -@param NF The number of bits encoding the fractional part + @param NI The number of bits encoding the integer part + @param NF The number of bits encoding the fractional part */ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class SFixMath2 @@ -430,63 +431,63 @@ class SFixMath2 */ SFixMath2() {;} - /** Constructor from a floating point value. -@param fl Floating point value -@return An signed fixed point number + /** Constructor from a floating point value. + @param fl Floating point value + @return An signed fixed point number */ SFixMath2(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} /** Constructor from a floating point value. -@param fl Floating point value -@return An signed fixed point number + @param fl Floating point value + @return An signed fixed point number */ SFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } - /** Constructor from an integer value which can be interpreted as both a resulting fixed point -math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number. -@param value Integer value -@param as_raw=false with false value will be interpreted as an integer, with true it will be interpreted as a number with decimals. -@return An signed fixed point number + /** Constructor from an integer value which can be interpreted as both a resulting fixed point + math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number. + @param value Integer value + @param as_raw=false with false value will be interpreted as an integer, with true it will be interpreted as a number with decimals. + @return An signed fixed point number */ template SFixMath2(T value,bool as_raw=false) { - // if (as_frac) internal_value = value; - if (as_raw) fromRaw(value); + if (as_raw) internal_value = value; else internal_value = (internal_type(value) << NF); } - /** Set the internal value of the fixed point math number. -@param raw The new internal value. + /** Set the internal value of the fixed point math number. + @param raw The new internal value. + @return A SFixMath2. */ template - void fromRaw(T raw) { internal_value = raw; } + static SFixMath2 fromRaw(T raw){return UFixMath2(raw,true);} - /** Constructor from another sFixMath2. -@param uf A signed fixed type number which value can be represented in this type. -@return A signed fixed type number + /** Constructor from another SFixMath2. + @param uf A signed fixed type number which value can be represented in this type. + @return A signed fixed type number */ template SFixMath2(const SFixMath2<_NI,_NF>& uf) { - internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } /** Constructor from another UFixMath2. -@param uf A unsigned fixed type number. -@return A signed fixed type number + @param uf A unsigned fixed type number which value can be represented in this type. + @return A signed fixed type number */ template SFixMath2(const UFixMath2<_NI,_NF>& uf) { - internal_value = SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS - /** Addition with another SFixMath2. Safe. -@param op The SFixMath2 to be added. -@return The result of the addition as a SFixMath2. + /** Addition with another SFixMath2. Safe. + @param op The SFixMath2 to be added. + @return The result of the addition as a SFixMath2. */ template SFixMath2 operator+ (const SFixMath2<_NI,_NF>& op) const @@ -502,8 +503,8 @@ math number with a fractional part equals to 0, or as a number with decimal, ie } /** Addition with another type. Unsafe -@param op The number to be added. -@return The result of the addition as a UFixMath2. + @param op The number to be added. + @return The result of the addition as a UFixMath2. */ template SFixMath2 operator+ (const T op) const @@ -514,14 +515,14 @@ math number with a fractional part equals to 0, or as a number with decimal, ie //////// SUBSTRACTION OVERLOADS - /** Subtraction with another SFixMath2. Safe. -@param op The SFixMath2 to be subtracted. -@return The result of the subtraction as a SFixMath2. + /** Subtraction with another SFixMath2. Safe. + @param op The SFixMath2 to be subtracted. + @return The result of the subtraction as a SFixMath2. */ - template // We do not have the +1 after MAX(NI, _NI) because the substraction between two SFix should fit in the bigger of the two. - SFixMath2 operator- (const SFixMath2<_NI,_NF>& op) const + template + SFixMath2 operator- (const SFixMath2<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; SFixMath2 left(*this); @@ -532,9 +533,9 @@ math number with a fractional part equals to 0, or as a number with decimal, ie } - /** Subtraction with another type. Unsafe -@param op The number to be subtracted. -@return The result of the subtraction as a SFixMath2. + /** Subtraction with another type. Unsafe + @param op The number to be subtracted. + @return The result of the subtraction as a SFixMath2. */ template SFixMath2 operator- (const T op) const @@ -543,8 +544,8 @@ math number with a fractional part equals to 0, or as a number with decimal, ie } - /** Opposite of the number. -@return The opposite numberas a SFixMath2. + /** Opposite of the number. + @return The opposite numberas a SFixMath2. */ SFixMath2 operator-() const { @@ -554,8 +555,8 @@ math number with a fractional part equals to 0, or as a number with decimal, ie //////// MULTIPLICATION OVERLOADS /** Multiplication with another SFixMath2. Safe. -@param op The SFixMath2 to be multiplied. -@return The result of the multiplication as a SFixMath2. + @param op The SFixMath2 to be multiplied. + @return The result of the multiplication as a SFixMath2. */ template SFixMath2 operator* (const SFixMath2<_NI,_NF>& op) const @@ -566,8 +567,8 @@ math number with a fractional part equals to 0, or as a number with decimal, ie } /** Multiplication with another type. Unsafe. -@param op The number to be multiplied. -@return The result of the multiplication as a UFixMath2. + @param op The number to be multiplied. + @return The result of the multiplication as a UFixMath2. */ template SFixMath2 operator* (const T op) const @@ -577,9 +578,9 @@ math number with a fractional part equals to 0, or as a number with decimal, ie /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. -Better to use .sR() if possible instead. -@param op The shift number -@return The result of the shift as a SFixMath2. + Better to use .sR() if possible instead. + @param op The shift number + @return The result of the shift as a SFixMath2. */ SFixMath2 operator>> (const byte op) const { @@ -587,18 +588,18 @@ Better to use .sR() if possible instead. } /** Left shift. This can overflow if you shift to a value that cannot be represented. -Better to use .sL() if possible instead. -@param op The shift number -@return The result of the shift as a UFixMath2. + Better to use .sL() if possible instead. + @param op The shift number + @return The result of the shift as a UFixMath2. */ SFixMath2 operator<< (const byte op) const { return SFixMath2(internal_value< SFixMath2 sR() @@ -606,9 +607,9 @@ Better to use .sL() if possible instead. return SFixMath2(internal_value>>op,true); } - /** Safe and optimal left shift. The returned type will be adjusted accordingly -@param op The shift number -@return The result of the shift as a UFixMath2 of bigger size. + /** Safe and optimal left shift. The returned type will be adjusted accordingly + @param op The shift number + @return The result of the shift as a UFixMath2 of bigger size. */ template SFixMath2 sL() @@ -617,22 +618,22 @@ Better to use .sL() if possible instead. } /** Returns the value as floating point number. -@return The floating point value. + @return The floating point value. */ float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)< operator-(double op, const SFixMath2& uf) {return (-uf - /** Multiplication between a SFixMath2 and a UFixMath2. Safe. -@param op1 A SFixMath2 -@param op2 A UFixMath2 -@return The result of the multiplication of op1 and op2. As a SFixMath2 - */ +/** Multiplication between a SFixMath2 and a UFixMath2. Safe. + @param op1 A SFixMath2 + @param op2 A UFixMath2 + @return The result of the multiplication of op1 and op2. As a SFixMath2 +*/ template SFixMath2 operator* (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { @@ -758,11 +759,11 @@ SFixMath2 operator* (const SFixMath2& op1, const UFixMat return SFixMath2(tt,true); } - /** Multiplication between a UFixMath2 and a SFixMath2. Safe. -@param op1 A UFixMath2 -@param op2 A SFixMath2 -@return The result of the multiplication of op1 and op2. As a SFixMath2 - */ +/** Multiplication between a UFixMath2 and a SFixMath2. Safe. + @param op1 A UFixMath2 + @param op2 A SFixMath2 + @return The result of the multiplication of op1 and op2. As a SFixMath2 +*/ template SFixMath2 operator* (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { @@ -773,15 +774,15 @@ SFixMath2 operator* (const UFixMath2& op1, const SFixMat // Addition between SFixMath2 and UFixMath2 (promotion to next SFixMath2) - /** Addition between a SFixMath2 and a UFixMath2. Safe. -@param op1 A SFixMath2 -@param op2 A UFixMath2 -@return The result of the addition of op1 and op2. As a SFixMath2 - */ +/** Addition between a SFixMath2 and a UFixMath2. Safe. + @param op1 A SFixMath2 + @param op2 A UFixMath2 + @return The result of the addition of op1 and op2. As a SFixMath2 +*/ template -SFixMath2 operator+ (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator+ (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI) + 1; + constexpr byte new_NI = MAX(NI, _NI + 1) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; @@ -791,28 +792,28 @@ SFixMath2 operator+ (const SFixMath2& op1, con return SFixMath2(tt,true); } - /** Addition between a UFixMath2 and a SFixMath2. Safe. -@param op1 A UFixMath2 -@param op2 A SFixMath2 -@return The result of the addition of op1 and op2. As a SFixMath2 - */ +/** Addition between a UFixMath2 and a SFixMath2. Safe. + @param op1 A UFixMath2 + @param op2 A SFixMath2 + @return The result of the addition of op1 and op2. As a SFixMath2 +*/ template -SFixMath2 operator+ (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator+ (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { return op2+op1; } // Substraction between SFixMath2 and UFixMath2 (promotion to next SFixMath2) - /** Subtraction between a SFixMath2 and a UFixMath2. Safe. -@param op1 A SFixMath2 -@param op2 A UFixMath2 -@return The result of the subtraction of op1 by op2. As a SFixMath2 - */ +/** Subtraction between a SFixMath2 and a UFixMath2. Safe. + @param op1 A SFixMath2 + @param op2 A UFixMath2 + @return The result of the subtraction of op1 by op2. As a SFixMath2 +*/ template -SFixMath2 operator- (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator- (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI) + 1; + constexpr byte new_NI = MAX(NI, _NI+1) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; @@ -822,24 +823,16 @@ SFixMath2 operator- (const SFixMath2& op1, con return SFixMath2(tt,true); } - /** Subtraction between a UFixMath2 and a SFixMath2. Safe. -@param op1 A UFixMath2 -@param op2 A SFixMath2 -@return The result of the subtraction of op1 by op2. As a SFixMath2 - */ +/** Subtraction between a UFixMath2 and a SFixMath2. Safe. + @param op1 A UFixMath2 + @param op2 A SFixMath2 + @return The result of the subtraction of op1 by op2. As a SFixMath2 +*/ template -SFixMath2 operator- (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator- (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { return -op2+op1; - /* constexpr byte new_NI = MAX(NI, _NI) + 1; - constexpr byte new_NF = MAX(NF, _NF); - - typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; - SFixMath2 left(op1); - SFixMath2 right(op2); - return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath2(tt,true);*/ } - +#undef MAX #endif From 659da6adccf528be0569d91202203176b8fc592e Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 26 Nov 2023 13:57:31 +0100 Subject: [PATCH 028/215] Changed way of counting bits for UFixMath. Added simplifying macros --- FixMath2.h | 115 +++++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index 81b614a15..ad58d2af4 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -39,6 +39,8 @@ #define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) (N1 > N2 ? N1 : N2) +#define UBITSTOBYTES(N) (((N-1)>>3)+1) +#define SBITSTOBYTES(N) (((N)>>3)+1) // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1< // NI and NF being the number of bits for the integra class UFixMath2 { static_assert(NI+NF<=64, "The total width of a UFixMath2 cannot exceed 64bits"); - typedef typename IntegerType<((NI+NF-1)>>3)+1>::unsigned_type internal_type ; // smallest size that fits our internal integer - typedef typename IntegerType<((NI+NF)>>3)+1>::unsigned_type next_greater_type ; // smallest size that fits 1<::unsigned_type internal_type ; // smallest size that fits our internal integer + typedef typename IntegerType::unsigned_type next_greater_type ; // smallest size that fits 1< UFixMath2(const UFixMath2<_NI,_NF>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } /** Constructor from another SFixMath2. @@ -140,7 +143,7 @@ class UFixMath2 */ template UFixMath2(const SFixMath2<_NI,_NF>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -155,7 +158,7 @@ class UFixMath2 { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; + typedef typename IntegerType::unsigned_type return_type; UFixMath2 left(*this); UFixMath2 right(op); @@ -178,19 +181,19 @@ class UFixMath2 /** Subtraction with another UFixMath2. Safe. @param op The UFixMath2 to be subtracted. - @return The result of the subtraction as a UFixMath2. + @return The result of the subtraction as a SFixMath2. */ template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - UFixMath2 operator- (const UFixMath2<_NI,_NF>& op) const + SFixMath2 operator- (const UFixMath2<_NI,_NF>& op) const { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; - UFixMath2 left(*this); - UFixMath2 right(op); + typedef typename IntegerType::signed_type return_type; + SFixMath2 left(*this); + SFixMath2 right(op); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return UFixMath2(tt,true); + return SFixMath2(tt,true); } @@ -207,9 +210,9 @@ class UFixMath2 /** Opposite of the number. @return The opposite numberas a SFixMath2. */ - SFixMath2 operator-() const + SFixMath2 operator-() const { - return SFixMath2( -(typename IntegerType<((NI+NF-1+1)>>3)+1>::signed_type)(internal_value),true); + return SFixMath2( -(typename IntegerType::signed_type)(internal_value),true); } //////// MULTIPLICATION OVERLOADS @@ -221,7 +224,8 @@ class UFixMath2 template UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const { - typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; + //typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; + typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return UFixMath2(tt,true); } @@ -262,9 +266,9 @@ class UFixMath2 @return The result of the shift as a UFixMath2 of smaller size. */ template - UFixMath2 sR() + UFixMath2 sR() { - return UFixMath2(internal_value>>op,true); + return UFixMath2(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @@ -272,9 +276,11 @@ class UFixMath2 @return The result of the shift as a UFixMath2 of bigger size. */ template - UFixMath2 sL() + UFixMath2 sL() { - return UFixMath2((typename IntegerType<((NI+op+NF-1)>>3)+1>::unsigned_type) internal_value<((typename IntegerType<((NI+op+NF-op-1)>>3)+1>::unsigned_type) internal_value<((typename IntegerType::unsigned_type) internal_value,true); + return UFixMath2(internal_value,true); } @@ -383,34 +389,34 @@ UFixMath2 operator+(double op, const UFixMath2& uf) {return uf+o // Substraction template -SFixMath2 operator-(uint8_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(uint8_t op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(uint16_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(uint16_t op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(uint32_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(uint32_t op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(uint64_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(uint64_t op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(int8_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(int8_t op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(int16_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(int16_t op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(int32_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(int32_t op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(int64_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(int64_t op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(float op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(float op, const UFixMath2& uf) {return -uf+op;} template -SFixMath2 operator-(double op, const UFixMath2& uf) {return -uf+op;} +SFixMath2 operator-(double op, const UFixMath2& uf) {return -uf+op;} @@ -423,8 +429,8 @@ template // NI and NF being the number of bits for the integra class SFixMath2 { static_assert(NI+NF<64, "The total width of a SFixMath2 cannot exceed 63bits"); - typedef typename IntegerType<((NI+NF-1)>>3)+1>::signed_type internal_type ; // smallest size that fits our internal integer - typedef typename IntegerType<((NI+NF)>>3)+1>::signed_type next_greater_type ; // smallest size that fits 1<::signed_type internal_type ; // smallest size that fits our internal integer + typedef typename IntegerType::signed_type next_greater_type ; // smallest size that fits 1< SFixMath2(const SFixMath2<_NI,_NF>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + } /** Constructor from another UFixMath2. @@ -480,7 +488,8 @@ class SFixMath2 */ template SFixMath2(const UFixMath2<_NI,_NF>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS @@ -494,7 +503,7 @@ class SFixMath2 { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; + typedef typename IntegerType::unsigned_type return_type; SFixMath2 left(*this); SFixMath2 right(op); @@ -524,7 +533,7 @@ class SFixMath2 { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::unsigned_type return_type; + typedef typename IntegerType::unsigned_type return_type; SFixMath2 left(*this); SFixMath2 right(op); @@ -561,7 +570,7 @@ class SFixMath2 template SFixMath2 operator* (const SFixMath2<_NI,_NF>& op) const { - typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::signed_type return_type ; + typedef typename IntegerType::signed_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return SFixMath2(tt,true); } @@ -602,9 +611,9 @@ class SFixMath2 @return The result of the shift as a UFixMath2 of smaller size. */ template - SFixMath2 sR() + SFixMath2 sR() { - return SFixMath2(internal_value>>op,true); + return SFixMath2(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @@ -612,9 +621,9 @@ class SFixMath2 @return The result of the shift as a UFixMath2 of bigger size. */ template - SFixMath2 sL() + SFixMath2 sL() { - return SFixMath2((typename IntegerType<((NI+op+NF-1)>>3)+1>::signed_type) internal_value<(internal_value,true); } /** Returns the value as floating point number. @@ -752,11 +761,11 @@ SFixMath2 operator-(double op, const SFixMath2& uf) {return (-uf @return The result of the multiplication of op1 and op2. As a SFixMath2 */ template -SFixMath2 operator* (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator* (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { - typedef typename IntegerType< ((NI+_NI+1+NF+_NF-1)>>3)+1>::signed_type return_type ; + typedef typename IntegerType< SBITSTOBYTES(NI+_NI+NF+_NF)>::signed_type return_type ; return_type tt = return_type(op1.asRaw())*op2.asRaw(); - return SFixMath2(tt,true); + return SFixMath2(tt,true); } /** Multiplication between a UFixMath2 and a SFixMath2. Safe. @@ -765,7 +774,7 @@ SFixMath2 operator* (const SFixMath2& op1, const UFixMat @return The result of the multiplication of op1 and op2. As a SFixMath2 */ template -SFixMath2 operator* (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator* (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { return op2*op1; } @@ -780,12 +789,12 @@ SFixMath2 operator* (const UFixMath2& op1, const SFixMat @return The result of the addition of op1 and op2. As a SFixMath2 */ template -SFixMath2 operator+ (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator+ (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI + 1) + 1; + constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; + typedef typename IntegerType::signed_type return_type; SFixMath2 left(op1); SFixMath2 right(op2); return_type tt = return_type(left.asRaw()) + right.asRaw(); @@ -798,7 +807,7 @@ SFixMath2 operator+ (const SFixMath2& op1, c @return The result of the addition of op1 and op2. As a SFixMath2 */ template -SFixMath2 operator+ (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator+ (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { return op2+op1; } @@ -811,12 +820,12 @@ SFixMath2 operator+ (const UFixMath2& op1, c @return The result of the subtraction of op1 by op2. As a SFixMath2 */ template -SFixMath2 operator- (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator- (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI+1) + 1; + constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType< ((new_NI+new_NF-1)>>3)+1>::signed_type return_type; + typedef typename IntegerType::signed_type return_type; SFixMath2 left(op1); SFixMath2 right(op2); return_type tt = return_type(left.asRaw()) - right.asRaw(); @@ -829,10 +838,14 @@ SFixMath2 operator- (const SFixMath2& op1, c @return The result of the subtraction of op1 by op2. As a SFixMath2 */ template -SFixMath2 operator- (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +SFixMath2 operator- (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) { return -op2+op1; } #undef MAX +#undef UBITSTOBYTES +#undef SBITSTOBYTES + + #endif From f267ff4be556108a09a9a5d5f4b673e485a700bf Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 26 Nov 2023 16:04:23 +0100 Subject: [PATCH 029/215] Small fix on conversion from UF to SF. Documentation --- FixMath2.h | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/FixMath2.h b/FixMath2.h index ad58d2af4..2a73e7740 100644 --- a/FixMath2.h +++ b/FixMath2.h @@ -17,7 +17,7 @@ signed (SFixMath2) or unsigned (UFixMath2). A fixed point number has its range defined by the number of bits encoding the integer part (NI - in the following) and its precision by the number of bits encoding the fractional part (NF). + in the following) and its precision by the number of bits encoding the fractional part (NF). For UFixMath2 types, the integral part can hold values in [0,2^NI-1], for SFixMath2 types, the integral part can hold values in [-2^NI,2^NI-1]. Like standard C(++) types, the fixed point numbers defined here are following some rules: - any fixed type can be converted to another *as long as the value can be represented in the destination type*. Casting to a bigger type in term of NI and NF is safe, but reducing NI can lead to an overflow if the new type cannot hold the integer value and reducing NF leads to a loss of precision. @@ -26,7 +26,35 @@ - any operation between a signed and an unsigned leads to a signed number - resulting numbers will be casted to a type big enough to store the expected values. It follows that it is worth starting with types that are as small as possible to hold the initial value. - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. - - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. + - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. These shifts are basically on + + More specifically on the returned types of the operations between fixed point math types: + - Additions: + - UFixMath2 + UFixMath2<_NI,_NF> returns UFixMath2 + - SFixMath2 + SFixMath2<_NI,_NF> returns SFixMath2 + - UFixMath2 + SFixMath2<_NI,_NF> returns SFixMath2 + - UFixMath2 + anything_else returns UFixMath2 + - SFixMath2 + anything_else returns SFixMath2 + - Subtractions: + - UFixMath2 - UFixMath2<_NI,_NF> returns SFixMath2 + - SFixMath2 - SFixMath2<_NI,_NF> returns SFixMath2 + - SFixMath2 - UFixMath2<_NI,_NF> returns SFixMath2 + - UFixMath2 - anything_else returns UFixMath2 + - SFixMath2 - anything_else returns SFixMath2 + - (-)SFixMath2 return SFixMath2 + - (-)UFixMath2 return SFixMath2 + - Multiplications: + - UFixMath2 * UFixMath2<_NI,_NF> returns UFixMath2 + - UFixMath2 * SFixMath2<_NI,_NF> returns SFixMath2 + - SFixMath2 * SFixMath2<_NI,_NF> returns SFixMath2 + - UFixMath2 * anything_else returns UFixMath2 + - SFixMath2 * anything_else returns SFixMath2 + - Shifts: + - UFixMath2 .sR returns UFixMath2 + - UFixMath2 .sL returns UFixMath2 + - same for SFixMath2. + + */ @@ -73,7 +101,7 @@ class SFixMath2; /** Instanciate an unsigned fixed point math number. - @param NI The number of bits encoding the integer part + @param NI The number of bits encoding the integer part. The integral part can range into [0, 2^NI -1] @param NF The number of bits encoding the fractional part */ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. @@ -188,7 +216,7 @@ class UFixMath2 { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType::signed_type return_type; + typedef typename IntegerType::signed_type return_type; SFixMath2 left(*this); SFixMath2 right(op); @@ -422,8 +450,9 @@ SFixMath2 operator-(double op, const UFixMath2& uf) {return -uf+ /** Instanciate an signed fixed point math number. - @param NI The number of bits encoding the integer part + @param NI The number of bits encoding the integer part. The integral part can range into [-2^NI, 2^NI -1] @param NF The number of bits encoding the fractional part + @note The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFixMath2<7,0>. */ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class SFixMath2 @@ -488,8 +517,7 @@ class SFixMath2 */ template SFixMath2(const UFixMath2<_NI,_NF>& uf) { - //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS From 2d12770d0b3afbba90393b280c9c0236bdea9481 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 18 Dec 2023 18:52:19 +0100 Subject: [PATCH 030/215] Renamming to FixMath --- FixMath2.h => FixMath.h | 482 ++++++++++++++++++++-------------------- 1 file changed, 241 insertions(+), 241 deletions(-) rename FixMath2.h => FixMath.h (54%) diff --git a/FixMath2.h b/FixMath.h similarity index 54% rename from FixMath2.h rename to FixMath.h index 2a73e7740..fe98cc5df 100644 --- a/FixMath2.h +++ b/FixMath.h @@ -1,5 +1,5 @@ /* - * FixMath2.h + * FixMath.h * * Copyright 2023, Thomas Combriat and the Mozzi team * @@ -14,10 +14,10 @@ /** This file implements two fixed point number classes. These numbers can have a fractional part but are actually standard integers under the hood which makes calculations with them efficient on platforms which do not have a FPU like most micro-controllers. These numbers can be - signed (SFixMath2) or unsigned (UFixMath2). + signed (SFixMath) or unsigned (UFixMath). A fixed point number has its range defined by the number of bits encoding the integer part (NI - in the following) and its precision by the number of bits encoding the fractional part (NF). For UFixMath2 types, the integral part can hold values in [0,2^NI-1], for SFixMath2 types, the integral part can hold values in [-2^NI,2^NI-1]. + in the following) and its precision by the number of bits encoding the fractional part (NF). For UFixMath types, the integral part can hold values in [0,2^NI-1], for SFixMath types, the integral part can hold values in [-2^NI,2^NI-1]. Like standard C(++) types, the fixed point numbers defined here are following some rules: - any fixed type can be converted to another *as long as the value can be represented in the destination type*. Casting to a bigger type in term of NI and NF is safe, but reducing NI can lead to an overflow if the new type cannot hold the integer value and reducing NF leads to a loss of precision. @@ -30,29 +30,29 @@ More specifically on the returned types of the operations between fixed point math types: - Additions: - - UFixMath2 + UFixMath2<_NI,_NF> returns UFixMath2 - - SFixMath2 + SFixMath2<_NI,_NF> returns SFixMath2 - - UFixMath2 + SFixMath2<_NI,_NF> returns SFixMath2 - - UFixMath2 + anything_else returns UFixMath2 - - SFixMath2 + anything_else returns SFixMath2 + - UFixMath + UFixMath<_NI,_NF> returns UFixMath + - SFixMath + SFixMath<_NI,_NF> returns SFixMath + - UFixMath + SFixMath<_NI,_NF> returns SFixMath + - UFixMath + anything_else returns UFixMath + - SFixMath + anything_else returns SFixMath - Subtractions: - - UFixMath2 - UFixMath2<_NI,_NF> returns SFixMath2 - - SFixMath2 - SFixMath2<_NI,_NF> returns SFixMath2 - - SFixMath2 - UFixMath2<_NI,_NF> returns SFixMath2 - - UFixMath2 - anything_else returns UFixMath2 - - SFixMath2 - anything_else returns SFixMath2 - - (-)SFixMath2 return SFixMath2 - - (-)UFixMath2 return SFixMath2 + - UFixMath - UFixMath<_NI,_NF> returns SFixMath + - SFixMath - SFixMath<_NI,_NF> returns SFixMath + - SFixMath - UFixMath<_NI,_NF> returns SFixMath + - UFixMath - anything_else returns UFixMath + - SFixMath - anything_else returns SFixMath + - (-)SFixMath return SFixMath + - (-)UFixMath return SFixMath - Multiplications: - - UFixMath2 * UFixMath2<_NI,_NF> returns UFixMath2 - - UFixMath2 * SFixMath2<_NI,_NF> returns SFixMath2 - - SFixMath2 * SFixMath2<_NI,_NF> returns SFixMath2 - - UFixMath2 * anything_else returns UFixMath2 - - SFixMath2 * anything_else returns SFixMath2 + - UFixMath * UFixMath<_NI,_NF> returns UFixMath + - UFixMath * SFixMath<_NI,_NF> returns SFixMath + - SFixMath * SFixMath<_NI,_NF> returns SFixMath + - UFixMath * anything_else returns UFixMath + - SFixMath * anything_else returns SFixMath - Shifts: - - UFixMath2 .sR returns UFixMath2 - - UFixMath2 .sL returns UFixMath2 - - same for SFixMath2. + - UFixMath .sR returns UFixMath + - UFixMath .sL returns UFixMath + - same for SFixMath. */ @@ -73,8 +73,8 @@ // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1<(X)) - #define UFixAuto(X) (UFixMath2(X))*/ + #define UFixAuto(X) (UFixMath(X)) + #define UFixAuto(X) (UFixMath(X))*/ /* template @@ -86,7 +86,7 @@ } } - #define UFixAuto(X) (UFixMath2(X)) + #define UFixAuto(X) (UFixMath(X)) */ @@ -96,7 +96,7 @@ // Forward declaration template -class SFixMath2; +class SFixMath; @@ -105,28 +105,28 @@ class SFixMath2; @param NF The number of bits encoding the fractional part */ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. -class UFixMath2 +class UFixMath { - static_assert(NI+NF<=64, "The total width of a UFixMath2 cannot exceed 64bits"); + static_assert(NI+NF<=64, "The total width of a UFixMath cannot exceed 64bits"); typedef typename IntegerType::unsigned_type internal_type ; // smallest size that fits our internal integer typedef typename IntegerType::unsigned_type next_greater_type ; // smallest size that fits 1<*/(fl * (next_greater_type(1) << NF));} + UFixMath(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} /** Constructor from a floating point value. @param fl Floating point value @return An unsigned fixed point number */ - UFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } + UFixMath(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ @@ -137,7 +137,7 @@ class UFixMath2 @return An unsigned fixed point number */ template - UFixMath2(T value,bool as_raw=false) + UFixMath(T value,bool as_raw=false) { if (as_raw) internal_value = value; else internal_value = (internal_type(value) << NF); @@ -146,169 +146,169 @@ class UFixMath2 /** Set the internal value of the fixed point math number. @param raw The new internal value. - @return An UFixMath2x + @return An UFixMathx */ template - static UFixMath2 fromRaw(T raw){return UFixMath2(raw,true);} + static UFixMath fromRaw(T raw){return UFixMath(raw,true);} - /** Constructor from another UFixMath2. + /** Constructor from another UFixMath. @param uf An unsigned fixed type number which value can be represented in this type. @return A unsigned fixed type number */ template - UFixMath2(const UFixMath2<_NI,_NF>& uf) { + UFixMath(const UFixMath<_NI,_NF>& uf) { //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } - /** Constructor from another SFixMath2. + /** Constructor from another SFixMath. @param uf An signed fixed type number which value can be represented in this type: sign is thus discarded. @return A unsigned fixed type number */ template - UFixMath2(const SFixMath2<_NI,_NF>& uf) { + UFixMath(const SFixMath<_NI,_NF>& uf) { internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS - /** Addition with another UFixMath2. Safe. - @param op The UFixMath2 to be added. - @return The result of the addition as a UFixMath2. + /** Addition with another UFixMath. Safe. + @param op The UFixMath to be added. + @return The result of the addition as a UFixMath. */ template - UFixMath2 operator+ (const UFixMath2<_NI,_NF>& op) const + UFixMath operator+ (const UFixMath<_NI,_NF>& op) const { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; - UFixMath2 left(*this); - UFixMath2 right(op); + UFixMath left(*this); + UFixMath right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return UFixMath2(tt,true); + return UFixMath(tt,true); } /** Addition with another type. Unsafe @param op The number to be added. - @return The result of the addition as a UFixMath2. + @return The result of the addition as a UFixMath. */ template - UFixMath2 operator+ (const T op) const + UFixMath operator+ (const T op) const { - return UFixMath2(internal_value+((internal_type)op<(internal_value+((internal_type)op< // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - SFixMath2 operator- (const UFixMath2<_NI,_NF>& op) const + SFixMath operator- (const UFixMath<_NI,_NF>& op) const { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; - SFixMath2 left(*this); - SFixMath2 right(op); + SFixMath left(*this); + SFixMath right(op); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath2(tt,true); + return SFixMath(tt,true); } /** Subtraction with another type. Unsafe @param op The number to be subtracted. - @return The result of the subtraction as a UFixMath2. + @return The result of the subtraction as a UFixMath. */ template - UFixMath2 operator- (const T op) const + UFixMath operator- (const T op) const { - return UFixMath2(internal_value-((internal_type)op<(internal_value-((internal_type)op< operator-() const + SFixMath operator-() const { - return SFixMath2( -(typename IntegerType::signed_type)(internal_value),true); + return SFixMath( -(typename IntegerType::signed_type)(internal_value),true); } //////// MULTIPLICATION OVERLOADS - /** Multiplication with another UFixMath2. Safe. - @param op The UFixMath2 to be multiplied. - @return The result of the multiplication as a UFixMath2. + /** Multiplication with another UFixMath. Safe. + @param op The UFixMath to be multiplied. + @return The result of the multiplication as a UFixMath. */ template - UFixMath2 operator* (const UFixMath2<_NI,_NF>& op) const + UFixMath operator* (const UFixMath<_NI,_NF>& op) const { //typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); - return UFixMath2(tt,true); + return UFixMath(tt,true); } /** Multiplication with another type. Unsafe. @param op The number to be multiplied. - @return The result of the multiplication as a UFixMath2. + @return The result of the multiplication as a UFixMath. */ template - UFixMath2 operator* (const T op) const + UFixMath operator* (const T op) const { - return UFixMath2(internal_value*op,true); + return UFixMath(internal_value*op,true); } /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. Better to use .sR() if possible instead. @param op The shift number - @return The result of the shift as a UFixMath2. + @return The result of the shift as a UFixMath. */ - UFixMath2 operator>> (const byte op) const + UFixMath operator>> (const byte op) const { - return UFixMath2(internal_value>>op,true); + return UFixMath(internal_value>>op,true); } /** Left shift. This can overflow if you shift to a value that cannot be represented. Better to use .sL() if possible instead. @param op The shift number - @return The result of the shift as a UFixMath2. + @return The result of the shift as a UFixMath. */ - UFixMath2 operator<< (const byte op) const + UFixMath operator<< (const byte op) const { - return UFixMath2(internal_value<(internal_value< - UFixMath2 sR() + UFixMath sR() { - return UFixMath2(internal_value,true); + return UFixMath(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @param op The shift number - @return The result of the shift as a UFixMath2 of bigger size. + @return The result of the shift as a UFixMath of bigger size. */ template - UFixMath2 sL() + UFixMath sL() { - //return UFixMath2((typename IntegerType<((NI+op+NF-op-1)>>3)+1>::unsigned_type) internal_value<((typename IntegerType::unsigned_type) internal_value,true); - return UFixMath2(internal_value,true); + //return UFixMath((typename IntegerType<((NI+op+NF-op-1)>>3)+1>::unsigned_type) internal_value<((typename IntegerType::unsigned_type) internal_value,true); + return UFixMath(internal_value,true); } @@ -316,11 +316,11 @@ class UFixMath2 // Division. Might actually more misleading than helping. NON Working version below. /* template - UFixMath2 operator/(const UFixMath2& op1, const UFixMath2& op2) + UFixMath operator/(const UFixMath& op1, const UFixMath& op2) { typedef typename IntegerType< ((NI1-NI2+NF1-NF2+1)>>3)+1>::unsigned_type return_type ; return_type tt = (return_type(op1.getInt())<<(NF1-NF2))/op2.getInt(); - return UFixMath2(tt,true); + return UFixMath(tt,true); } */ @@ -355,96 +355,96 @@ class UFixMath2 // Multiplication template -UFixMath2 operator*(uint8_t op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(uint8_t op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(uint16_t op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(uint16_t op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(uint32_t op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(uint32_t op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(uint64_t op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(uint64_t op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(int8_t op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(int8_t op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(int16_t op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(int16_t op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(int32_t op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(int32_t op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(int64_t op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(int64_t op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(float op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(float op, const UFixMath& uf) {return uf*op;} template -UFixMath2 operator*(double op, const UFixMath2& uf) {return uf*op;} +UFixMath operator*(double op, const UFixMath& uf) {return uf*op;} // Addition template -UFixMath2 operator+(uint8_t op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(uint8_t op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(uint16_t op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(uint16_t op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(uint32_t op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(uint32_t op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(uint64_t op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(uint64_t op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(int8_t op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(int8_t op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(int16_t op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(int16_t op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(int32_t op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(int32_t op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(int64_t op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(int64_t op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(float op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(float op, const UFixMath& uf) {return uf+op;} template -UFixMath2 operator+(double op, const UFixMath2& uf) {return uf+op;} +UFixMath operator+(double op, const UFixMath& uf) {return uf+op;} // Substraction template -SFixMath2 operator-(uint8_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(uint8_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(uint16_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(uint16_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(uint32_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(uint32_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(uint64_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(uint64_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(int8_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(int8_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(int16_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(int16_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(int32_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(int32_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(int64_t op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(int64_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(float op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(float op, const UFixMath& uf) {return -uf+op;} template -SFixMath2 operator-(double op, const UFixMath2& uf) {return -uf+op;} +SFixMath operator-(double op, const UFixMath& uf) {return -uf+op;} @@ -452,31 +452,31 @@ SFixMath2 operator-(double op, const UFixMath2& uf) {return -uf+ /** Instanciate an signed fixed point math number. @param NI The number of bits encoding the integer part. The integral part can range into [-2^NI, 2^NI -1] @param NF The number of bits encoding the fractional part - @note The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFixMath2<7,0>. + @note The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFixMath<7,0>. */ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. -class SFixMath2 +class SFixMath { - static_assert(NI+NF<64, "The total width of a SFixMath2 cannot exceed 63bits"); + static_assert(NI+NF<64, "The total width of a SFixMath cannot exceed 63bits"); typedef typename IntegerType::signed_type internal_type ; // smallest size that fits our internal integer typedef typename IntegerType::signed_type next_greater_type ; // smallest size that fits 1<*/(fl * (next_greater_type(1) << NF));} + SFixMath(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} /** Constructor from a floating point value. @param fl Floating point value @return An signed fixed point number */ - SFixMath2(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } + SFixMath(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } /** Constructor from an integer value which can be interpreted as both a resulting fixed point @@ -486,7 +486,7 @@ class SFixMath2 @return An signed fixed point number */ template - SFixMath2(T value,bool as_raw=false) + SFixMath(T value,bool as_raw=false) { if (as_raw) internal_value = value; else internal_value = (internal_type(value) << NF); @@ -494,164 +494,164 @@ class SFixMath2 /** Set the internal value of the fixed point math number. @param raw The new internal value. - @return A SFixMath2. + @return A SFixMath. */ template - static SFixMath2 fromRaw(T raw){return UFixMath2(raw,true);} + static SFixMath fromRaw(T raw){return UFixMath(raw,true);} - /** Constructor from another SFixMath2. + /** Constructor from another SFixMath. @param uf A signed fixed type number which value can be represented in this type. @return A signed fixed type number */ template - SFixMath2(const SFixMath2<_NI,_NF>& uf) { + SFixMath(const SFixMath<_NI,_NF>& uf) { //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } - /** Constructor from another UFixMath2. + /** Constructor from another UFixMath. @param uf A unsigned fixed type number which value can be represented in this type. @return A signed fixed type number */ template - SFixMath2(const UFixMath2<_NI,_NF>& uf) { + SFixMath(const UFixMath<_NI,_NF>& uf) { internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS - /** Addition with another SFixMath2. Safe. - @param op The SFixMath2 to be added. - @return The result of the addition as a SFixMath2. + /** Addition with another SFixMath. Safe. + @param op The SFixMath to be added. + @return The result of the addition as a SFixMath. */ template - SFixMath2 operator+ (const SFixMath2<_NI,_NF>& op) const + SFixMath operator+ (const SFixMath<_NI,_NF>& op) const { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; - SFixMath2 left(*this); - SFixMath2 right(op); + SFixMath left(*this); + SFixMath right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFixMath2(tt,true); + return SFixMath(tt,true); } /** Addition with another type. Unsafe @param op The number to be added. - @return The result of the addition as a UFixMath2. + @return The result of the addition as a UFixMath. */ template - SFixMath2 operator+ (const T op) const + SFixMath operator+ (const T op) const { - return SFixMath2(internal_value+(op<(internal_value+(op< - SFixMath2 operator- (const SFixMath2<_NI,_NF>& op) const + SFixMath operator- (const SFixMath<_NI,_NF>& op) const { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; - SFixMath2 left(*this); - SFixMath2 right(op); + SFixMath left(*this); + SFixMath right(op); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath2(tt,true); + return SFixMath(tt,true); } /** Subtraction with another type. Unsafe @param op The number to be subtracted. - @return The result of the subtraction as a SFixMath2. + @return The result of the subtraction as a SFixMath. */ template - SFixMath2 operator- (const T op) const + SFixMath operator- (const T op) const { - return SFixMath2(internal_value-(op<(internal_value-(op< operator-() const + SFixMath operator-() const { - return SFixMath2(-internal_value,true); + return SFixMath(-internal_value,true); } //////// MULTIPLICATION OVERLOADS - /** Multiplication with another SFixMath2. Safe. - @param op The SFixMath2 to be multiplied. - @return The result of the multiplication as a SFixMath2. + /** Multiplication with another SFixMath. Safe. + @param op The SFixMath to be multiplied. + @return The result of the multiplication as a SFixMath. */ template - SFixMath2 operator* (const SFixMath2<_NI,_NF>& op) const + SFixMath operator* (const SFixMath<_NI,_NF>& op) const { typedef typename IntegerType::signed_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); - return SFixMath2(tt,true); + return SFixMath(tt,true); } /** Multiplication with another type. Unsafe. @param op The number to be multiplied. - @return The result of the multiplication as a UFixMath2. + @return The result of the multiplication as a UFixMath. */ template - SFixMath2 operator* (const T op) const + SFixMath operator* (const T op) const { - return SFixMath2(internal_value*op,true); + return SFixMath(internal_value*op,true); } /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. Better to use .sR() if possible instead. @param op The shift number - @return The result of the shift as a SFixMath2. + @return The result of the shift as a SFixMath. */ - SFixMath2 operator>> (const byte op) const + SFixMath operator>> (const byte op) const { - return SFixMath2(internal_value>>op,true); + return SFixMath(internal_value>>op,true); } /** Left shift. This can overflow if you shift to a value that cannot be represented. Better to use .sL() if possible instead. @param op The shift number - @return The result of the shift as a UFixMath2. + @return The result of the shift as a UFixMath. */ - SFixMath2 operator<< (const byte op) const + SFixMath operator<< (const byte op) const { - return SFixMath2(internal_value<(internal_value< - SFixMath2 sR() + SFixMath sR() { - return SFixMath2(internal_value,true); + return SFixMath(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @param op The shift number - @return The result of the shift as a UFixMath2 of bigger size. + @return The result of the shift as a UFixMath of bigger size. */ template - SFixMath2 sL() + SFixMath sL() { - return SFixMath2(internal_value,true); + return SFixMath(internal_value,true); } /** Returns the value as floating point number. @@ -684,96 +684,96 @@ class SFixMath2 // Multiplication template -SFixMath2 operator*(uint8_t op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(uint8_t op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(uint16_t op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(uint16_t op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(uint32_t op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(uint32_t op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(uint64_t op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(uint64_t op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(int8_t op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(int8_t op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(int16_t op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(int16_t op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(int32_t op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(int32_t op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(int64_t op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(int64_t op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(float op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(float op, const SFixMath& uf) {return uf*op;} template -SFixMath2 operator*(double op, const SFixMath2& uf) {return uf*op;} +SFixMath operator*(double op, const SFixMath& uf) {return uf*op;} // Addition template -SFixMath2 operator+(uint8_t op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(uint8_t op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(uint16_t op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(uint16_t op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(uint32_t op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(uint32_t op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(uint64_t op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(uint64_t op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(int8_t op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(int8_t op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(int16_t op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(int16_t op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(int32_t op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(int32_t op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(int64_t op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(int64_t op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(float op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(float op, const SFixMath& uf) {return uf+op;} template -SFixMath2 operator+(double op, const SFixMath2& uf) {return uf+op;} +SFixMath operator+(double op, const SFixMath& uf) {return uf+op;} // Substraction template -SFixMath2 operator-(uint8_t op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(uint8_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(uint16_t op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(uint16_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(uint32_t op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(uint32_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(uint64_t op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(uint64_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(int8_t op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(int8_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(int16_t op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(int16_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(int32_t op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(int32_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(int64_t op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(int64_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(float op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(float op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath2 operator-(double op, const SFixMath2& uf) {return (-uf)+op;} +SFixMath operator-(double op, const SFixMath& uf) {return (-uf)+op;} @@ -783,90 +783,90 @@ SFixMath2 operator-(double op, const SFixMath2& uf) {return (-uf -/** Multiplication between a SFixMath2 and a UFixMath2. Safe. - @param op1 A SFixMath2 - @param op2 A UFixMath2 - @return The result of the multiplication of op1 and op2. As a SFixMath2 +/** Multiplication between a SFixMath and a UFixMath. Safe. + @param op1 A SFixMath + @param op2 A UFixMath + @return The result of the multiplication of op1 and op2. As a SFixMath */ template -SFixMath2 operator* (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +SFixMath operator* (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { typedef typename IntegerType< SBITSTOBYTES(NI+_NI+NF+_NF)>::signed_type return_type ; return_type tt = return_type(op1.asRaw())*op2.asRaw(); - return SFixMath2(tt,true); + return SFixMath(tt,true); } -/** Multiplication between a UFixMath2 and a SFixMath2. Safe. - @param op1 A UFixMath2 - @param op2 A SFixMath2 - @return The result of the multiplication of op1 and op2. As a SFixMath2 +/** Multiplication between a UFixMath and a SFixMath. Safe. + @param op1 A UFixMath + @param op2 A SFixMath + @return The result of the multiplication of op1 and op2. As a SFixMath */ template -SFixMath2 operator* (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +SFixMath operator* (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2*op1; } -// Addition between SFixMath2 and UFixMath2 (promotion to next SFixMath2) +// Addition between SFixMath and UFixMath (promotion to next SFixMath) -/** Addition between a SFixMath2 and a UFixMath2. Safe. - @param op1 A SFixMath2 - @param op2 A UFixMath2 - @return The result of the addition of op1 and op2. As a SFixMath2 +/** Addition between a SFixMath and a UFixMath. Safe. + @param op1 A SFixMath + @param op2 A UFixMath + @return The result of the addition of op1 and op2. As a SFixMath */ template -SFixMath2 operator+ (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; - SFixMath2 left(op1); - SFixMath2 right(op2); + SFixMath left(op1); + SFixMath right(op2); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFixMath2(tt,true); + return SFixMath(tt,true); } -/** Addition between a UFixMath2 and a SFixMath2. Safe. - @param op1 A UFixMath2 - @param op2 A SFixMath2 - @return The result of the addition of op1 and op2. As a SFixMath2 +/** Addition between a UFixMath and a SFixMath. Safe. + @param op1 A UFixMath + @param op2 A SFixMath + @return The result of the addition of op1 and op2. As a SFixMath */ template -SFixMath2 operator+ (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +SFixMath operator+ (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2+op1; } -// Substraction between SFixMath2 and UFixMath2 (promotion to next SFixMath2) +// Substraction between SFixMath and UFixMath (promotion to next SFixMath) -/** Subtraction between a SFixMath2 and a UFixMath2. Safe. - @param op1 A SFixMath2 - @param op2 A UFixMath2 - @return The result of the subtraction of op1 by op2. As a SFixMath2 +/** Subtraction between a SFixMath and a UFixMath. Safe. + @param op1 A SFixMath + @param op2 A UFixMath + @return The result of the subtraction of op1 by op2. As a SFixMath */ template -SFixMath2 operator- (const SFixMath2& op1, const UFixMath2<_NI,_NF>& op2 ) +SFixMath operator- (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; - SFixMath2 left(op1); - SFixMath2 right(op2); + SFixMath left(op1); + SFixMath right(op2); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath2(tt,true); + return SFixMath(tt,true); } -/** Subtraction between a UFixMath2 and a SFixMath2. Safe. - @param op1 A UFixMath2 - @param op2 A SFixMath2 - @return The result of the subtraction of op1 by op2. As a SFixMath2 +/** Subtraction between a UFixMath and a SFixMath. Safe. + @param op1 A UFixMath + @param op2 A SFixMath + @return The result of the subtraction of op1 by op2. As a SFixMath */ template -SFixMath2 operator- (const UFixMath2& op1, const SFixMath2<_NI,_NF>& op2 ) +SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return -op2+op1; } From 735da568b8a896da290ccc0706ee8bd40d40b0a8 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 18 Dec 2023 22:16:12 +0100 Subject: [PATCH 031/215] Implemented midi functions for UFixMath --- mozzi_midi.cpp | 12 ++++++++++++ mozzi_midi.h | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/mozzi_midi.cpp b/mozzi_midi.cpp index 0ae7c4737..c7d5758cd 100644 --- a/mozzi_midi.cpp +++ b/mozzi_midi.cpp @@ -166,3 +166,15 @@ A good choice if you're using whole note values, want speed and simplicity, and int mtof(int midi_note){ return (FLASH_OR_RAM_READ(midiToFreq + midi_note) >> 16); } + +inline UFixMath<16,16> mtof(UFixMath<16,16> midival) +{ + return Q16n16_mtof(midival.asRaw()); +} + + +template + inline UFixMath<16,16> mtof(UFixMath midival) +{ + return Q16n16_mtof(UFixMath<16,16>(midival).asRaw()); +} diff --git a/mozzi_midi.h b/mozzi_midi.h index e71995719..38d11e200 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -2,10 +2,15 @@ #define MOZZI_MIDI_H_ #include "mozzi_fixmath.h" +#include "FixMath.h" float mtof(float x); int mtof(uint8_t midi_note); int mtof(int midi_note); Q16n16 Q16n16_mtof(Q16n16 midival); +UFixMath<16,16> mtof(UFixMath<16,16> midival); + +template + UFixMath<16,16> mtof(UFixMath midival); #endif /* MOZZI_MIDI_H_ */ From 11545ddd74078d41be6d00907678a64f43e5b343 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 19 Dec 2023 22:16:33 +0100 Subject: [PATCH 032/215] Implemented mozzi_midi for FixMath --- mozzi_midi.cpp | 11 ----------- mozzi_midi.h | 17 +++++++++++++++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/mozzi_midi.cpp b/mozzi_midi.cpp index c7d5758cd..09b28d337 100644 --- a/mozzi_midi.cpp +++ b/mozzi_midi.cpp @@ -167,14 +167,3 @@ int mtof(int midi_note){ return (FLASH_OR_RAM_READ(midiToFreq + midi_note) >> 16); } -inline UFixMath<16,16> mtof(UFixMath<16,16> midival) -{ - return Q16n16_mtof(midival.asRaw()); -} - - -template - inline UFixMath<16,16> mtof(UFixMath midival) -{ - return Q16n16_mtof(UFixMath<16,16>(midival).asRaw()); -} diff --git a/mozzi_midi.h b/mozzi_midi.h index 38d11e200..9734f1fac 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -8,9 +8,22 @@ float mtof(float x); int mtof(uint8_t midi_note); int mtof(int midi_note); Q16n16 Q16n16_mtof(Q16n16 midival); -UFixMath<16,16> mtof(UFixMath<16,16> midival); + +inline UFixMath<16,16> mtof(UFixMath<16,16> midival) +{ + return Q16n16_mtof(midival.asRaw()); +} + +template + inline UFixMath<16,16> mtof(UFixMath midival) +{ + return Q16n16_mtof(UFixMath<16,16>(midival).asRaw()); +} template - UFixMath<16,16> mtof(UFixMath midival); + inline UFixMath<16,16> mtof(SFixMath midival) +{ + return Q16n16_mtof(UFixMath<16,16>(midival).asRaw()); +} #endif /* MOZZI_MIDI_H_ */ From 3f09dedca42ab36c9379f16f434acefb4e1a3c15 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 19 Dec 2023 22:17:59 +0100 Subject: [PATCH 033/215] Implemented setFreq and phMod for Oscil using FixMath --- Oscil.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/Oscil.h b/Oscil.h index d5b302daf..5068a8fe0 100644 --- a/Oscil.h +++ b/Oscil.h @@ -21,6 +21,7 @@ #endif #include "MozziGuts.h" #include "mozzi_fixmath.h" +#include "FixMath.h" #include "mozzi_pgmspace.h" #ifdef OSCIL_DITHER_PHASE @@ -154,6 +155,19 @@ class Oscil } + /** Returns the next sample given a phase modulation value. + @param phmod_proportion a phase modulation value given as a proportion of the wave. The + phmod_proportion parameter is a SFixMath<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in + each direction. + @return a sample from the table. + */ + inline + int8_t phMod(SFixMath<15,16> phmod_proportion) + { + return phMod(phmod_proportion.asRaw()); + } + + /** Set the oscillator frequency with an unsigned int. This is faster than using a float, so it's useful when processor time is tight, but it can be tricky with low and high frequencies, depending on the size of the wavetable being used. If @@ -207,6 +221,19 @@ class Oscil } } + /** Set the frequency using UFixMath<24,8> fixed-point number format. + This might be faster than the float version for setting low frequencies such as + 1.5 Hz, or other values which may not work well with your table size. A UFixMath<24,8> + representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE + less than 64 Hz. + @param frequency in UFixMath<24,8> fixed-point number format. + */ + inline + void setFreq(UFixMath<24,8> frequency) + { + setFreq_Q24n8(frequency.asRaw()); + } + /** Set the frequency using Q16n16 fixed-point number format. This is useful in combination with Q16n16_mtof(), a fast alternative to mtof(), using Q16n16 @@ -230,6 +257,36 @@ class Oscil phase_increment_fractional = ((unsigned long)frequency) / (UPDATE_RATE/NUM_TABLE_CELLS); } } + + + /** Set the frequency using UFixMath<16,16> fixed-point number format. This is useful in + combination with Q16n16_mtof(), a fast alternative to mtof(), using UFixMath<16,16> + fixed-point format instead of fractional numbers. + @note This should work OK with tables 2048 cells or smaller and + frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz. + @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. + @param frequency in UFixMath<16,16> fixed-point number format. + */ + inline + void setFreq(UFixMath<16,16> frequency) + { + setFreq_Q16n16(frequency.asRaw()); + } + + + /** Set the frequency using UFixMath fixed-point number format. This falls back to using UFixMath<16,16> internally and is provided as a fallout for other UFixMath types. If possible try to use directly UFixMath<16,16> or UFixMath<24,8> for well defined (and well tested) behaviors. + @note This should work OK with tables 2048 cells or smaller and + frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz. + @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. + @param frequency in UFixMath<16,16> fixed-point number format. + */ + template + inline + void setFreq(UFixMath frequency) + { + setFreq_Q16n16(UFixMath<16,16>(frequency).asRaw()); + } + /* inline void setFreqMidi(int8_t note_num) { From 0c495ebf805cd22c19fe1bbaf17e9e11c3d457bf Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 19 Dec 2023 22:21:41 +0100 Subject: [PATCH 034/215] Added template for signed FixMath to Oscil setFreq --- Oscil.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Oscil.h b/Oscil.h index 5068a8fe0..f2608a120 100644 --- a/Oscil.h +++ b/Oscil.h @@ -278,7 +278,7 @@ class Oscil @note This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz. @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. - @param frequency in UFixMath<16,16> fixed-point number format. + @param frequency in UFixMath fixed-point number format. */ template inline @@ -286,6 +286,19 @@ class Oscil { setFreq_Q16n16(UFixMath<16,16>(frequency).asRaw()); } + + /** Set the frequency using SFixMath fixed-point number format. This falls back to using UFixMath<16,16> internally and is provided as a fallout for other UFixMath types. If possible try to use directly UFixMath<16,16> or UFixMath<24,8> for well defined (and well tested) behaviors. + @note This should work OK with tables 2048 cells or smaller and + frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz. + @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. + @param frequency in SFixMath<16,16> fixed-point number format. + */ + template + inline + void setFreq(SFixMath frequency) + { + setFreq_Q16n16(UFixMath<16,16>(frequency).asRaw()); + } /* inline From 862954fd269675c4ebb5dc7b7a82e42630b075dd Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 24 Dec 2023 15:47:24 +0100 Subject: [PATCH 035/215] Fixed mozzi_midi.h with FixMath --- mozzi_midi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mozzi_midi.h b/mozzi_midi.h index 9734f1fac..88ebae2a3 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -11,19 +11,19 @@ Q16n16 Q16n16_mtof(Q16n16 midival); inline UFixMath<16,16> mtof(UFixMath<16,16> midival) { - return Q16n16_mtof(midival.asRaw()); + return UFixMath<16,16>::fromRaw(Q16n16_mtof(midival.asRaw())); } template inline UFixMath<16,16> mtof(UFixMath midival) { - return Q16n16_mtof(UFixMath<16,16>(midival).asRaw()); + return UFixMath<16,16>::fromRaw(Q16n16_mtof(UFixMath<16,16>(midival).asRaw())); } template inline UFixMath<16,16> mtof(SFixMath midival) { - return Q16n16_mtof(UFixMath<16,16>(midival).asRaw()); + return UFixMath<16,16>::fromRaw(Q16n16_mtof(UFixMath<16,16>(midival).asRaw())); } #endif /* MOZZI_MIDI_H_ */ From 9f43c812ca7b7cf2d34c726655398ea834851211 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 24 Dec 2023 16:47:06 +0100 Subject: [PATCH 036/215] Added comparison between FixMath --- FixMath.h | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 153 insertions(+), 2 deletions(-) diff --git a/FixMath.h b/FixMath.h index fe98cc5df..eff01c296 100644 --- a/FixMath.h +++ b/FixMath.h @@ -269,6 +269,8 @@ class UFixMath } + //////// SHIFTS OVERLOADS + /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. Better to use .sR() if possible instead. @param op The shift number @@ -306,11 +308,47 @@ class UFixMath template UFixMath sL() { - //return UFixMath((typename IntegerType<((NI+op+NF-op-1)>>3)+1>::unsigned_type) internal_value<((typename IntegerType::unsigned_type) internal_value,true); return UFixMath(internal_value,true); } + + //////// COMPARISON OVERLOADS + + template + bool operator> (const UFixMath<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + UFixMath left(*this); + UFixMath right(op); + return left.asRaw()>right.asRaw(); + } + + template + bool operator< (const UFixMath<_NI,_NF>& op) const + { + return op > *this; + } + + template + bool operator== (const UFixMath<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + UFixMath left(*this); + UFixMath right(op); + return left.asRaw()==right.asRaw(); + } + + template + bool operator!= (const UFixMath<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + UFixMath left(*this); + UFixMath right(op); + return left.asRaw()!=right.asRaw(); + } // Division. Might actually more misleading than helping. NON Working version below. @@ -614,6 +652,8 @@ class SFixMath } + //////// SHIFTS OVERLOADS + /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. Better to use .sR() if possible instead. @param op The shift number @@ -654,6 +694,46 @@ class SFixMath return SFixMath(internal_value,true); } + + //////// COMPARISON OVERLOADS + + template + bool operator> (const SFixMath<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + SFixMath left(*this); + SFixMath right(op); + return left.asRaw()>right.asRaw(); + } + + template + bool operator< (const SFixMath<_NI,_NF>& op) const + { + return op > *this; + } + + template + bool operator== (const SFixMath<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + SFixMath left(*this); + SFixMath right(op); + return left.asRaw()==right.asRaw(); + } + + template + bool operator!= (const SFixMath<_NI,_NF>& op) const + { + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + SFixMath left(*this); + SFixMath right(op); + return left.asRaw()!=right.asRaw(); + } + + /** Returns the value as floating point number. @return The floating point value. */ @@ -871,6 +951,77 @@ SFixMath operator- (const UFixMath& op1, const return -op2+op1; } +// Comparaison between SFixMath and UFixmath + +template +bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +{ + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + SFixMath left(op1); + SFixMath right(op2); + return left.asRaw() > right.asRaw(); +} + +template +bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +{ + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + SFixMath left(op1); + SFixMath right(op2); + return left.asRaw() > right.asRaw(); +} + +template +bool operator< (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +{ + return op2 > op1; +} + +template +bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +{ + return op2 > op1; +} + + + +template +bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +{ + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + SFixMath left(op1); + SFixMath right(op2); + return left.asRaw() == right.asRaw(); +} + +template +bool operator== (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +{ + return op2 == op1; +} + +template +bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +{ + constexpr byte new_NI = MAX(NI, _NI); + constexpr byte new_NF = MAX(NF, _NF); + SFixMath left(op1); + SFixMath right(op2); + return left.asRaw() != right.asRaw(); +} + +template +bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +{ + return op2 != op1; +} + + + + #undef MAX #undef UBITSTOBYTES #undef SBITSTOBYTES From 1d6f87b207691b9db01d63df6583da9d8492372d Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Wed, 3 Jan 2024 13:19:26 +0100 Subject: [PATCH 037/215] Add a multi-complation-unit example This is pretty pointless at the time being, but will be marginally useful, to demonstrate how to customize config in that case, once Mozzi itself is compiled as single compilation unit. Add it now, already (at the Mozzi2-branch), so it is available as a baseline for the "report" action in future PRs. --- .../Skeleton_Multi/Skeleton_Multi.ino | 19 +++++++++++++++++++ .../Skeleton_Multi/Skeleton_Multi_Unit2.cpp | 5 +++++ 2 files changed, 24 insertions(+) create mode 100644 examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino create mode 100644 examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp diff --git a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino new file mode 100644 index 000000000..2c9cc85a2 --- /dev/null +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino @@ -0,0 +1,19 @@ +/** This example shows how to set up a sketch where Mozzi-related functions are called + * from more than one .cpp source file (which will be compiled, separately). + * + * Unless you have good reason to do this, it is recommended to base your sketch on the + * single-file "Skeleton" example, instead. */ + +#include // at the top of your sketch + +void setup() { + startMozzi(64); +} + +void updateControl() { + // your control code +} + +void loop() { + audioHook(); // fills the audio buffer +} diff --git a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp new file mode 100644 index 000000000..a661c8e32 --- /dev/null +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp @@ -0,0 +1,5 @@ +#include // This file, too, will have to include the Mozzi headers. + +AudioOutput_t updateAudio() { + return MonoOutput::from8Bit(0); // just a dummy +} From 30cb150839637693a2a149e54ad3c97bdcfb1a86 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 13 Nov 2023 17:04:29 +0100 Subject: [PATCH 038/215] Start config rework This does not actually do anything yet, but I hope the outline is becoming visible. Plan is to finish this outline for AVR, first, then adapt MozziGuts, and get it to compile for AVR, then follow up on the other platforms. --- MozziConfigExample.h | 267 ++++++++++++++++++++++++++++++++ MozziConfigValues.h | 40 +++++ internal/Readme.md | 4 + internal/config_check_generic.h | 79 ++++++++++ internal/config_checks_avr.h | 24 +++ internal/mozzi_macros.h | 34 ++++ 6 files changed, 448 insertions(+) create mode 100644 MozziConfigExample.h create mode 100644 MozziConfigValues.h create mode 100644 internal/Readme.md create mode 100644 internal/config_check_generic.h create mode 100644 internal/config_checks_avr.h create mode 100644 internal/mozzi_macros.h diff --git a/MozziConfigExample.h b/MozziConfigExample.h new file mode 100644 index 000000000..aef19bb55 --- /dev/null +++ b/MozziConfigExample.h @@ -0,0 +1,267 @@ +/*! @ingroup core + * @file MozziConfigExample.h + * + * @brief Mozzi Configuration + * + * @note + * It is generally safe to leave the Mozzi Configuration unchanged, and that's very much recommended _until_ you have a very specific need to customize something. + * + * Usage: + * - either: + * 1. Copy this file to your sketch directory + * 2. Adjust as desired, uncommenting only those options that you intend to change from their default value + * 3. #include it in your sketch **before** #include + * (must be included in each .cpp-file using Mozzi inside your sketch, if more than one) + * - or: + * 1. Copy only the sections you want to customize + * 2. Put them near the top of your sketch **before** #include + * (should your sketch have more than one .cpp-file, identical options need to be set before each #include ) + * + * TODO: Fix and complete Doxygen coverage +*/ + +/** @ingroup core + * @def MOZZI_COMPATIBILTY_LEVEL + * + * Mozzi generally tries to keep your old sketches working, but we continue to find new (and hopefully better) approaches to old problems. + * Sometimes, keeping API compatibilty with the pre-existing solution may come with a smaller or larger penalty in terms of performance or code size. + * Therefore - if your sketch supports it - you may be able to get some minor benefit from disabling compatibility code. + * + * Currently supported values are: + * - MOZZI_COMPATIBILITY_1_1 - try to support sketches written for Mozzi version 1.1 (or possibly lower); this is the default when including MozziGuts.h + * - MOZZI_COMPATIBILITY_2_0 - try to support sketches written for Mozzi version 2.0; this is - currently - the default when including Mozzi.h + * - MOZZI_COMPATIBILITY_LATEST - always live on the bleeding edge + * + * @note + * MOZZI_COMPATIBILTY_V1_1 does not guarantee, that *everything* from Mozzi 1.1 will continue to work, just that we're doing a reasonable effort. +*/ +//#define MOZZI_COMPATIBILTY_LEVEL MOZZI_COMPATIBILTY_LATEST + +/** @ingroup core + * @def MOZZI_AUDIO_MODE + * + * @brief Configure how Mozzi outputs generated sounds. + * + * @note + * Not all options are available on all platforms, and several options require specific wiring or external components to function on top of this! + * When customizing this, it is highly recommended to start experimenting with a simple and known-to-work sketch (such as a basic sinewave) to verify that your + * hardware setup is correct. Similarly, if you observe problems running your "real" sketch, it is often a good idea ot test your sketch with the default audio mode, + * too (by leaving this option, and preferrably all others, unset). + * + * TODO: link to specific documentation for each option/platform, and/or spell out, what is supported, where + * + * Supported values: + * - MOZZI_OUTPUT_PWM Output using pulse width modulation (PWM) on a GPIO pin. This is the default on most platforms. + * On the Arduino Uno (more generally ATMEGA328P), this allows for a sample resolution of 488 (almost 9 bits) on pin 9. + * Usable pins and resolution will be different on other boards. + * - MOZZI_OUTPUT_2PIN_PWM Output using pulse width modulation on two GPIO pins, where one pin represents the lower bits, and the other the higer bits of the sample. + * On the Aduino Uno, this allows for 14 bits of resolution on pins 9 (low) and 10 (high). For further information (wiring etc.) see TODO add ref. + * - MOZZI_OUTPUT_EXTERNAL Output is not controlled by Mozzi itself, but left to the user sketch. This setting allows to completely customize the audio output, e.g. + * for connecting to external DACs. For more detail, @see AudioOuput + * - MOZZI_OUTPUT_PDM_VIA_I2S Output pulse density modulated (PDM) samples via a (hardware) I2S interface (without a DAC connected to it). + * - MOZZI_OUTPUT_PDM_VIA_SERIAL Output pulse density modulated (PDM) samples via a hardware serial interface. + * - MOZZI_OUTPUT_I2S_DAC Output samples to a PT8211 (or compatible) DAC connected to a hardware I2S interface. + * - MOZZI_OUTPUT_INTERNAL_DAC Output to the interal DAC on boards that support one. + * + * TODO: Adding an R2R-DAC option would be cool, http://blog.makezine.com/2008/05/29/makeit-protodac-shield-fo/ , some discussion on Mozzi-users. +*/ +//#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM + + +/** @ingroup core + * @def MOZZI_AUDIO_CHANNELS + * + * This sets allows to change from a single/mono audio output channel to + * stereo output. To actually generate two channels, your updateAudio()-function + * should return a StereoOutput(). Sketches returning a MonoOutput() in a stereo + * config, or vice versa will continue to work, but will generate a warning a + * compile time. + * + * @note This option superseeds the earlier STEREO_HACK, which is still available at + * the time of this writing, but should not be used in new sketches. + * + * @note At the time of this writing, only MOZZI_MONO and MOZZI_STEREO are supported. The value of + * MOZZI_MONO is 1 and the value of MOZZI_STEREO is 2, so future extensions are also expected + * to set this to the number of available channels. */ +//#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO + + + +/** @ingroup core + * @def MOZZI_AUDIO_RATE + * + * @brief Defines the audio rate, i.e. rate of samples output per second. + * + * The default rate on the classis Arduino Uno is 16384 Hz, but can be increased to 32768 Hz, subject to the caveats, detailed below. For most other platforms 32678 Hz + * is the default, but even higher rates may be supported. + *. + * Increasing the rate allows for better frequency response, but generally all affects achievable sample bitdepth (especially from PWM output). + * Also, of course, doubling the sample rate also halves the amount of time available to calculate the each sample, so it + * may only be useful for relatively simple sketches. The increased frequency response can also make + * unwanted artefacts of low resolution synthesis calculations more apparent, so it's not always a bonus. + * + * It is highly recommended to keep the audio rate a power of two (16384, 32678, 64536, etc.), as some internal calculations can be highly be optimised for speed, this way. + * + * @note + * For compatibility reasons, the option AUDIO_RATE is automatically set to the same value as this option, and you will find some uses of that in old (pre Mozzi 2.0) code examples. + * It is advised to use only MOZZI_AUDIO_RATE in new code, however. + * TODO: Only do the above, if MozziGuts.h, rather than Mozzi.h was included? + */ +//#define MOZZI_AUDIO_RATE 32768 + + + +/** @ingroup core + * @def MOZZI_CONTROL_RATE + * + * @brief Control rate setting. + * + * Mozzi's MOZZI_CONTROL_RATE sets how many times per second updateControl() is called. + * MOZZI_CONTROL_RATE has a default of 64 Hz. It is useful to have MOZZI_CONTROL_RATE set at a power of 2 (such as 64,128,256 etc), + * to have exact timing of audio and control operations. Non-power-of-2 MOZZI_CONTROL_RATE can cause glitches due to audio and control + * events not lining up precisely. If this happens a power of two MOZZI_CONTROL_RATE might solve it. + * + * Try to keep MOZZI_CONTROL_RATE low, for efficiency, though higher rates up to about 1000 + * can sometimes give smoother results, avoiding the need to interpolate + * sensitive variables at audio rate in updateAudio(). + * + * TODO: If a definition of CONTROL_RATE is detected, apply that with a warning. +*/ +//#define MOZZI_CONTROL_RATE 256 + + +/** @ingroup core + * @def MOZZI_ANALOG_READ + * + * Whether to compile in support for non-blocking analog reads. This is enabled by default on platforms that support it, but may be + * disabled, explicitly, to save resources, or in order to implement custom read schemes (e.g. with IO multiplexing). + * + * For simplicity, mozziAnalogRead() is always defined, but when MOZZI_ANALOG_READ s are disabled or unsupported, it simply relays + * to Arduino's regular analogRead(). + * + * Currently allowed values are: + * - MOZZI_ANALOG_READ_NONE + * Disabled + * - MOZZI_ANALOG_READ_STANDARD + * Analog read implementation enabled (currently there is only the "standard" method, but future versions might allow additional choice, here). +*/ +//#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE + + +/** @ingroup core + * @def MOZZI_AUDIO_INPUT + * + * Whether to enable built in audio input feature. This is not supported on all platforms, and + * on platforms that do support it may come with a considerable performance overhead. Don't enable, unless you need this. + * + * Currently allowed values are: + * - MOZZI_AUDIO_INPUT_DISABLED + * No audio input + * - MOZZI_AUDIO_INPUT_STANDARD + * Audio input enabled (currently there is only the "standard" method, but future versions might allow additional choice, here). + * This mode implies that MOZZI_ANALOG_READ s are enabled and supported. You may have to call setupFastAnalogReads(FASTEST_ADC) + * after setupMozzi(), when using this. + * + * Further reading and config: @see getAudioInput() @see MOZZI_AUDIO_INPUT_PIN +*/ +//#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD + + + +/** @ingroup core + * @def MOZZI_AUDIO_INPUT_PIN + * + * This sets which analog input channel to use for audio input, if you have enabled MOZZI_AUDIO_INPUT, above. + * Not all pins may be available for this, be sure to check the documentation for your platform. +*/ +//#define MOZZI_AUDIO_INPUT_PIN 0 + + + + +/***************************************** ADVANCED SETTTINGS -- AVR *********************************************************** + * + * The settings in the following section applies to the AVR architecture (classic Arduino, and further 8bit ATMEGA based boards), + * only. + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + + +/** @ingroup hardware + * @page hardware_avr Mozzi on classic Arduino, Teensy (2.x and 3.x), Arduino Mega, and other 8 bit "AVR"/ATMEGA architecture boards + * + * The following audio modes (@see MOZZI_AUDIO_MODE) are currently supported on this hardware. In all cases, Timer 1 is claimed, and + * is not available for any other purpose: + * - MOZZI_OUTPUT_PWM + * - MOZZI_OUTPUT_2PIN_PWM + * - MOZZI_OUTPUT_EXTERNAL + * + * In all cases, Timer 1 is claimed, and is not available for any other purpose. + * + * @section MOZZI_OUTPUT_PWM + * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured + * within this tight limit. In particular, the default setup on the + * Arduino UNO is: + * - Mono: Pin 9 -> configurable using MOZZI_AUDIO_PIN_1 + * - Stereo: Pin 9 (left) and Pin 10 (right) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_2 + * For pinouts on other boards, refer to config/known_16bit_timers. + * + * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE: MOZZI_PWM_RATE. + * + * The available sample resolution is 488, i.e. almost 9 bits, providing some headroom above the 8 bit table resolution + * currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate. + * + * @section MOZZI_OUTPUT_2PIN_PWM + * For MOZZI_OUTPUT_2PIN_PWM, Timer 2 is used in addition to Timer 1. Output is split across two pins (again, both connected to Timer 1), with each + * outputting 7 bits for a total of 14. Add signals through a 3.9k resistor on the "high" pin and 499k resistor on "low" pin. + * Use 0.5% resistors or select the most accurate from a batch. As discussed on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ + * Also, there are higher quality output circuits are on the site. + * + * The default pinout in this mode is: + * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW + * For pinouts on other boards, refer to config/known_16bit_timers. + * + * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE, and is much higher (125kHz), by default: MOZZI_PWM_RATE. + * + * The default sample resolution is 7 bits per pin, for a total of 14 bits. This can be configured within hardware limits (@see MOZZI_PWM_RATE) using + * MOZZI_AUDIO_BITS_PER_CHANNEL, but beware that increasing this will require even more accuracy in our output resistors (see the linked documentation, above). + * + * @section MOZZI_OUTPUT_PWM + * @see AudioOutput +*/ + + +/** @ingroup core + * @def MOZZI_PWM_RATE + * + * Only for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_PWM and MOZZI_OUTPUT_2PIN_PWM. On some platforms, the rate at which PWM signals are repeated may be higher + * than that at with audio signals are produced (i.e. MOZZI_AUDIO_RATE). E.g. fro MOZZI_OUTPUT_PWM on the classic Arduino, the pwm defaults to 32768 while the audio rate defaults to 16384. + * + * This improves the signal quality at less cost than doubling the audio rate itself. However, increasing this too far will limit the dynamic resolution of the samples that can be + * writte to the output pin(s): 2 ^ (output bits) * MOZZI_PWM_RATE cannot be higher than the CPU frequency! +*/ + + + + + + + + + + +/// TODO: settings bits that still need to end up in their proper section, below + + + +/** @ingroup core + * @def MOZZI_AUDIO_BITS +Only used when EXTERNAL_AUDIO_OUTPUT is set to true: The resolution to use for audio samples, internally. You will usually set this to match the +output resolution of your DAC. 16 is the default value, here. Note that 16 bits is also the maximum currently supported on AVR. */ +//#define EXTERNAL_AUDIO_BITS 16 + + + diff --git a/MozziConfigValues.h b/MozziConfigValues.h new file mode 100644 index 000000000..fc47b96d3 --- /dev/null +++ b/MozziConfigValues.h @@ -0,0 +1,40 @@ +/** This file keeps a list of named configuration values. + +Note that these are all given as defines, instead of e.g. const ints or enum values, because they need to be usable at preprocessor level, in order to control conditional compilation. + +TODO: Fix documentation +*/ + +#ifndef MOZZICONFIG_VALUES_H +#define MOZZICONFIG_VALUES_H + + + +#define MOZZI_MONO 1 +#define MOZZI_STEREO 2 + +// We try to use distinct values as much as possible so we can catch semantic errors like "#define MOZZI_AUDIO_MODE MOZZI_STEREO" +#define MOZZI_OUTPUT_PWM 101 +#define MOZZI_OUTPUT_2PIN_PWM 102 +#define MOZZI_OUTPUT_EXTERNAL 103 +#define MOZZI_OUTPUT_PDM_VIA_I2S 104 +#define MOZZI_OUTPUT_PDM_VIA_SERIAL 105 +#define MOZZI_OUTPUT_I2S_DAC 106 +#define MOZZI_OUTPUT_INTERNAL_DAC 107 + +#define MOZZI_AUDIO_INPUT_DISABLED 201 +#define MOZZI_AUDIO_INPUT_STANDARD 202 + +#define MOZZI_ANALOG_READ_NONE 201 +#define MOZZI_ANALOG_READ_STANDARD 202 + +// defined with some space in between, just in case. This should be numerically ordered. +#define MOZZI_COMPATIBILITY_1_1 1100 +#define MOZZI_COMPATIBILITY_2_0 2000 +#define MOZZI_COMPATIBILITY_LATEST 9000 // May be upped, arbitrarily + +// For convenience +#include "hardware_defines.h" + + +#endif diff --git a/internal/Readme.md b/internal/Readme.md new file mode 100644 index 000000000..95448668c --- /dev/null +++ b/internal/Readme.md @@ -0,0 +1,4 @@ +# About this directory + +These files are part of the Mozzi project, but not meant for direct inclusion by the user. Functions and macros in here may be subject to change without notice. + diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h new file mode 100644 index 000000000..481f31be3 --- /dev/null +++ b/internal/config_check_generic.h @@ -0,0 +1,79 @@ +/** For Mozzi-internal use: Check configuration options for (some) invalid settings, and apply default for options that have not been set, so far. + * */ + +#ifndef MOZZI_CONFIG_CHECK_GENERIC_H +#define MOZZI_CONFIG_CHECK_GENERIC_H + + +//// Step 1: Apply missing defaults for generic config options (not hardware specific) +#if not defined(MOZZI_COMPATIBILITY_LEVEL) +#define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_2_0 +#endif + +#if not defined(MOZZI_AUDIO_CHANNELS) +#define MOZZI_MONO +#endif + +//MOZZI_AUDIO_MODE -> hardware specific +//MOZZI_AUDIO_RATE -> hardware specific + +#if not defined(MOZZI_CONTROL_RATE) +#define MOZZI_CONTROL_RATE 64 +#endif + +//MOZZI_ANALOG_READ -> hardware specific + +#if not defined(MOZZI_AUDIO_INPUT) +#define MOZZI_AUDIO_INPUT_DISABLED +#endif + +#if not defined(MOZZI_AUDIO_INPUT_PIN) +#define MOZZI_AUDIO_INPUT_PIN 0 +#endif + +//MOZZI_PWM_RATE -> hardware specific +//MOZZI_AUDIO_PIN_1 -> hardware specific +//MOZZI_AUDIO_PIN_1_LOW -> hardware specific +//MOZZI_AUDIO_PIN_2 -> hardware specific +//MOZZI_AUDIO_PIN_2_LOW -> hardware specific + + +/// Step 2: Include the hardware specific checks-and-defaults-header +#if IS_AVR() +#include "config_checks_avr.h" +#else +// TODO + +#endif + +/// Step 3: Apply various generic checks that make sense on more than one platform +MOZZI_CHECK_POW2(MOZZI_AUDIO_RATE) +MOZZI_CHECK_POW2(MOZZI_CONTROL_RATE) + +#if MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_STANDARD) && MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) +#error "MOZZI_AUDIO_INPUT depends on MOZZI_ANALOG_READ option" +#endif + +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && defined(MOZZI_AUDIO_INPUT_PIN) +#warning "MOZZI_AUDIO_INPUT_PIN defined without MOZZI_AUDIO_INPUT" +#endif + +#if (MOZZI_AUDIO_CHANNELS < MOZZI_MONO) || (MOZZI_AUDIO_CHANNELS > MOZZI_STEREO) +#error "MOZZI_AUDIO_CHANNELS outside of (currently) supported range" +#endif + +// Hardware-specific checks file should have more narrow checks for most options, below, but is not required to: +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL,MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC) +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) + + +// TODO: much more + + +/// Step 4: Patch up some backwards compatibility issues as far as config-related +#if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST +#define AUDIO_RATE MOZZI_AUDIO_RATE +#define CONTROL_RATE MOZZI_CONTROL_RATE +#endif + +#endif diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h new file mode 100644 index 000000000..639d3bc8c --- /dev/null +++ b/internal/config_checks_avr.h @@ -0,0 +1,24 @@ +/** For Mozzi-internal use: Apply hardware specific config defaults and config checks: AVR */ + +// Step 1: Apply missing defaults +// NOTE: This step is actually required for all ports + +#if not defined(MOZZI_AUDIO_MODE) +#define MOZZI_OUTPUT_PWM +#endif + +#if not defined(MOZZI_AUDIO_RATE) +#define 16384 +#endif + +#if not defined(MOZZI_ANALOG_READ) +#define MOZZI_ANALOG_READ MOZZI_ANALOG_READS_STANDARD +#endif + +/// TODO much more + +// Step 2: Check +// NOTE: This step is not technically required, but a good idea in any port + +// TODO much more + diff --git a/internal/mozzi_macros.h b/internal/mozzi_macros.h new file mode 100644 index 000000000..fdf4df4ea --- /dev/null +++ b/internal/mozzi_macros.h @@ -0,0 +1,34 @@ +/** This file contains some macros used internally inside Mozzi. These are not meant to be useful in user code. */ + +#ifndef MOZZI_MACROS_H +#define MOZZI_MACROS_H + + +// internal dummy that should be distinct from any valid config value +#define MOZZI__INVALID_CONFIG_VALUE 9999976543 + +// internal implementation of MOZZI_CHECK_SUPPORTED +#define MOZZI__CHECK_SUPPORTED(X, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, ...) \ + static_assert(X != MOZZI__INVALID_CONFIG_VALUE && \ + (X == A0 || X == A1 || X == A2 || X == A3 || X == A4 || X == A5 || X == A6 || X == A7 || X == A8 || X == A9 || \ + X == B0 || X == B1 || X == B2 || X == B3 || X == B4 || X == B5 || X == B6 || X == B7 || X == B8 || X == B9), "Compile time option " M " does not support value " #X " on this platform."); + +// MSVC needs this indirection for proper __VA_ARGS__ expansion. I case we ever need to support MSVC... +#define MOZZI__MACRO_EVAL(...) __VA_ARGS__ + +/// @file mozzi_internal_macros +/// compile time check whether the given first value (usually specified as a #define) is among the values specified in subsequent args (up to 20) +/// @example MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL) +#define MOZZI_CHECK_SUPPORTED(X, ...) MOZZI__MACRO_EVAL(MOZZI__CHECK_SUPPORTED(X, #X, __VA_ARGS__, \ + MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ + MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ + MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ + MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE)) + +/// Complain if the given argument is not a power of two +#define MOZZI_CHECK_POW_2(X) static_assert((X & (X - 1)) == 0, #X " must be a power of two"); + +/// Simply a way to check if X is Y, realiably, in case one or both are defined empty (such as because of a programmer's typo) +#define MOZZI_IS(X, Y) (X == Y) + +#endif From 819c3141a217578ddec92f1d25f22617a3fa95e8 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 13 Nov 2023 20:00:34 +0100 Subject: [PATCH 039/215] Finish "outline" for config options (generic, and AVR, only for now) --- AudioOutput.h | 2 + MozziConfigExample.h | 85 +++++++++++++++++++++++---------- MozziConfigValues.h | 11 +++-- internal/config_check_generic.h | 31 ++++++++++-- internal/config_checks_avr.h | 60 ++++++++++++++++++++++- 5 files changed, 153 insertions(+), 36 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index 8ad297844..329ae15cd 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -16,6 +16,7 @@ * 2. A platform-specific timer is triggered at audio rate (usually), takes a sample from the output buffer and sends it to audioOutput(). * * 3. The audioOutput() function - usually predefined inside Mozzi - takes care of sending the sample to the hardware. + * // TODO refer to @see external_audio for most of this, instead. * * This basic output pipeline can be customized in several ways. First, defining EXTERNAL_AUDIO_OUTPUT to true in mozzi_config.h will allow you to define your own audioOutput() * fuction. The library ships with some sample sketches for output to external DACs using this mechanism. @@ -46,6 +47,7 @@ #define AudioOutputStorage_t int #if IS_AVR() && ((AUDIO_MODE == STANDARD_PLUS) || (AUDIO_MODE == STANDARD)) +// TODO: remove this specialisation -> see MOZZI_AUDIO_BITS_OPTIMISTIC #define SCALE_AUDIO(x,bits) (bits > 8 ? (x) >> (bits - 8) : (x) << (8 - bits)) #define SCALE_AUDIO_NEAR(x,bits) (bits > 9 ? (x) >> (bits - 9) : (x) << (9 - bits)) #define CLIP_AUDIO(x) constrain((x), -244,243) diff --git a/MozziConfigExample.h b/MozziConfigExample.h index aef19bb55..ddd327c0c 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -20,6 +20,8 @@ * TODO: Fix and complete Doxygen coverage */ +#include // needed for the named option values + /** @ingroup core * @def MOZZI_COMPATIBILTY_LEVEL * @@ -48,16 +50,17 @@ * hardware setup is correct. Similarly, if you observe problems running your "real" sketch, it is often a good idea ot test your sketch with the default audio mode, * too (by leaving this option, and preferrably all others, unset). * - * TODO: link to specific documentation for each option/platform, and/or spell out, what is supported, where + * TODO: link to specific documentation for each option/platform, here, and/or spell out, what is supported, where * * Supported values: * - MOZZI_OUTPUT_PWM Output using pulse width modulation (PWM) on a GPIO pin. This is the default on most platforms. * On the Arduino Uno (more generally ATMEGA328P), this allows for a sample resolution of 488 (almost 9 bits) on pin 9. * Usable pins and resolution will be different on other boards. * - MOZZI_OUTPUT_2PIN_PWM Output using pulse width modulation on two GPIO pins, where one pin represents the lower bits, and the other the higer bits of the sample. - * On the Aduino Uno, this allows for 14 bits of resolution on pins 9 (low) and 10 (high). For further information (wiring etc.) see TODO add ref. - * - MOZZI_OUTPUT_EXTERNAL Output is not controlled by Mozzi itself, but left to the user sketch. This setting allows to completely customize the audio output, e.g. - * for connecting to external DACs. For more detail, @see AudioOuput + * On the Aduino Uno, this allows for 14 bits of resolution on pins 9 (low) and 10 (high). For further information (wiring etc.) see @ref hardware_avr_2pin. + * - MOZZI_OUTPUT_EXTERNAL_TIMED Output is not controlled by Mozzi itself, but left to the user sketch. This setting allows to completely customize the audio output, e.g. + * for connecting to external DACs. For more detail, see @ref external_audio + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM As above, but additionally bypassing Mozzi's sample buffer. For more detail, see @ref external_audio * - MOZZI_OUTPUT_PDM_VIA_I2S Output pulse density modulated (PDM) samples via a (hardware) I2S interface (without a DAC connected to it). * - MOZZI_OUTPUT_PDM_VIA_SERIAL Output pulse density modulated (PDM) samples via a hardware serial interface. * - MOZZI_OUTPUT_I2S_DAC Output samples to a PT8211 (or compatible) DAC connected to a hardware I2S interface. @@ -82,7 +85,7 @@ * * @note At the time of this writing, only MOZZI_MONO and MOZZI_STEREO are supported. The value of * MOZZI_MONO is 1 and the value of MOZZI_STEREO is 2, so future extensions are also expected - * to set this to the number of available channels. */ + * to set this to the number of available channels, and it's ok to use numerical comparison. */ //#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO @@ -162,7 +165,7 @@ * This mode implies that MOZZI_ANALOG_READ s are enabled and supported. You may have to call setupFastAnalogReads(FASTEST_ADC) * after setupMozzi(), when using this. * - * Further reading and config: @see getAudioInput() @see MOZZI_AUDIO_INPUT_PIN + * Further reading and config: @ref getAudioInput() @ref MOZZI_AUDIO_INPUT_PIN */ //#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD @@ -193,15 +196,16 @@ /** @ingroup hardware * @page hardware_avr Mozzi on classic Arduino, Teensy (2.x and 3.x), Arduino Mega, and other 8 bit "AVR"/ATMEGA architecture boards * - * The following audio modes (@see MOZZI_AUDIO_MODE) are currently supported on this hardware. In all cases, Timer 1 is claimed, and + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware. In all cases, Timer 1 is claimed, and * is not available for any other purpose: * - MOZZI_OUTPUT_PWM * - MOZZI_OUTPUT_2PIN_PWM - * - MOZZI_OUTPUT_EXTERNAL + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM * * In all cases, Timer 1 is claimed, and is not available for any other purpose. * - * @section MOZZI_OUTPUT_PWM + * @section avr_pwm MOZZI_OUTPUT_PWM * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured * within this tight limit. In particular, the default setup on the * Arduino UNO is: @@ -214,7 +218,7 @@ * The available sample resolution is 488, i.e. almost 9 bits, providing some headroom above the 8 bit table resolution * currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate. * - * @section MOZZI_OUTPUT_2PIN_PWM + * @section avr_2pin_pwm MOZZI_OUTPUT_2PIN_PWM * For MOZZI_OUTPUT_2PIN_PWM, Timer 2 is used in addition to Timer 1. Output is split across two pins (again, both connected to Timer 1), with each * outputting 7 bits for a total of 14. Add signals through a 3.9k resistor on the "high" pin and 499k resistor on "low" pin. * Use 0.5% resistors or select the most accurate from a batch. As discussed on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ @@ -226,11 +230,11 @@ * * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE, and is much higher (125kHz), by default: MOZZI_PWM_RATE. * - * The default sample resolution is 7 bits per pin, for a total of 14 bits. This can be configured within hardware limits (@see MOZZI_PWM_RATE) using + * The default sample resolution is 7 bits per pin, for a total of 14 bits. This can be configured within hardware limits (@ref MOZZI_PWM_RATE) using * MOZZI_AUDIO_BITS_PER_CHANNEL, but beware that increasing this will require even more accuracy in our output resistors (see the linked documentation, above). * - * @section MOZZI_OUTPUT_PWM - * @see AudioOutput + * @section avr_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio */ @@ -244,24 +248,57 @@ * writte to the output pin(s): 2 ^ (output bits) * MOZZI_PWM_RATE cannot be higher than the CPU frequency! */ +/** @ingroup core + * @def MOZZI_AUDIO_BITS_PER_CHANNEL + * + * Only for MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM. Sample resolution per channel to use in 2 pin output, given in bits (i.e. total resolution is twice as much). + * Defaults to 7 bits per channel. Note that increasing this requires very, very well matched output resistors. + * + * See @ref hardware_avr for a more detailed description. +*/ +/***************************************** ADVANCED SETTTINGS -- External audio output ****************************************** + * + * The settings in the following section applies to MOZZI_OUTPUT_EXTERNAL_TIMED, and MOZZI_OUTPUT_EXTERNAL_CUSTOM, only. + * +********************************************************************************************************************************/ - - - -/// TODO: settings bits that still need to end up in their proper section, below - +/** @ingroup hardware + * @page external_audio External audio output + * + * Only for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM. Most (all?) platforms support + * output using an "external" function. When using this option, you will need to provide a suitable definition for audioOutput() in + * your own sketch, yourself. Some understanding of the general Mozzi audio output architecture may be recommendable, when using this + * mode: See @ref AudioOutput . + * + * In the more simple case (MOZZI_OUPUT_EXTERNAL_TIMED), Mozzi will still take care of buffering the samples, and calling this function + * at audio rate (hence "timed"). This generally involves use of a timer, which should be detailed in the @ref hardware details for + * your platform. + * + * Should you desire even more control - perhaps because your board, or your external DAC already comes with a rate controlled DMA buffer - + * using MOZZI_OUPUT_EXTERNAL_CUSTOM also bypasses Mozzis sample buffer. In addition to audioOutput(), you will then need to provide + * a definition for canBufferAudioOutput(), which will control the rate at which samples are produced. In essence, whenever + * canBufferAudioOutput() returns true, Mozzi will call updateAudio(), and pass the produced sample to audioOutput(), unbuffered. It is + * entirely your job to make sure that this actually happens at MOZZI_AUDIO_RATE, and / or an appropriate buffer gets used. + * + * One additional configuration setting is MOZZI_AUDIO_BITS, which defaults to 16 bits for this mode, but might be set higher, if your + * hardware supports it. +*/ /** @ingroup core * @def MOZZI_AUDIO_BITS -Only used when EXTERNAL_AUDIO_OUTPUT is set to true: The resolution to use for audio samples, internally. You will usually set this to match the -output resolution of your DAC. 16 is the default value, here. Note that 16 bits is also the maximum currently supported on AVR. */ -//#define EXTERNAL_AUDIO_BITS 16 - - - + * + * Output resolution of audio samples. In most cases you should leave this value untouched (for the defaults that get applied, see @ref hardware . + * However, for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM you way wish to customize the default value + * of 16 bits. + * + * @note + * At the time of this writng single audio samples are stored as "int", unconditionally. This limits MOZZI_AUDIO_BITS to a maximumg of 16 bits on + * some 8 bit boards! + */ +//#define MOZZI_AUDIO_BITS 16 diff --git a/MozziConfigValues.h b/MozziConfigValues.h index fc47b96d3..06958ece6 100644 --- a/MozziConfigValues.h +++ b/MozziConfigValues.h @@ -16,11 +16,12 @@ TODO: Fix documentation // We try to use distinct values as much as possible so we can catch semantic errors like "#define MOZZI_AUDIO_MODE MOZZI_STEREO" #define MOZZI_OUTPUT_PWM 101 #define MOZZI_OUTPUT_2PIN_PWM 102 -#define MOZZI_OUTPUT_EXTERNAL 103 -#define MOZZI_OUTPUT_PDM_VIA_I2S 104 -#define MOZZI_OUTPUT_PDM_VIA_SERIAL 105 -#define MOZZI_OUTPUT_I2S_DAC 106 -#define MOZZI_OUTPUT_INTERNAL_DAC 107 +#define MOZZI_OUTPUT_EXTERNAL_TIMED 103 +#define MOZZI_OUTPUT_EXTERNAL_CUSTOM 104 +#define MOZZI_OUTPUT_PDM_VIA_I2S 105 +#define MOZZI_OUTPUT_PDM_VIA_SERIAL 106 +#define MOZZI_OUTPUT_I2S_DAC 107 +#define MOZZI_OUTPUT_INTERNAL_DAC 108 #define MOZZI_AUDIO_INPUT_DISABLED 201 #define MOZZI_AUDIO_INPUT_STANDARD 202 diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 481f31be3..cb520e5c3 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -4,8 +4,9 @@ #ifndef MOZZI_CONFIG_CHECK_GENERIC_H #define MOZZI_CONFIG_CHECK_GENERIC_H +#include // in case not user-included -//// Step 1: Apply missing defaults for generic config options (not hardware specific) +//// Step 1: Apply missing defaults for generic config options (not the hardware specific ones) #if not defined(MOZZI_COMPATIBILITY_LEVEL) #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_2_0 #endif @@ -38,6 +39,7 @@ //MOZZI_AUDIO_PIN_2_LOW -> hardware specific + /// Step 2: Include the hardware specific checks-and-defaults-header #if IS_AVR() #include "config_checks_avr.h" @@ -46,6 +48,14 @@ #endif + +/// Step 2b: Minimal special handling for MOZZI_OUTPUT_EXTERNAL +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL) && !defined(MOZZI_AUDIO_BITS) +#define MOZZI_AUDIO_BITS 16 +#endif + + + /// Step 3: Apply various generic checks that make sense on more than one platform MOZZI_CHECK_POW2(MOZZI_AUDIO_RATE) MOZZI_CHECK_POW2(MOZZI_CONTROL_RATE) @@ -62,15 +72,26 @@ MOZZI_CHECK_POW2(MOZZI_CONTROL_RATE) #error "MOZZI_AUDIO_CHANNELS outside of (currently) supported range" #endif -// Hardware-specific checks file should have more narrow checks for most options, below, but is not required to: -MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL,MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC) +// Hardware-specific checks file should have more narrow checks for most options, below, but is not required to, so let's check for anything that is wildly out of scope: +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC) MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) +static_assert(MOZZI_AUDIO_BITS <= (4*sizeof(AudioOutputStorage_t)), "Configured MOZZI_AUDIO_BITS is too large for the internal storage type"); + + + +/// Step 4: Init Read-only defines that depend on other values +#if !defined(MOZZI_AUDIO_BIAS) +#define MOZZI_AUDIO_BIAS ((uint16_t) 1<<(MOZZI_AUDIO_BITS-1)) +#endif + +#if !defined(MOZZI_AUDIO_BITS_OPTIMISTIC) +#define MOZZI_AUDIO_BITS_OPTIMISTIC MOZZI_AUDIO_BITS +#endif -// TODO: much more -/// Step 4: Patch up some backwards compatibility issues as far as config-related +/// Step 5: Patch up some backwards compatibility issues as far as config-related #if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST #define AUDIO_RATE MOZZI_AUDIO_RATE #define CONTROL_RATE MOZZI_CONTROL_RATE diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index 639d3bc8c..8372cca81 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -15,10 +15,66 @@ #define MOZZI_ANALOG_READ MOZZI_ANALOG_READS_STANDARD #endif -/// TODO much more +// Pins for regular PWM output +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) +# if !defined(MOZZI_AUDIO_PIN_1) +#define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN +# endif +# if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_2) +#define MOZZI_AUDIO_PIN_2 TIMER1_B_PIN +# endif + +# if !defined(MOZZI_PWM_RATE) +#define MOZZI_PWM_RATE 32768 +# endif + +#define MOZZI_AUDIO_BITS 8 +#define MOZZI_AUDIO_BITS_OPTIMISTIC 9 +#define MOZZI_AUDIO_BIAS ((uint8_t) 244) +#endif + +// Pins for 2 pin HIFI PWM output +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) +# if !defined(MOZZI_AUDIO_PIN_1) +#define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN +# endif +# if !defined(MOZZI_AUDIO_PIN_1) +#define MOZZI_AUDIO_PIN_1_LOW TIMER1_B_PIN +# endif + +# if !defined(MOZZI_PWM_RATE) +#define MOZZI_PWM_RATE 125000 +# endif + +# if !defined(MOZZI_PWM_RATE) +#define MOZZI_AUDIO_BITS_PER_CHANNEL 7 +# endif + +#define MOZZI_AUDIO_BITS (2*MOZZI_AUDIO_BITS_PER_CHANNEL) +#endif // Step 2: Check // NOTE: This step is not technically required, but a good idea in any port -// TODO much more +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) + +#if (MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO, MOZZI_STEREO) +#endif +#if (MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO) +#endif + +/** should we enforce the following? +#if (MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_RATE, 16384, 32768) +#endif */ + +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD) +#if defined(TIMER1_C_PIN) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN, TIMER1_C_PIN); +#else +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN); +#endif From 3c178651b6575ced3ad5d9032fda4a8d19283caa Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 13 Nov 2023 20:17:56 +0100 Subject: [PATCH 040/215] Start obsoleted files start adding porting table --- AudioConfigHiSpeed14bitPwm.h | 37 ------------ AudioConfigStandard9bitPwm.h | 25 -------- AudioConfigStandardPlus.h | 26 --------- Readme_Mozzi_2_0.md | 26 +++++++++ mozzi_config.h | 107 ----------------------------------- 5 files changed, 26 insertions(+), 195 deletions(-) delete mode 100644 AudioConfigHiSpeed14bitPwm.h delete mode 100644 AudioConfigStandard9bitPwm.h delete mode 100644 AudioConfigStandardPlus.h create mode 100644 Readme_Mozzi_2_0.md delete mode 100644 mozzi_config.h diff --git a/AudioConfigHiSpeed14bitPwm.h b/AudioConfigHiSpeed14bitPwm.h deleted file mode 100644 index 6123257b4..000000000 --- a/AudioConfigHiSpeed14bitPwm.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef AUDIOCONFIGHISPEED14BITPWM_H -#define AUDIOCONFIGHISPEED14BITPWM_H - -/* -14 bit sound at 16384 Hz and 125kHz pwm rate -Timer 1: PWM 125kHz -Timer 2: called at AUDIO_RATE 16384 Hz, setting Timer1 pwm levels -Output on Timer1, low uint8_t on Pin 10, and high uint8_t on Pin 9 (on 328 based Arduino boards) -Add signals through a 3.9k resistor on high uint8_t pin and 499k resistor on low uint8_t pin. -Use 0.5% resistors or select the most accurate from a batch. -As discussed on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ -Also, there are higher quality output circuits are on the site. - -Boards, pins and resistor positions are documented in MozziGuts.h -*/ - -/* PWM carrier frequency, for HIFI this should be well out of hearing range, about 5 times the nyquist frequency if possible. */ -#define PWM_RATE 125000 -// following doesn't play nice -//#define PWM_RATE 65536 // count will be 244 (7+ bits) on each pin = 14+ bits - - -// pins defined in TimerOne/config/known_16bit_timers.h -#define AUDIO_CHANNEL_1_highByte_PIN TIMER1_A_PIN // 3.9k resistor -#define AUDIO_CHANNEL_1_lowByte_PIN TIMER1_B_PIN // 499k resistor -#define AUDIO_CHANNEL_1_highByte_REGISTER OCR1AL -#define AUDIO_CHANNEL_1_lowByte_REGISTER OCR1BL - -#define AUDIO_BITS_PER_REGISTER 7 -#define AUDIO_BITS 14 - -/* Used internally to put the 0-biased generated audio into the right range for PWM output.*/ -// 14 bit -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) - - -#endif // #ifndef AUDIOCONFIGHISPEED14BITPWM_H diff --git a/AudioConfigStandard9bitPwm.h b/AudioConfigStandard9bitPwm.h deleted file mode 100644 index e7c9402c2..000000000 --- a/AudioConfigStandard9bitPwm.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef AUDIOCONFIGSTANDARD9BITPWM_H -#define AUDIOCONFIGSTANDARD9BITPWM_H - - -/** @ingroup core -This is the dynamic range of Mozzi's audio output in STANDARD mode. -It is equal to Timer1.pwmPeriod calculated for interrupt rate 16384. -It's included in the documentation because it's a slightly unusual number and useful to know -about when you're writing sketches. -*/ -#define STANDARD_PWM_RESOLUTION 488 - -/* PWM carrier frequency, for standard mode this will be the same as the audio rate. */ -#define PWM_RATE 16384 - -/* Used internally to put the 0-biased generated audio into the right range for PWM output.*/ -#define AUDIO_BIAS ((uint8_t) 244) - -// Used internally. If there was a channel 2, it would be OCR1B. -#define AUDIO_CHANNEL_1_OUTPUT_REGISTER OCR1A - -#define AUDIO_CHANNEL_1_PIN TIMER1_A_PIN // defined in TimerOne/config/known_16bit_timers.h - -#endif // #ifndef AUDIOCONFIGSTANDARD9BITPWM_H - diff --git a/AudioConfigStandardPlus.h b/AudioConfigStandardPlus.h deleted file mode 100644 index 0d0b3c27a..000000000 --- a/AudioConfigStandardPlus.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef AUDIOCONFIGSTANDARDPLUS_H -#define AUDIOCONFIGSTANDARDPLUS_H - - -/** @ingroup core -This is the dynamic range of Mozzi's audio output in STANDARD mode. -It is equal to Timer1.pwmPeriod calculated for interrupt rate 16384. -It's included in the documentation because it's a slightly unusual number and useful to know -about when you're writing sketches. -*/ -#define STANDARD_PWM_RESOLUTION 488 - -/* Used internally for standard mode because the audio gets updated every alternate ISR, so the PWM rate is double the audio update rate */ -#define PWM_RATE 32768 - -/* Used internally to put the 0-biased generated audio into the right range for PWM output.*/ -#define AUDIO_BIAS ((uint8_t) 244) - -// Used internally. If there was a channel 2, it would be OCR1B. -#define AUDIO_CHANNEL_1_OUTPUT_REGISTER OCR1A -#define AUDIO_CHANNEL_2_OUTPUT_REGISTER OCR1B - -#define AUDIO_CHANNEL_1_PIN TIMER1_A_PIN // defined in TimerOne/config/known_16bit_timers.h -#define AUDIO_CHANNEL_2_PIN TIMER1_B_PIN - -#endif // #ifndef AUDIOCONFIGSTANDARDPLUS_H diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md new file mode 100644 index 000000000..e052b66c7 --- /dev/null +++ b/Readme_Mozzi_2_0.md @@ -0,0 +1,26 @@ +Porting to Mozzi 2.0 + +// TODO: properly type up + + +changed config names and semantics TODO (incomplete) + +audio modes mapping + + - STANDARD: MOZZI_OUTPUT_PWM with PWM_RATE == AUDIO_RATE + - STANDARD_PLUS: MOZZI_OUTPUT_PWM with PWM_RATE == 32768 + - HIFI: MOZZI_OUTPUT_2PIN_PWM + - EXTERNAL_AUDIO_OUTPUT (without BYPASS_MOZZI_BUFFER): MOZZI_OUTPUT_EXTERNAL_TIMED + - EXTERNAL_AUDIO_OUTPUT (with BYPASS_MOZZI_BUFFER): MOZZI_OUTPUT_EXTERNAL_CUSTOM + +further + - USE_AUDIO_INPUT: MOZZI_AUDIO_INPUT + +simple renames: + - AUDIO_RATE: MOZZI_AUDIO_RATE + - CONTROL_RATE: MOZZI_CONTROL_RATE + +all new + - MOZZI_ANALOG_READS + - MOZZI_COMPATIBILITY_LEVEL + diff --git a/mozzi_config.h b/mozzi_config.h deleted file mode 100644 index 1f9d4dba1..000000000 --- a/mozzi_config.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef MOZZI_CONFIG_H -#define MOZZI_CONFIG_H -#include "hardware_defines.h" - -/* -Edit this file if you want to choose your own configuration options. -*/ - - -/** @ingroup core -AUDIO_MODE holds the audio mode setting. -Select STANDARD (deprecated), STANDARD_PLUS or HIFI audio output mode in the Mozzi/mozzi_config.h file with -\#define AUDIO_MODE STANDARD_PLUS or \#define AUDIO_MODE HIFI. -In Mozzi/config.h, comment one of these options in and the others out to set the audio mode. - -In STANDARD_PLUS mode the sample resolution is 488, -which provides some headroom above the 8 bit table resolution currently used by -the oscillators. You can look at utility/TimerOne library for more info about how -interrupt rate and pwm resolution relate. - -HIFI audio mode enables much higher quality output by combining signals from pins 9 and 10. -For HIFI mode, edit Mozzi/mozzi_config.h to contain \#define AUDIO_MODE HIFI, -and comment out \#define AUDIO_MODE STANDARD and \#define AUDIO_MODE STANDARD_PLUS. - -@note Teensy 3.* plays 12 bit audio in STANDARD or STANDARD_PLUS modes, and has no HIFI mode. -*/ -//#define AUDIO_MODE STANDARD -#define AUDIO_MODE STANDARD_PLUS -//#define AUDIO_MODE HIFI - - -/** @ingroup core -Holds the audio rate setting. -AUDIO_RATE can be \#defined as 16384 or 32768 Hertz in Mozzi/mozzi_config.h. - -Mozzi's original audio mode, now called STANDARD, uses 16384 Hz, chosen as a -compromise between the sample rate (interrupt rate) and sample bitdepth (pwm -width), which are interdependent due to the way pulse wave modulation is used to -generate the sound output. -An AUDIO_RATE of 32768 Hz works in STANDARD_PLUS and HIFI modes. -Of course, doubling the sample rate halves the amount of time available to calculate the each sample, so it -may only be useful for relatively simple sketches. The increased frequency response can also make -unwanted artefacts of low resolution synthesis calculations more apparent, so it's not always a bonus. - -Another factor which is important for Mozzi's operation is that with AUDIO_RATE -being a power of two, some internal calculations can be highly optimised for -speed. - -In STANDARD and STANDARD_PLUS modes, the sample resolution is 488, -which provides some headroom above the 8 bit table resolution currently used by -the oscillators. You can look at the TimerOne library for more info about how -interrupt rate and pwm resolution relate. - -HIFI audio mode enables much higher quality output by combining signals from pins 9 and 10. -For HIFI mode, edit Mozzi/mozzi_config.h to contain \#define AUDIO_MODE HIFI, -and comment out \#define AUDIO_MODE STANDARD and \#define AUDIO_MODE STANDARD_PLUS. - -@todo Possible option for output to R/2R DAC circuit, like -http://blog.makezine.com/2008/05/29/makeit-protodac-shield-fo/ . -Mozzi-users list has a thread on this. -*/ -#define AUDIO_RATE AUDIO_RATE_PLATFORM_DEFAULT -//#define AUDIO_RATE 16384 // default on AVR / classic Arduino -//#define AUDIO_RATE 32768 // default on most other platforms -//#define AUDIO_RATE 65536 // try on Teensy3/3.1 or other strong cpus - - -//#define USE_AUDIO_INPUT true - -/** @ingroup core -This sets which analog input channel to use for audio input, if you have uncommented -\#define USE_AUDIO_INPUT true -in mozz_config.h -@note You may have to call setupFastAnalogReads(FASTEST_ADC) after setupMozzi(), when using this. -*/ -#define AUDIO_INPUT_PIN 0 - - -/** @ingroup core -This sets allows to change from a single/mono audio output channel to -stereo output. To actually generate two channels, your updateAudio()-function -should return a StereoOutput(). Sketches returning a MonoOutput() in a stereo -config, or vice versa will continue to work, but will generate a warning a -compile time. - -@note This option superseeds the earlier STEREO_HACK, which is still available at - the time of this writing, but should not be used in new sketches. - -@note At the time of this writing, only MONO and STEREO are supported. The value of - MONO is 1 and the value of STEREO is 2, so future extensions are also expected - to set this to the number of available channels. */ -#define AUDIO_CHANNELS MONO -//#define AUDIO_CHANNELS STEREO - -/** @ingroup core -Defining this option as true in mozzi_config.h allows to completely customize the audio output, e.g. for connecting to external DACs. -For more detail, @see AudioOuput . -*/ -#define EXTERNAL_AUDIO_OUTPUT false -//#define EXTERNAL_AUDIO_OUTPUT true - -/** @ingroup core -Only used when EXTERNAL_AUDIO_OUTPUT is set to true: The resolution to use for audio samples, internally. You will usually set this to match the -output resolution of your DAC. 16 is the default value, here. Note that 16 bits is also the maximum currently supported on AVR. */ -//#define EXTERNAL_AUDIO_BITS 16 - -#endif // #ifndef MOZZI_CONFIG_H From b1c1e9df3f4eaa199bb6d428294966f386ad4872 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 13 Nov 2023 21:51:20 +0100 Subject: [PATCH 041/215] Start moving MozziGuts over the the new config. Commit known to be broken. The larger part of this is actually moving around / merging lots of (duplicated) information. --- MozziConfigExample.h | 46 +++++-- MozziGuts.h | 210 +++----------------------------- Readme_Mozzi_2_0.md | 15 +++ internal/config_check_generic.h | 25 +++- 4 files changed, 91 insertions(+), 205 deletions(-) diff --git a/MozziConfigExample.h b/MozziConfigExample.h index ddd327c0c..038188985 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -219,14 +219,41 @@ * currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate. * * @section avr_2pin_pwm MOZZI_OUTPUT_2PIN_PWM - * For MOZZI_OUTPUT_2PIN_PWM, Timer 2 is used in addition to Timer 1. Output is split across two pins (again, both connected to Timer 1), with each - * outputting 7 bits for a total of 14. Add signals through a 3.9k resistor on the "high" pin and 499k resistor on "low" pin. - * Use 0.5% resistors or select the most accurate from a batch. As discussed on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ + * In this mode, output is split across two pins (again, both connected to Timer 1), with each outputting 7 bits for a total of 14. This allows for + * much better dynamic range, providing much more definition than can be achieved using @ref avr_pwm , while using + * only modestly more processing power. Further, it allows for a much higher PWM carrier rate can be much higher (125 kHz by default; see @ref + * MOZZI_PWM_RATE), which is well beyond the audible range. + * + * On the downside, this mode requires an extra hardware timer (Timer2 in addition to Timer1), which may increase compatibility + * problems with other Arduino libraries that also require a timer. Further, a more elaborate hardware setup is needed, making it less convenient + * for rapid prototyping: + * + * In hardware, add the two signals through a 3.9k resistor on the "high" pin and 499k resistor on "low" pin. + * Use 0.5% resistors or select the most accurate from a batch. It is further recommended to place a 4.7nF capacitor between the summing junction + * of the resistors and ground. This is discussed in much more detail on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ * Also, there are higher quality output circuits are on the site. * - * The default pinout in this mode is: + * On the classic Arduino Uno, the default pinout in this mode is: * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW - * For pinouts on other boards, refer to config/known_16bit_timers. + * + * Here is table of the default pins on some other boards. Rows with an x on it have actually been tested (and importantly, the outcome recoreded; + * input welcome on further boards.) + * + * resistor.....3.9k......499k \n + * x................9..........10...............Arduino Uno \n + * x................9..........10...............Arduino Duemilanove \n + * x................9..........10...............Arduino Nano \n + * x................9..........10...............Arduino Leonardo \n + * x................9..........10...............Ardweeny \n + * x................9..........10...............Boarduino \n + * x...............11.........12...............Freetronics EtherMega \n + * .................11.........12...............Arduino Mega \n + * .................14.........15...............Teensy \n + * .............B5(14)...B6(15)...........Teensy2 \n + * x...........B5(25)...B6(26)...........Teensy2++ \n + * .................13.........12...............Sanguino \n + * + * For pinouts on other AVR boards, config/known_16bit_timers might contain some hints. * * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE, and is much higher (125kHz), by default: MOZZI_PWM_RATE. * @@ -242,10 +269,13 @@ * @def MOZZI_PWM_RATE * * Only for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_PWM and MOZZI_OUTPUT_2PIN_PWM. On some platforms, the rate at which PWM signals are repeated may be higher - * than that at with audio signals are produced (i.e. MOZZI_AUDIO_RATE). E.g. fro MOZZI_OUTPUT_PWM on the classic Arduino, the pwm defaults to 32768 while the audio rate defaults to 16384. + * than that at with audio signals are produced (i.e. MOZZI_AUDIO_RATE). E.g. for MOZZI_OUTPUT_PWM on the classic Arduino, the pwm defaults to 32768 while the + * audio rate defaults to 16384. The reasoning behind this is that 16384 Hz audio rate turned out to be te most useful compromise - in most casses - between + * output quality, and available computing power. However, output at that rate produced high-frequency whine, audible to some people, which could be mitigated + * by the higher PWM rate. * - * This improves the signal quality at less cost than doubling the audio rate itself. However, increasing this too far will limit the dynamic resolution of the samples that can be - * writte to the output pin(s): 2 ^ (output bits) * MOZZI_PWM_RATE cannot be higher than the CPU frequency! + * In other words, increasing this improves the signal quality at less cost than doubling the audio rate itself. However, increasing this too far will limit the dynamic resolution of the samples that can be + * written to the output pin(s): 2 ^ (output bits) * MOZZI_PWM_RATE cannot be higher than the CPU frequency! */ /** @ingroup core diff --git a/MozziGuts.h b/MozziGuts.h index f3dad8a46..3007c2088 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -29,175 +29,9 @@ #include "mozzi_analog.h" -#if not defined (CONTROL_RATE) -/** @ingroup core -Control rate setting. -Mozzi's CONTROL_RATE sets how many times per second updateControl() is called. -CONTROL_RATE has a default of 64 Hz, but it can be changed at the top of your sketch, -(before the \#includes), for example: \#define CONTROL_RATE 256. -It is useful to have CONTROL_RATE set at a power of 2 (such as 64,128,256 etc), -to have exact timing of audio and control operations. -Non-power-of-2 CONTROL_RATE can cause glitches due to audio and control -events not lining up precisely. If this happens a power of two CONTROL_RATE might solve it. -Try to keep CONTROL_RATE low, for efficiency, though higher rates up to about 1000 -can sometimes give smoother results, avoiding the need to interpolate -sensitive variables at audio rate in updateAudio(). -*/ -#define CONTROL_RATE 64 -#endif - - - -/** @ingroup core -Used to set AUDIO_MODE to STANDARD, STANDARD_PLUS, or HIFI. - -STANDARD / STANDARD_PLUS ---------------- -Use \#define AUDIO_MODE STANDARD_PLUS in Mozzi/config.h to select this -output configuration, which is nearly 9 bit sound (-244 to 243) at 16384 Hz sample rate (AUDIO_RATE) and -32768 Hz PWM rate. It uses Timer 1 for PWM and the sample updating routine (as an interrupt). - -STANDARD is obsolete now, replaced by STANDARD_PLUS which is the default audio mode. -STANDARD mode uses 16384 Hz PWM rate with an output interrupt at the same frequency. -Some people can hear the PWM carrier frequency as an annoying whine. - -STANDARD_PLUS mode uses 32768 Hz PWM rate, so the PWM carrier is out of hearing range. -In this mode every alternate interrupt is used for the sample update (unless you /#define AUDIO_RATE 32768 in mozzi_config.h), -which makes it slightly less efficient than STANDARD, but almost always better. - -Advantages: Only uses one timer for audio, and one output pin. -Disadvantages: low dynamic range. - -Below is a list of the Digital Pins used by Mozzi for STANDARD and STANDARD_PLUS audio out on different boards. -Those which have been tested and reported to work have an x. -Feedback about others is welcome. - -Model | Pin | Tested ------ | --- | ------ -Arduino Uno | 9 | yes -Arduino Duemilanove | 9 | yes -Arduino Nano | 9 | yes -Arduino Pro Mini | 9 | yes -Arduino Leonardo | 9 | yes -Arduino Mega | 11 | yes -Freetronics EtherMega | 11 | yes -Ardweeny | 9 | yes -Boarduino | 9 | yes -Teensy | 14 | - -Teensy2 | B5 | yes -Teensy2++ | B5(25) | yes -Teensy 3.0 3.1 LC 3.2 | DAC/D | yes -Teensy 3.4, 3.5 | DAC/D | - -Teensy 4.0 4.1 | A8 | yes -Gemma M0 | A0 | yes -Adafruit Playground Express | Built in Speaker | yes -Sanguino | 13 | - -STM32duino (see "Hardware specific notes", below) | PB8 | yes -ESP8266 *see details in README* | GPIO2 | yes -RP2040 | 0 | yes - - -On Teensy 3.* STANDARD and STANDARD_PLUS are the same, providing 16384Hz sample rate and 12 bit resolution on pin A14/ADC. -The Teensy 3.* DAC output does not rely on PWM. - - -@ingroup core - -Used to set AUDIO_MODE to HIFI. - -HIFI for AVR and STM32 (not for Teensy 3.*) ----- -Use \#define AUDIO_MODE HIFI in Mozzi/config.h to set the audio mode to HIFI for output 14 bit sound at 16384 Hz sample rate and 125kHz PWM rate. -The high PWM rate of HIFI mode places the carrier frequency beyond audible range. - -Also, 14 bits of dynamic range in HIFI mode provides more definition than the nearly 9 bits in STANDARD_PLUS mode. -HIFI mode takes about the same amount of processing time as STANDARD_PLUS mode, and should sound clearer and brighter. -However, it requires an extra timer to be used on the Arduino, which could increase the chances of -conflicts with other libraries or processes if they rely on Timer 2. - -Timer 1 is used to provide the PWM output at 125kHz. -Timer 2 generates an interrupt at AUDIO_RATE 16384 Hz, which sets the Timer1 PWM levels. -HIFI mode uses 2 output pins, and sums their outputs with resistors, so is slightly less convenient for -rapid prototyping where you could listen to STANDARD_PLUS mode by connecting the single output pin -directly to a speaker or audio input (though a resistor of about 100 ohms is recommended). - -The resistors needed for HIFI output are 3.9k and 499k, with 0.5% or better tolerance. -If you can only get 1% resistors, use a multimeter to find the most accurate. -Use two 1M resistors in parallel if you can't find 499k. - -On 328 based Arduino boards, output is on Timer1, with the high byte on Pin 9 and low byte on Pin 10. -Add the signals through a 3.9k resistor on high byte pin (9) and 499k resistor on low byte pin (10). -Also, a 4.7nF capacitor is recommended between the summing junction of the resistors and ground. - -This dual PWM technique is discussed on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ -Also, there are higher quality output circuits are on the site. - -Advantages: should be higher quality sound than STANDARD_PLUS mode. Doesn't need a notch filter on -the audio signal (like STANDARD which is now obsolete) because the carrier frequency is out of hearing range. - -Disadvantages: requires 2 pins, 2 resistors and a capacitor, so it's not so quick to set up compared -to a rough, direct single-pin output in STANDARD_PLUS mode. - -Pins and where to put the resistors on various boards for HIFI mode. -Boards tested in HIFI mode have an x, though most of these have been tested in STANDARD_PLUS mode -and there's no reason for them not to work in HIFI (unless the pin number is wrong or something). -Any reports are welcome. \n - -resistor.....3.9k......499k \n -x................9..........10...............Arduino Uno \n -x................9..........10...............Arduino Duemilanove \n -x................9..........10...............Arduino Nano \n -x................9..........10...............Arduino Leonardo \n -x................9..........10...............Ardweeny \n -x................9..........10...............Boarduino \n -x...............11.........12...............Freetronics EtherMega \n -.................11.........12...............Arduino Mega \n -.................14.........15...............Teensy \n -.............B5(14)...B6(15)...........Teensy2 \n -x...........B5(25)...B6(26)...........Teensy2++ \n -.................13.........12...............Sanguino \n - -HIFI is not available/not required on Teensy 3.* or ARM. -*/ -//enum audio_modes {STANDARD,STANDARD_PLUS,HIFI}; -#define STANDARD 0 -#define STANDARD_PLUS 1 -#define HIFI 2 - -//enum audio_channels {MONO,STEREO,...}; -#define MONO 1 -#define STEREO 2 - -#include "mozzi_config.h" // User can change the config file to set audio mode - -#if (AUDIO_MODE == STANDARD) && (AUDIO_RATE == 32768) -#error AUDIO_RATE 32768 does not work when AUDIO_MODE is STANDARD, try setting the AUDIO_MODE to STANDARD_PLUS in Mozzi/mozzi_config.h -#endif - -#if (STEREO_HACK == true) -#warning Use of STEREO_HACK is deprecated. Use AUDIO_CHANNELS STEREO, instead. -#define AUDIO_CHANNELS STEREO -#endif -#if !defined(AUDIO_CHANNELS) -#define AUDIO_CHANNELS MONO -#endif +#include "internal/config_check_generic.h" -#define CLOCK_TICKS_PER_AUDIO_TICK (F_CPU / AUDIO_RATE) - - -#if AUDIO_RATE == 16384 -#define AUDIO_RATE_AS_LSHIFT 14 -#define MICROS_PER_AUDIO_TICK 61 // 1000000 / 16384 = 61.035, ...* 256 = 15625 -#elif AUDIO_RATE == 32768 -#define AUDIO_RATE_AS_LSHIFT 15 -#define MICROS_PER_AUDIO_TICK 31 // = 1000000 / 32768 = 30.518, ...* 256 = 7812.6 -#endif - -// for compatibility with old (local) versions of mozzi_config.h -#if !defined(EXTERNAL_AUDIO_OUTPUT) -#define EXTERNAL_AUDIO_OUTPUT false -#endif #if (EXTERNAL_AUDIO_OUTPUT != true) #if IS_TEENSY3() @@ -241,6 +75,7 @@ extern int audio_out_1, audio_out_2; #include "AudioOutput.h" +// TODO Mozzi 2.0: These typedef probably obsolete? // common numeric types typedef unsigned char uchar; typedef unsigned int uint; @@ -264,16 +99,8 @@ Sets up the timers for audio and control rate processes, storing the timer registers so they can be restored when Mozzi stops. startMozzi() goes in your sketch's setup() routine. -Contrary to earlier versions of Mozzi, this version does not take over Timer 0, and thus Arduino -functions delay(), millis(), micros() and delayMicroseconds() remain usable in theory. That said, -you should avoid these functions, as they are slow (or even blocking). For measuring time, refer -to mozziMircos(). For delaying events, you can use Mozzi's EventDelay() unit instead -(not to be confused with AudioDelay()). - -In STANDARD mode, startMozzi() starts Timer 1 for PWM output and audio output interrupts, -and in STANDARD_PLUS and HIFI modes, Mozzi uses Timer 1 for PWM and Timer2 for audio interrupts. - -The audio rate defaults to 16384 Hz, but you can experiment with 32768 Hz by changing AUDIO_RATE in mozzi_config.h. +This function intializes the timer(s) needed to move audio samples to the output according to the +configured @ref MOZZI_AUDIO_MODE . @param control_rate_hz Sets how often updateControl() is called. It must be a power of 2. If no parameter is provided, control_rate_hz is set to CONTROL_RATE, @@ -303,22 +130,12 @@ reading sensors. As it is, stopMozzi restores all the Timers used by Mozzi to their previous settings. Another scenario which could be easily hacked in MozziGuts.cpp could involve individually saving and restoring particular Timer registers depending -on which one(s) are required for other tasks. */ -void stopMozzi(); +on which one(s) are required for other tasks. - -/** @ingroup core -Obsolete function, use stopMozzi() instead. +@note This function is not actually implemented on all platforms. */ -void pauseMozzi(); +void stopMozzi(); -//TB2017-19 -/** @ingroup core -Obsolete function, use startMozzi() instead. -Restores Mozzi audio and control interrupts, if they have been temporarily -disabled with pauseMozzi(). -*/ -void unPauseMozzi(); /** @ingroup core @@ -327,6 +144,8 @@ AUDIO_RATE of 16384 Hz, so to keep things running smoothly, avoid doing any calculations here which could be done in setup() or updateControl(). @return an audio sample. In STANDARD modes this is between -244 and 243 inclusive. In HIFI mode, it's a 14 bit number between -16384 and 16383 inclusive. + +TODO: Update documentation */ AudioOutput_t updateAudio(); @@ -342,7 +161,7 @@ void updateControl(); /** @ingroup core This is required in Arduino's loop(). If there is room in Mozzi's output buffer, audioHook() calls updateAudio() once and puts the result into the output -buffer. Also, if \#define USE_AUDIO_INPUT true is in Mozzi/mozzi_config.h, +buffer. Also, if \@ref MOZZI_AUDIO_INPUT is enabled in the config, audioHook() takes care of moving audio input from the input buffer so it can be accessed with getAudioInput() in your updateAudio() routine. If other functions are called in loop() along with audioHook(), see if @@ -358,10 +177,9 @@ void audioHook(); /** @ingroup analog This returns audio input from the input buffer, if -\#define USE_AUDIO_INPUT true is in the Mozzi/mozzi_config.h file. -The pin used for audio input is set in Mozzi/mozzi_config.h with -\#define AUDIO_INPUT_PIN 0 (or other analog input pin). -The audio signal needs to be in the range 0 to 5 volts. +\@ref MOZZI_AUDIO_INPUT is enabled in the config (see also the related option MOZZI_AUDIO_INPUT_PIN). + +The audio signal needs to be in the range 0 to VCC volts (i.e. 5 volts on Arduino Uno R3). Circuits and discussions about biasing a signal in the middle of this range can be found at http://electronics.stackexchange.com/questions/14404/dc-biasing-audio-signal @@ -371,7 +189,7 @@ A circuit and instructions for amplifying and biasing a microphone signal can be http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS @return audio data from the input buffer */ -#if (USE_AUDIO_INPUT == true) +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) int getAudioInput(); #endif diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index e052b66c7..9a8fbbaaf 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -24,3 +24,18 @@ all new - MOZZI_ANALOG_READS - MOZZI_COMPATIBILITY_LEVEL + + + Other removed stuff: + - pauseMozzi() - was still declared but not defined -> not usable, anyway + - unpauseMozzi() - was still declared but not defined -> not usable, anyway + + + +Documentation bits that still need to find a new home (many other bits were moved around, many, many duplicates merged into a common place, and seom obsoleted bits discarded): + +Contrary to earlier versions of Mozzi, this version does not take over Timer 0, and thus Arduino +functions delay(), millis(), micros() and delayMicroseconds() remain usable in theory. That said, +you should avoid these functions, as they are slow (or even blocking). For measuring time, refer +to mozziMircos(). For delaying events, you can use Mozzi's EventDelay() unit instead +(not to be confused with AudioDelay()). diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index cb520e5c3..8c6f87160 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -12,8 +12,13 @@ #endif #if not defined(MOZZI_AUDIO_CHANNELS) +#if (MOZZI_COMPATIBILITY_LEVEL <= MOZZI_COMPATIBILITY_1_1) && (STEREO_HACK == true) +#warning Use of STEREO_HACK is deprecated. Use AUDIO_CHANNELS STEREO, instead. +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO +#else #define MOZZI_MONO #endif +#endif //MOZZI_AUDIO_MODE -> hardware specific //MOZZI_AUDIO_RATE -> hardware specific @@ -88,7 +93,22 @@ static_assert(MOZZI_AUDIO_BITS <= (4*sizeof(AudioOutputStorage_t)), "Configured #define MOZZI_AUDIO_BITS_OPTIMISTIC MOZZI_AUDIO_BITS #endif - +// TODO: Rename these defines +#if MOZZI_AUDIO_RATE == 8192 +#define AUDIO_RATE_AS_LSHIFT 13 +#define MICROS_PER_AUDIO_TICK 122 +#if MOZZI_AUDIO_RATE == 16384 +#define AUDIO_RATE_AS_LSHIFT 14 +#define MICROS_PER_AUDIO_TICK 61 // 1000000 / 16384 = 61.035, ...* 256 = 15625 +#elif MOZZI_AUDIO_RATE == 32768 +#define AUDIO_RATE_AS_LSHIFT 15 +#define MICROS_PER_AUDIO_TICK 31 // = 1000000 / 32768 = 30.518, ...* 256 = 7812.6 +#elif MOZZI_AUDIO_RATE == 65336 +#define AUDIO_RATE_AS_LSHIFT 16 +#define MICROS_PER_AUDIO_TICK 15 +#else +#error Whoopsie, not LSHIFT defined for this audio rate. Please report and/or fix +#endif /// Step 5: Patch up some backwards compatibility issues as far as config-related @@ -97,4 +117,7 @@ static_assert(MOZZI_AUDIO_BITS <= (4*sizeof(AudioOutputStorage_t)), "Configured #define CONTROL_RATE MOZZI_CONTROL_RATE #endif + + + #endif From f5c9e92ba671de7b77d6d05670eb4e0b558f8edb Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 13 Nov 2023 22:31:42 +0100 Subject: [PATCH 042/215] Fix a first round of bugs --- AudioOutput.h | 2 +- MozziConfigExample.h | 4 ++-- MozziConfigValues.h | 2 +- MozziGuts.cpp | 1 - MozziGuts.h | 6 ------ MozziGuts_impl_AVR.hpp | 5 ----- internal/config_check_generic.h | 24 ++++++++++++------------ internal/config_checks_avr.h | 11 ++++++----- internal/mozzi_macros.h | 2 +- mozzi_analog.cpp | 1 - 10 files changed, 23 insertions(+), 35 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index 329ae15cd..f958f09fa 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -93,7 +93,7 @@ struct StereoOutput { StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r) : _l(l), _r(r) {}; /** Default contstructor */ StereoOutput() : _l(0), _r(0) {}; -#if (AUDIO_CHANNELS != STEREO) +#if (MOZZI_AUDIO_CHANNELS != MOZZI_STEREO) /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning). This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 038188985..7da4651b2 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -158,7 +158,7 @@ * on platforms that do support it may come with a considerable performance overhead. Don't enable, unless you need this. * * Currently allowed values are: - * - MOZZI_AUDIO_INPUT_DISABLED + * - MOZZI_AUDIO_INPUT_NONE * No audio input * - MOZZI_AUDIO_INPUT_STANDARD * Audio input enabled (currently there is only the "standard" method, but future versions might allow additional choice, here). @@ -233,7 +233,7 @@ * of the resistors and ground. This is discussed in much more detail on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ * Also, there are higher quality output circuits are on the site. * - * On the classic Arduino Uno, the default pinout in this mode is: + * On the classic Arduino Uno, the default pinout in this mode is: * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW * * Here is table of the default pins on some other boards. Rows with an x on it have actually been tested (and importantly, the outcome recoreded; diff --git a/MozziConfigValues.h b/MozziConfigValues.h index 06958ece6..d311ad1ad 100644 --- a/MozziConfigValues.h +++ b/MozziConfigValues.h @@ -23,7 +23,7 @@ TODO: Fix documentation #define MOZZI_OUTPUT_I2S_DAC 107 #define MOZZI_OUTPUT_INTERNAL_DAC 108 -#define MOZZI_AUDIO_INPUT_DISABLED 201 +#define MOZZI_AUDIO_INPUT_NONE 201 #define MOZZI_AUDIO_INPUT_STANDARD 202 #define MOZZI_ANALOG_READ_NONE 201 diff --git a/MozziGuts.cpp b/MozziGuts.cpp index b6aad9dda..139de506a 100644 --- a/MozziGuts.cpp +++ b/MozziGuts.cpp @@ -14,7 +14,6 @@ #include "CircularBuffer.h" #include "MozziGuts.h" #include "mozzi_analog.h" -#include "mozzi_config.h" // at the top of all MozziGuts and analog files //#include "mozzi_utils.h" #include "AudioOutput.h" diff --git a/MozziGuts.h b/MozziGuts.h index 3007c2088..a178cd5d1 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -52,12 +52,6 @@ #include "AudioConfigRP2040.h" #elif IS_MBED() #include "AudioConfigMBED.h" -#elif IS_AVR() && (AUDIO_MODE == STANDARD) -#include "AudioConfigStandard9bitPwm.h" -#elif IS_AVR() && (AUDIO_MODE == STANDARD_PLUS) -#include "AudioConfigStandardPlus.h" -#elif IS_AVR() && (AUDIO_MODE == HIFI) -#include "AudioConfigHiSpeed14bitPwm.h" #elif IS_RENESAS() #include "AudioConfigRenesas.h" #endif diff --git a/MozziGuts_impl_AVR.hpp b/MozziGuts_impl_AVR.hpp index dd0f474dc..8e2bf0c50 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/MozziGuts_impl_AVR.hpp @@ -182,11 +182,6 @@ ISR(TIMER1_OVF_vect, ISR_BLOCK) { defaultAudioOutput(); } #elif (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS) -# if (AUDIO_MODE == STANDARD_PLUS) -# include "AudioConfigStandardPlus.h" -# else -# include "AudioConfigStandard9bitPwm.h" -# endif inline void audioOutput(const AudioOutput f) { AUDIO_CHANNEL_1_OUTPUT_REGISTER = f.l()+AUDIO_BIAS; diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 8c6f87160..2650b79b6 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -4,7 +4,8 @@ #ifndef MOZZI_CONFIG_CHECK_GENERIC_H #define MOZZI_CONFIG_CHECK_GENERIC_H -#include // in case not user-included +#include "../MozziConfigValues.h" // in case not user-included +#include "mozzi_macros.h" //// Step 1: Apply missing defaults for generic config options (not the hardware specific ones) #if not defined(MOZZI_COMPATIBILITY_LEVEL) @@ -16,7 +17,7 @@ #warning Use of STEREO_HACK is deprecated. Use AUDIO_CHANNELS STEREO, instead. #define MOZZI_AUDIO_CHANNELS MOZZI_STEREO #else -#define MOZZI_MONO +#define MOZZI_AUDIO_CHANNELS MOZZI_MONO #endif #endif @@ -30,10 +31,10 @@ //MOZZI_ANALOG_READ -> hardware specific #if not defined(MOZZI_AUDIO_INPUT) -#define MOZZI_AUDIO_INPUT_DISABLED +#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_NONE #endif -#if not defined(MOZZI_AUDIO_INPUT_PIN) +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && !defined(MOZZI_AUDIO_INPUT_PIN) #define MOZZI_AUDIO_INPUT_PIN 0 #endif @@ -50,7 +51,7 @@ #include "config_checks_avr.h" #else // TODO - +#error oops #endif @@ -80,9 +81,6 @@ MOZZI_CHECK_POW2(MOZZI_CONTROL_RATE) // Hardware-specific checks file should have more narrow checks for most options, below, but is not required to, so let's check for anything that is wildly out of scope: MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC) MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) -static_assert(MOZZI_AUDIO_BITS <= (4*sizeof(AudioOutputStorage_t)), "Configured MOZZI_AUDIO_BITS is too large for the internal storage type"); - - /// Step 4: Init Read-only defines that depend on other values #if !defined(MOZZI_AUDIO_BIAS) @@ -97,7 +95,7 @@ static_assert(MOZZI_AUDIO_BITS <= (4*sizeof(AudioOutputStorage_t)), "Configured #if MOZZI_AUDIO_RATE == 8192 #define AUDIO_RATE_AS_LSHIFT 13 #define MICROS_PER_AUDIO_TICK 122 -#if MOZZI_AUDIO_RATE == 16384 +#elif MOZZI_AUDIO_RATE == 16384 #define AUDIO_RATE_AS_LSHIFT 14 #define MICROS_PER_AUDIO_TICK 61 // 1000000 / 16384 = 61.035, ...* 256 = 15625 #elif MOZZI_AUDIO_RATE == 32768 @@ -107,7 +105,7 @@ static_assert(MOZZI_AUDIO_BITS <= (4*sizeof(AudioOutputStorage_t)), "Configured #define AUDIO_RATE_AS_LSHIFT 16 #define MICROS_PER_AUDIO_TICK 15 #else -#error Whoopsie, not LSHIFT defined for this audio rate. Please report and/or fix +//#error Whoopsie, not LSHIFT defined for this audio rate. Please report and/or fix #endif @@ -117,7 +115,9 @@ static_assert(MOZZI_AUDIO_BITS <= (4*sizeof(AudioOutputStorage_t)), "Configured #define CONTROL_RATE MOZZI_CONTROL_RATE #endif - - +/// Step 6: Some more checks that need to be at the end, because of requiring end of the foodchain headers +// TODO: Rather move this up again, and make AudioOutputStorage_t a primary config option +#include "../AudioOutput.h" +static_assert(MOZZI_AUDIO_BITS <= (8*sizeof(AudioOutputStorage_t)), "Configured MOZZI_AUDIO_BITS is too large for the internal storage type"); #endif diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index 8372cca81..5084f84a8 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -4,15 +4,15 @@ // NOTE: This step is actually required for all ports #if not defined(MOZZI_AUDIO_MODE) -#define MOZZI_OUTPUT_PWM +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM #endif #if not defined(MOZZI_AUDIO_RATE) -#define 16384 +#define MOZZI_AUDIO_RATE 16384 #endif #if not defined(MOZZI_ANALOG_READ) -#define MOZZI_ANALOG_READ MOZZI_ANALOG_READS_STANDARD +#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD #endif // Pins for regular PWM output @@ -58,10 +58,10 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) -#if (MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO, MOZZI_STEREO) #endif -#if (MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO) #endif @@ -72,6 +72,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_RATE, 16384, 32768) MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD) +#include "../config/known_16bit_timers.h" #if defined(TIMER1_C_PIN) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN, TIMER1_C_PIN); #else diff --git a/internal/mozzi_macros.h b/internal/mozzi_macros.h index fdf4df4ea..ea692a3d0 100644 --- a/internal/mozzi_macros.h +++ b/internal/mozzi_macros.h @@ -26,7 +26,7 @@ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE)) /// Complain if the given argument is not a power of two -#define MOZZI_CHECK_POW_2(X) static_assert((X & (X - 1)) == 0, #X " must be a power of two"); +#define MOZZI_CHECK_POW2(X) static_assert((X & (X - 1)) == 0, #X " must be a power of two"); /// Simply a way to check if X is Y, realiably, in case one or both are defined empty (such as because of a programmer's typo) #define MOZZI_IS(X, Y) (X == Y) diff --git a/mozzi_analog.cpp b/mozzi_analog.cpp index 927bc40a9..ae472dbbf 100644 --- a/mozzi_analog.cpp +++ b/mozzi_analog.cpp @@ -10,7 +10,6 @@ */ -#include "mozzi_config.h" #include "mozzi_analog.h" #include "hardware_defines.h" From 5d3a611d30ba2acc5e85fd9c8bb58de8d4f19bd1 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Tue, 14 Nov 2023 10:37:26 +0100 Subject: [PATCH 043/215] Sinewave compiles on AVR with reworked config --- AudioOutput.h | 23 ++++-------- MozziConfigExample.h | 28 +++++++++++++-- MozziGuts.cpp | 29 +++++++-------- MozziGuts_impl_AVR.hpp | 63 ++++++++++++++++----------------- MozziGuts_impl_MBED.hpp | 4 +-- internal/config_check_generic.h | 13 ++++++- internal/config_checks_avr.h | 4 +++ internal/mozzi_macros.h | 22 +++++++++--- 8 files changed, 111 insertions(+), 75 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index f958f09fa..d8b81ad07 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -46,18 +46,11 @@ * than 16 bits). */ #define AudioOutputStorage_t int -#if IS_AVR() && ((AUDIO_MODE == STANDARD_PLUS) || (AUDIO_MODE == STANDARD)) -// TODO: remove this specialisation -> see MOZZI_AUDIO_BITS_OPTIMISTIC -#define SCALE_AUDIO(x,bits) (bits > 8 ? (x) >> (bits - 8) : (x) << (8 - bits)) -#define SCALE_AUDIO_NEAR(x,bits) (bits > 9 ? (x) >> (bits - 9) : (x) << (9 - bits)) -#define CLIP_AUDIO(x) constrain((x), -244,243) -#else -#define SCALE_AUDIO(x,bits) (bits > AUDIO_BITS ? (x) >> (bits - AUDIO_BITS) : (x) << (AUDIO_BITS - bits)) -#define SCALE_AUDIO_NEAR(x,bits) SCALE_AUDIO(x,bits) -#define CLIP_AUDIO(x) constrain((x), (-(AudioOutputStorage_t) AUDIO_BIAS), (AudioOutputStorage_t) AUDIO_BIAS-1) -#endif +#define SCALE_AUDIO(x,bits) (bits > MOZZI_AUDIO_BITS ? (x) >> (bits - MOZZI_AUDIO_BITS) : (x) << (MOZZI_AUDIO_BITS - bits)) +#define SCALE_AUDIO_NEAR(x,bits) (bits > MOZZI_AUDIO_BITS_OPTIMISTIC ? (x) >> (bits - MOZZI_AUDIO_BITS_OPTIMISTIC) : (x) << (MOZZI_AUDIO_BITS_OPTIMISTIC - bits)) +#define CLIP_AUDIO(x) constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) MOZZI_AUDIO_BIAS-1) -#if (AUDIO_CHANNELS == STEREO) +#if MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO) #define AudioOutput StereoOutput #if (STEREO_HACK == true) #define AudioOutput_t void @@ -93,7 +86,7 @@ struct StereoOutput { StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r) : _l(l), _r(r) {}; /** Default contstructor */ StereoOutput() : _l(0), _r(0) {}; -#if (MOZZI_AUDIO_CHANNELS != MOZZI_STEREO) +#if !MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO) /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning). This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ @@ -134,7 +127,7 @@ template static inline StereoOutput fromNBit(uint8_t bits, T l, T r) struct MonoOutput { /** Construct an audio frame from raw values (zero-centered) */ MonoOutput(AudioOutputStorage_t l=0) : _l(l) {}; -#if (AUDIO_CHANNELS > 1) +#if (MOZZI_AUDIO_CHANNELS > 1) /** Conversion to stereo operator: If used in a stereo config, returns identical channels (and gives a compile time warning). This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ @@ -214,8 +207,4 @@ inline uint32_t pdmCode32(uint16_t sample) { return outbits; } -#if (EXTERNAL_AUDIO_OUTPUT == true) -#warning "Mozzi is configured to use an external void 'audioOutput(const AudioOutput f)' function. Please define one in your sketch" -#endif - #endif diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 7da4651b2..e4e1dd895 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -277,6 +277,7 @@ * In other words, increasing this improves the signal quality at less cost than doubling the audio rate itself. However, increasing this too far will limit the dynamic resolution of the samples that can be * written to the output pin(s): 2 ^ (output bits) * MOZZI_PWM_RATE cannot be higher than the CPU frequency! */ +//#define MOZZI_PWM_RATE 65356 /** @ingroup core * @def MOZZI_AUDIO_BITS_PER_CHANNEL @@ -286,9 +287,32 @@ * * See @ref hardware_avr for a more detailed description. */ +//#define MOZZI_AUDIO_BITS_PER_CHANNEL 8 - - +/** @ingroup core + * @def MOZZI_AUDIO_PIN_1 + * + * Only for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_PWM and MOZZI_OUTPUT_2PIN_PWM: The IO pin to use as (first) audio output. This **must** be attached to Timer1. + * When settings this, you alsso need to specify the output compare register responsible for this pin (either OCR1A or OCR1B). + * + * Example: + * @code + * #define MOZZI_AUDIO_PIN_1 TIMER1_B_PIN + * #define MOZZI_AUDIO_PIN_1_REGISTER OCR1B // must also specify this, when customizing MOZZI_AUDIO_PIN_1 + * @endcode + * + * Equivalent definitions can be used to control the pin for the right audio channel (in stereo mode), or the low byte channel (in 2 Pin PWM mode): + * + * @code + * #define MOZZI_AUDIO_PIN_2 [...] + * #define MOZZI_AUDIO_PIN_2_REGISTER [the matching OCR] + * // or + * #define MOZZI_AUDIO_PIN_2_LOW [...] + * #define MOZZI_AUDIO_PIN_2_LOW_REGISTER [the matching OCR] + * @endcode + * + * @see config/known_16bit_timers.h + * */ /***************************************** ADVANCED SETTTINGS -- External audio output ****************************************** diff --git a/MozziGuts.cpp b/MozziGuts.cpp index 139de506a..04e4b19e2 100644 --- a/MozziGuts.cpp +++ b/MozziGuts.cpp @@ -17,11 +17,6 @@ //#include "mozzi_utils.h" #include "AudioOutput.h" -#define AUDIO_INPUT_NONE 0 -#define AUDIO_INPUT_LEGACY 1 -#define AUDIO_INPUT_CUSTOM 2 - - // Forward declarations of functions to be provided by platform specific implementations #if (!BYPASS_MOZZI_OUTPUT_BUFFER) static void CACHED_FUNCTION_ATTR defaultAudioOutput(); @@ -57,10 +52,12 @@ static void startSecondADCReadOnCurrentChannel(); /* Retro-compatibility with "legacy" boards which use the async ADC for getting AUDIO_INPUT */ -#if (defined(USE_AUDIO_INPUT) && !defined(AUDIO_INPUT_MODE)) - #define AUDIO_INPUT_MODE AUDIO_INPUT_LEGACY -#elif !defined(AUDIO_INPUT_MODE) - #define AUDIO_INPUT_MODE AUDIO_INPUT_NONE +#if !defined(MOZZI__LEGACY_AUDIO_INPUT_IMPL) +# if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) +# define MOZZI__LEGACY_AUDIO_INPUT_IMPL 1 +# else +# define MOZZI__LEGACY_AUDIO_INPUT_IMPL 0 +# endif #endif @@ -85,7 +82,7 @@ CircularBuffer output_buffer; // fixed size 256 # define bufferAudioOutput(f) output_buffer.write(f) static void CACHED_FUNCTION_ATTR defaultAudioOutput() { -#if (AUDIO_INPUT_MODE == AUDIO_INPUT_LEGACY) // in that case, we rely on asynchroneous ADC reads implemented for mozziAnalogRead to get the audio in samples +#if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // in that case, we rely on asynchroneous ADC reads implemented for mozziAnalogRead to get the audio in samples adc_count = 0; startSecondADCReadOnCurrentChannel(); // the current channel is the AUDIO_INPUT pin # endif @@ -119,8 +116,8 @@ void adcReadSelectedChannels() { __attribute__((noinline)) void adcStartReadCycle() { if (current_channel < 0) // last read of adc_channels_to_read stack was empty, ie. all channels from last time have been read { -#if (AUDIO_INPUT_MODE == AUDIO_INPUT_LEGACY) // use of async ADC for audio input - adc_channels_to_read.push(AUDIO_INPUT_PIN); // for audio +#if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // use of async ADC for audio input + adc_channels_to_read.push(MOZZI_AUDIO_INPUT_PIN); // for audio #else adcReadSelectedChannels(); adc_count = 0; @@ -139,12 +136,12 @@ int mozziAnalogRead(uint8_t pin) { #endif } -#if (USE_AUDIO_INPUT == true) +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) static AudioOutputStorage_t audio_input; // holds the latest audio from input_buffer AudioOutputStorage_t getAudioInput() { return audio_input; } #endif -#if (AUDIO_INPUT_MODE == AUDIO_INPUT_LEGACY) +#if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // ring buffer for audio input CircularBuffer input_buffer; // fixed size 256 #define audioInputAvailable() (!input_buffer.isEmpty()) @@ -227,7 +224,7 @@ void audioHook() // 2us on AVR excluding updateAudio() LOOP_YIELD #endif -#if (USE_AUDIO_INPUT == true) +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) if (audioInputAvailable()) audio_input = readAudioInput(); #endif } @@ -263,7 +260,7 @@ void startMozzi(int control_rate_hz) { // in setup() if desired (not for Teensy 3.* ) setupFastAnalogRead(); // delay(200); // so AutoRange doesn't read 0 to start with - update_control_timeout = AUDIO_RATE / control_rate_hz; + update_control_timeout = MOZZI_AUDIO_RATE / control_rate_hz; startAudio(); } diff --git a/MozziGuts_impl_AVR.hpp b/MozziGuts_impl_AVR.hpp index 8e2bf0c50..c06da2e46 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/MozziGuts_impl_AVR.hpp @@ -133,7 +133,7 @@ carrier freq noise can be an issue static uint8_t pre_mozzi_TCCR1A, pre_mozzi_TCCR1B, pre_mozzi_OCR1A, pre_mozzi_TIMSK1; -#if (AUDIO_MODE == HIFI) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) #if defined(TCCR2A) static uint8_t pre_mozzi_TCCR2A, pre_mozzi_TCCR2B, pre_mozzi_OCR2A, pre_mozzi_TIMSK2; @@ -153,7 +153,7 @@ static void backupPreMozziTimer1() { pre_mozzi_TIMSK1 = TIMSK1; } -#if (AUDIO_MODE == HIFI) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) #if defined(TCCR2A) static uint8_t mozzi_TCCR2A, mozzi_TCCR2B, mozzi_OCR2A, mozzi_TIMSK2; #elif defined(TCCR2) @@ -164,7 +164,7 @@ static uint8_t mozzi_TCCR4A, mozzi_TCCR4B, mozzi_TCCR4C, mozzi_TCCR4D, #endif #endif -#if (EXTERNAL_AUDIO_OUTPUT == true) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // TODO: Check: This block used to compile also for BYPASS_MOZZI_OUTPUT_BUFFER, but I think unneccessarily so. static void startAudio() { backupPreMozziTimer1(); Timer1.initializeCPUCycles( @@ -181,38 +181,38 @@ static void startAudio() { ISR(TIMER1_OVF_vect, ISR_BLOCK) { defaultAudioOutput(); } -#elif (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS) +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) inline void audioOutput(const AudioOutput f) { - AUDIO_CHANNEL_1_OUTPUT_REGISTER = f.l()+AUDIO_BIAS; -# if (AUDIO_CHANNELS > 1) - AUDIO_CHANNEL_2_OUTPUT_REGISTER = f.r()+AUDIO_BIAS; + MOZZI_AUDIO_PIN_1_REGISTER = f.l()+MOZZI_AUDIO_BIAS; +# if (MOZZI_AUDIO_CHANNELS > 1) + MOZZI_AUDIO_PIN_2_REGISTER = f.r()+MOZZI_AUDIO_BIAS; # endif } static void startAudio() { backupPreMozziTimer1(); - pinMode(AUDIO_CHANNEL_1_PIN, OUTPUT); // set pin to output for audio - // pinMode(AUDIO_CHANNEL_2_PIN, OUTPUT); // set pin to output for audio -# if (AUDIO_MODE == STANDARD) + pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); // set pin to output for audio +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) && (MOZZI_PWM_RATE < 32768) // Formerly known as the - long since deprecated - "STANDARD" mode Timer1.initializeCPUCycles( - (F_CPU/AUDIO_RATE)-1,// the -1 here is a result of empirical tests + (F_CPU/MOZZI_AUDIO_RATE)-1,// the -1 here is a result of empirical tests // that showed that it brings the resulting frequency // closer to what is expected. // see: https://github.com/sensorium/Mozzi/pull/202 PHASE_FREQ_CORRECT); // set period, phase and frequency correct -# else // (AUDIO_MODE == STANDARD_PLUS) - Timer1.initializeCPUCycles((F_CPU/PWM_RATE)-1, // the -1 here is a result of empirical tests +# else // Formerly known as "STANDARD_PLUS" mode + Timer1.initializeCPUCycles((F_CPU/MOZZI_PWM_RATE)-1, // the -1 here is a result of empirical tests // that showed that it brings the resulting frequency // closer to what is expected. // see: https://github.com/sensorium/Mozzi/pull/202 FAST); // fast mode enables higher PWM rate # endif - Timer1.pwm(AUDIO_CHANNEL_1_PIN, - AUDIO_BIAS); // pwm pin, 50% of Mozzi's duty cycle, ie. 0 signal -# if (AUDIO_CHANNELS > 1) - Timer1.pwm(AUDIO_CHANNEL_2_PIN, AUDIO_BIAS); // sets pin to output + Timer1.pwm(MOZZI_AUDIO_PIN_1, + MOZZI_AUDIO_BIAS); // pwm pin, 50% of Mozzi's duty cycle, ie. 0 signal +# if (MOZZI_AUDIO_CHANNELS > 1) + pinMode(MOZZI_AUDIO_PIN_2, OUTPUT); // set pin to output for audio + Timer1.pwm(MOZZI_AUDIO_PIN_2, MOZZI_AUDIO_BIAS); # endif TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using // Timer1.attachInterrupt()) @@ -222,7 +222,8 @@ static void startAudio() { Arduino output register, running at AUDIO_RATE. */ ISR(TIMER1_OVF_vect, ISR_BLOCK) { -# if (AUDIO_MODE == STANDARD_PLUS) && (AUDIO_RATE == 16384) // only update every second ISR, if lower audio rate +# if (MOZZI_AUDIO_RATE < MOZZI_PWM_RATE) // only update every second ISR, if lower audio rate + static_assert(2l*MOZZI_AUDIO_RATE == MOZZI_PWM_RATE, "audio rate must the same, or exactly half of the pwm rate!"); static boolean alternate; alternate = !alternate; if (alternate) return; @@ -231,9 +232,8 @@ ISR(TIMER1_OVF_vect, ISR_BLOCK) { defaultAudioOutput(); } -#elif (AUDIO_MODE == HIFI) -# if (EXTERNAL_AUDIO_OUTPUT != true) -# include "AudioConfigHiSpeed14bitPwm.h" +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) +# include "AudioConfigHiSpeed14bitPwm.h" inline void audioOutput(const AudioOutput f) { // read about dual pwm at // http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ @@ -242,13 +242,13 @@ inline void audioOutput(const AudioOutput f) { // if (!output_buffer.isEmpty()){ //unsigned int out = output_buffer.read(); // 14 bit, 7 bits on each pin - // AUDIO_CHANNEL_1_highByte_REGISTER = out >> 7; // B00111111 10000000 becomes + // MOZZI_AUDIO_PIN_1_REGISTER = out >> 7; // B00111111 10000000 becomes // B1111111 // try to avoid looping over 7 shifts - need to check timing or disassemble to // see what really happens unsigned int out_high = out<<1; // B00111111 // 10000000 becomes B01111111 00000000 - // AUDIO_CHANNEL_1_highByte_REGISTER = out_high >> 8; // B01111111 00000000 - // produces B01111111 AUDIO_CHANNEL_1_lowByte_REGISTER = out & 127; + // MOZZI_AUDIO_PIN_1_REGISTER = out_high >> 8; // B01111111 00000000 + // produces B01111111 MOZZI_AUDIO_PIN_1_LOW_REGISTER = out & 127; /* Atmega manual, p123 The high byte (OCR1xH) has to be written first. When the high byte I/O location is written by the CPU, @@ -258,25 +258,24 @@ inline void audioOutput(const AudioOutput f) { either the OCR1x buffer or OCR1x Compare Register in the same system clock cycle. */ - AUDIO_CHANNEL_1_highByte_REGISTER = (f.l()+AUDIO_BIAS) >> AUDIO_BITS_PER_REGISTER; - AUDIO_CHANNEL_1_lowByte_REGISTER = (f.l()+AUDIO_BIAS) & ((1 << AUDIO_BITS_PER_REGISTER) - 1); + MOZZI_AUDIO_PIN_1_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_REGISTER; + MOZZI_AUDIO_PIN_1_LOW_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_REGISTER) - 1); } -# endif static void setupTimer2(); static void startAudio() { backupPreMozziTimer1(); // pwm on timer 1 - pinMode(AUDIO_CHANNEL_1_highByte_PIN, + pinMode(MOZZI_AUDIO_CHANNEL_1_PIN, OUTPUT); // set pin to output for audio, use 3.9k resistor - pinMode(AUDIO_CHANNEL_1_lowByte_PIN, + pinMode(MOZZI_AUDIO_CHANNEL_1_LOW_PIN, OUTPUT); // set pin to output for audio, use 499k resistor Timer1.initializeCPUCycles( F_CPU/125000, FAST); // set period for 125000 Hz fast pwm carrier frequency = 14 bits - Timer1.pwm(AUDIO_CHANNEL_1_highByte_PIN, + Timer1.pwm(MOZZI_AUDIO_CHANNEL_1_PIN, 0); // pwm pin, 0% duty cycle, ie. 0 signal - Timer1.pwm(AUDIO_CHANNEL_1_lowByte_PIN, + Timer1.pwm(MOZZI_AUDIO_CHANNEL_1_LOW_PIN, 0); // pwm pin, 0% duty cycle, ie. 0 signal // audio output interrupt on timer 2, sets the pwm levels of timer 1 setupTimer2(); @@ -349,7 +348,7 @@ void stopMozzi() { TIMSK1 = pre_mozzi_TIMSK1; -#if (AUDIO_MODE == HIFI) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) #if defined(TCCR2A) TCCR2A = pre_mozzi_TCCR2A; TCCR2B = pre_mozzi_TCCR2B; diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index e3a642218..ea1878f57 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -18,8 +18,8 @@ ////// BEGIN analog input code //////// -#if (USE_AUDIO_INPUT) -#define AUDIO_INPUT_MODE AUDIO_INPUT_CUSTOM +#if MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_STANDARD) +#define MOZZI__LEGACY_AUDIO_INPUT_IMPL 0 #include diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 2650b79b6..5e5ac4d01 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -78,6 +78,14 @@ MOZZI_CHECK_POW2(MOZZI_CONTROL_RATE) #error "MOZZI_AUDIO_CHANNELS outside of (currently) supported range" #endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) +#warning "Mozzi is configured to use an external void 'audioOutput(const AudioOutput f)' function. Please define one in your sketch" +#endif + +#if defined(BYPASS_MOZZI_OUTPUT_BUFFER) +#error "BYPASS_MOZZI_OUTPUT_BUFFER may not be customized via config" +#endif + // Hardware-specific checks file should have more narrow checks for most options, below, but is not required to, so let's check for anything that is wildly out of scope: MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC) MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) @@ -105,9 +113,12 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_RE #define AUDIO_RATE_AS_LSHIFT 16 #define MICROS_PER_AUDIO_TICK 15 #else -//#error Whoopsie, not LSHIFT defined for this audio rate. Please report and/or fix +#error Whoopsie, not LSHIFT defined for this audio rate. Please report and/or fix #endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) +#define BYPASS_MOZZI_OUTPUT_BUFFER true +#endif /// Step 5: Patch up some backwards compatibility issues as far as config-related #if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index 5084f84a8..fc04ae1a7 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -19,9 +19,11 @@ #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) # if !defined(MOZZI_AUDIO_PIN_1) #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN +#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A # endif # if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_2) #define MOZZI_AUDIO_PIN_2 TIMER1_B_PIN +#define MOZZI_AUDIO_PIN_2_REGISTER OCR1B # endif # if !defined(MOZZI_PWM_RATE) @@ -37,9 +39,11 @@ #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) # if !defined(MOZZI_AUDIO_PIN_1) #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN +#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A # endif # if !defined(MOZZI_AUDIO_PIN_1) #define MOZZI_AUDIO_PIN_1_LOW TIMER1_B_PIN +#define MOZZI_AUDIO_PIN_1_LOW_REGISTER OCR1B # endif # if !defined(MOZZI_PWM_RATE) diff --git a/internal/mozzi_macros.h b/internal/mozzi_macros.h index ea692a3d0..51b157dbb 100644 --- a/internal/mozzi_macros.h +++ b/internal/mozzi_macros.h @@ -16,19 +16,31 @@ // MSVC needs this indirection for proper __VA_ARGS__ expansion. I case we ever need to support MSVC... #define MOZZI__MACRO_EVAL(...) __VA_ARGS__ -/// @file mozzi_internal_macros -/// compile time check whether the given first value (usually specified as a #define) is among the values specified in subsequent args (up to 20) -/// @example MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL) +/** @file mozzi_internal_macros + * compile time check whether the given first value (usually specified as a #define) is among the values specified in subsequent args (up to 20) + * + * Example: @code MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL) @endcode +*/ #define MOZZI_CHECK_SUPPORTED(X, ...) MOZZI__MACRO_EVAL(MOZZI__CHECK_SUPPORTED(X, #X, __VA_ARGS__, \ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE)) -/// Complain if the given argument is not a power of two +/** Compile time check to complain if the given argument is not a power of two */ #define MOZZI_CHECK_POW2(X) static_assert((X & (X - 1)) == 0, #X " must be a power of two"); -/// Simply a way to check if X is Y, realiably, in case one or both are defined empty (such as because of a programmer's typo) +/** Simply a way to check if X equal Y, realiably (at compile time). The advantage of this macro is that it will produce an error, in case one or both are defined empty + * (such as because of a programmer's typo) + * + * TODO: Gahh, this doesn't work. I thought it did. + * + * Example: @code + * #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) + * [...] + * #endif + * @endcode + */ #define MOZZI_IS(X, Y) (X == Y) #endif From dbdfcf13435d5be9fd1d0355d1d4b8f276ab993a Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Tue, 14 Nov 2023 10:44:39 +0100 Subject: [PATCH 044/215] Fix typos in defines --- MozziConfigExample.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MozziConfigExample.h b/MozziConfigExample.h index e4e1dd895..7de7e0f50 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -23,7 +23,7 @@ #include // needed for the named option values /** @ingroup core - * @def MOZZI_COMPATIBILTY_LEVEL + * @def MOZZI_COMPATIBILITY_LEVEL * * Mozzi generally tries to keep your old sketches working, but we continue to find new (and hopefully better) approaches to old problems. * Sometimes, keeping API compatibilty with the pre-existing solution may come with a smaller or larger penalty in terms of performance or code size. @@ -35,9 +35,9 @@ * - MOZZI_COMPATIBILITY_LATEST - always live on the bleeding edge * * @note - * MOZZI_COMPATIBILTY_V1_1 does not guarantee, that *everything* from Mozzi 1.1 will continue to work, just that we're doing a reasonable effort. + * MOZZI_COMPATIBILITY_V1_1 does not guarantee, that *everything* from Mozzi 1.1 will continue to work, just that we're doing a reasonable effort. */ -//#define MOZZI_COMPATIBILTY_LEVEL MOZZI_COMPATIBILTY_LATEST +//#define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_LATEST /** @ingroup core * @def MOZZI_AUDIO_MODE @@ -307,8 +307,8 @@ * #define MOZZI_AUDIO_PIN_2 [...] * #define MOZZI_AUDIO_PIN_2_REGISTER [the matching OCR] * // or - * #define MOZZI_AUDIO_PIN_2_LOW [...] - * #define MOZZI_AUDIO_PIN_2_LOW_REGISTER [the matching OCR] + * #define MOZZI_AUDIO_PIN_1_LOW [...] + * #define MOZZI_AUDIO_PIN_1_LOW_REGISTER [the matching OCR] * @endcode * * @see config/known_16bit_timers.h @@ -329,12 +329,12 @@ * your own sketch, yourself. Some understanding of the general Mozzi audio output architecture may be recommendable, when using this * mode: See @ref AudioOutput . * - * In the more simple case (MOZZI_OUPUT_EXTERNAL_TIMED), Mozzi will still take care of buffering the samples, and calling this function + * In the more simple case (MOZZI_OUTPUT_EXTERNAL_TIMED), Mozzi will still take care of buffering the samples, and calling this function * at audio rate (hence "timed"). This generally involves use of a timer, which should be detailed in the @ref hardware details for * your platform. * * Should you desire even more control - perhaps because your board, or your external DAC already comes with a rate controlled DMA buffer - - * using MOZZI_OUPUT_EXTERNAL_CUSTOM also bypasses Mozzis sample buffer. In addition to audioOutput(), you will then need to provide + * using MOZZI_OUTPUT_EXTERNAL_CUSTOM also bypasses Mozzis sample buffer. In addition to audioOutput(), you will then need to provide * a definition for canBufferAudioOutput(), which will control the rate at which samples are produced. In essence, whenever * canBufferAudioOutput() returns true, Mozzi will call updateAudio(), and pass the produced sample to audioOutput(), unbuffered. It is * entirely your job to make sure that this actually happens at MOZZI_AUDIO_RATE, and / or an appropriate buffer gets used. From 12640337694a38e7cbcf120393ae24c7d43047eb Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Tue, 14 Nov 2023 13:21:56 +0100 Subject: [PATCH 045/215] Also compiles for ESP32, now, in default config. --- AudioConfigESP32.h | 45 --------------------- MozziConfigExample.h | 72 ++++++++++++++++++++++++++++++++- MozziGuts.h | 31 -------------- MozziGuts_impl_ESP32.hpp | 52 ++++++++++++------------ Readme_Mozzi_2_0.md | 3 +- hardware_defines.h | 6 --- internal/config_check_generic.h | 13 +++--- internal/config_checks_esp32.h | 68 +++++++++++++++++++++++++++++++ 8 files changed, 176 insertions(+), 114 deletions(-) delete mode 100644 AudioConfigESP32.h create mode 100644 internal/config_checks_esp32.h diff --git a/AudioConfigESP32.h b/AudioConfigESP32.h deleted file mode 100644 index fd3fcba76..000000000 --- a/AudioConfigESP32.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef AUDIOCONFIGESP32_H -#define AUDIOCONFIGESP32_H - -#if not IS_ESP32() -#error This header should be included for ESP32 architecture, only -#endif - -#if (AUDIO_MODE == HIFI) -#error HIFI mode is not available for this CPU architecture (but check ESP32_AUDIO_OUT_MODE, and PDM_RESOLUTION) -#endif - -// Audio output options -#define INTERNAL_DAC 1 // output using internal DAC via I2S, output on pin 26 -#define PT8211_DAC 2 // output using an external PT8211 DAC via I2S -#define PDM_VIA_I2S 3 // output PDM coded sample on the I2S data pin (pin 33, by default, configurable, below) - -// Set output mode -#define ESP32_AUDIO_OUT_MODE INTERNAL_DAC - -// For external I2S output, only: I2S_PINS -#define ESP32_I2S_BCK_PIN 26 -#define ESP32_I2S_WS_PIN 25 -#define ESP32_I2S_DATA_PIN 33 - -#include -const i2s_port_t i2s_num = I2S_NUM_0; -/// User config end. Do not modify below this line - -#if (ESP32_AUDIO_OUT_MODE == INTERNAL_DAC) -#define AUDIO_BITS 8 -#define PDM_RESOLUTION 1 -#elif (ESP32_AUDIO_OUT_MODE == PT8211_DAC) -#define AUDIO_BITS 16 -#define PDM_RESOLUTION 1 -#elif (ESP32_AUDIO_OUT_MODE == PDM_VIA_I2S) -#define AUDIO_BITS 16 -#define PDM_RESOLUTION 4 -#else -#error Invalid output mode configured in AudioConfigESP32.h -#endif - -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) -#define BYPASS_MOZZI_OUTPUT_BUFFER true - -#endif // #ifndef AUDIOCONFIGESP_H diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 7de7e0f50..73e5eb0d3 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -203,7 +203,7 @@ * - MOZZI_OUTPUT_EXTERNAL_TIMED * - MOZZI_OUTPUT_EXTERNAL_CUSTOM * - * In all cases, Timer 1 is claimed, and is not available for any other purpose. + * In all cases, except MOZZI_OUTPUT_EXTERNAL_CUSTOM, Timer 1 is claimed, and is not available for any other purpose. * * @section avr_pwm MOZZI_OUTPUT_PWM * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured @@ -356,3 +356,73 @@ * some 8 bit boards! */ //#define MOZZI_AUDIO_BITS 16 + + + + +/***************************************** ADVANCED SETTTINGS -- ESP32 *********************************************************** + * + * The settings in the following section applies to the ESP32 architecture. + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + + +/** @ingroup hardware + * @page hardware_esp32 Mozzi on ESP32-based boards. + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PDM_VIA_I2S + * - MOZZI_OUTPUT_I2S_DAC + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref esp32_internal_dac . + * + * @note + * This port really does not currently come with a PWM mode! + * + * @section esp32_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * The internal DAC has 8 bit resolution, and outputs to GPIO pins 25 and 26 (non-configurable). For simplicity of code, both pins are always used. + * In a mono configuration, both pins output the same sample. + * + * TODO: We could really use this to hack in a 2 PIN mode! + * + * @note + * The number 25 refers to "GPIO 25" or sometimes labelled "D25". Confusingly, many boards come with an additional, totally different numbering scheme on top of that. + * + * Internally, the inbuilt DAC is connected via an I2S interface. Which interface number to use can be configured using: + * + * @code + * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0) + * @endcode + * + * @section esp32_i2s_dac MOZZI_OUTPUT_I2S_DAC + * This mode outputs to a PT8211 (or compatible) I2S DAC, which allows for very high quality (mono or stereo) output. Communication needs the BCK, WS, and DATA(out) pins + * of one I2S interface. Presumably, any pins qualify, and you can configure this using: + * @code + * #define MOZZI_I2S_PIN_BCK ... // (default: 26) + * #define MOZZI_I2S_PIN_WS ... // (default: 15) + * #define MOZZI_I2S_PIN_DATA ... // (default: 33) + * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0) + * @endcode + * + * See the note above (@ref esp_internal_dac) regarding pin numbering. Also, please always test the default pinout, should a custom setting fail! + * + * As a technical note, I2S support in the ESP32 SDK has been reworked since this was implemented in Mozzi, and Mozzi uses the "legacy" implementation "i2s.h". + * This should not be an issue, unless you want to connect additional I2S components, yourself. In which case contributions are certainly welcome! + * + * @section esp32_pdm_via_i2s MOZZI_OUTPUT_PDM_VIA_I2S + * This mode uses the same setup as @ref esp32_i2s_dac, but rather than using an external DAC, the communication signal itself is modulated in PDM + * (pulse density modulation) encoded form. Thus not extra hardware is needed, and the signal is output on the DATA pin (see above). The BCK and + * WS pins are also claimed, but should be left non-connected, and do not produce anything meaningful. This can only be used in mono mode. + * + * Output resolution may be adjusted by defining MOZZI_PDM_RESOLUTION , where the default value of 4 means that each audio sample is encoded into four 32 bit blocks + * of ones and zeros. Obviously, more is potentially better, but at the cost of considerable computation power. + * + * @section esp32_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ diff --git a/MozziGuts.h b/MozziGuts.h index a178cd5d1..cbaeccb7a 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -32,37 +32,6 @@ #include "internal/config_check_generic.h" - -#if (EXTERNAL_AUDIO_OUTPUT != true) -#if IS_TEENSY3() -#include "AudioConfigTeensy3_12bit.h" -#elif IS_TEENSY4() -#include "AudioConfigTeensy4.h" -#elif IS_STM32() -#include "AudioConfigSTM32.h" -#elif IS_STM32DUINO() -#include "AudioConfigSTM32duino.h" -#elif IS_ESP8266() -#include "AudioConfigESP.h" -#elif IS_ESP32() -#include "AudioConfigESP32.h" -#elif IS_SAMD21() -#include "AudioConfigSAMD21.h" -#elif IS_RP2040() -#include "AudioConfigRP2040.h" -#elif IS_MBED() -#include "AudioConfigMBED.h" -#elif IS_RENESAS() -#include "AudioConfigRenesas.h" -#endif -#else // EXTERNAL_AUDIO_OUTPUT==true -#if !defined(EXTERNAL_AUDIO_BITS) -#define EXTERNAL_AUDIO_BITS 16 -#endif -#define AUDIO_BITS EXTERNAL_AUDIO_BITS -#define AUDIO_BIAS (1 << (AUDIO_BITS - 1)) -#endif - #if (STEREO_HACK == true) extern int audio_out_1, audio_out_2; #endif diff --git a/MozziGuts_impl_ESP32.hpp b/MozziGuts_impl_ESP32.hpp index 7657eb62c..a5ef98ed8 100644 --- a/MozziGuts_impl_ESP32.hpp +++ b/MozziGuts_impl_ESP32.hpp @@ -39,22 +39,21 @@ void setupMozziADC(int8_t speed) { //// BEGIN AUDIO OUTPUT code /////// -#include // for I2S-based output modes -#include // for EXTERNAL_AUDIO_OUTPUT +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) +# include // for I2S-based output modes, including - technically - internal DAC +const i2s_port_t i2s_num = MOZZI_I2S_PORT; -#if (EXTERNAL_AUDIO_OUTPUT != true) -# include "AudioConfigESP32.h" // On ESP32 we cannot test wether the DMA buffer has room. Instead, we have to use a one-sample mini buffer. In each iteration we // _try_ to write that sample to the DMA buffer, and if successful, we can buffer the next sample. Somewhat cumbersome, but works. // TODO: Should ESP32 gain an implemenation of i2s_available(), we should switch to using that, instead. static bool _esp32_can_buffer_next = true; -# if (ESP32_AUDIO_OUT_MODE == INTERNAL_DAC) +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) static uint16_t _esp32_prev_sample[2]; # define ESP_SAMPLE_SIZE (2*sizeof(uint16_t)) -# elif (ESP32_AUDIO_OUT_MODE == PT8211_DAC) +# elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) static int16_t _esp32_prev_sample[2]; # define ESP_SAMPLE_SIZE (2*sizeof(int16_t)) -# elif (ESP32_AUDIO_OUT_MODE == PDM_VIA_I2S) +# elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) static uint32_t _esp32_prev_sample[PDM_RESOLUTION]; # define ESP_SAMPLE_SIZE (PDM_RESOLUTION*sizeof(uint32_t)) # endif @@ -72,17 +71,17 @@ inline bool canBufferAudioOutput() { } inline void audioOutput(const AudioOutput f) { -# if (ESP32_AUDIO_OUT_MODE == INTERNAL_DAC) - _esp32_prev_sample[0] = (f.l() + AUDIO_BIAS) << 8; -# if (AUDIO_CHANNELS > 1) - _esp32_prev_sample[1] = (f.r() + AUDIO_BIAS) << 8; +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) + _esp32_prev_sample[0] = (f.l() + MOZZI_AUDIO_BIAS) << 8; +# if (MOZZI_AUDIO_CHANNELS > 1) + _esp32_prev_sample[1] = (f.r() + MOZZI_AUDIO_BIAS) << 8; # else // For simplicity of code, even in mono, we're writing stereo samples _esp32_prev_sample[1] = _esp32_prev_sample[0]; # endif -# elif (ESP32_AUDIO_OUT_MODE == PDM_VIA_I2S) - for (uint8_t i=0; i void CACHED_FUNCTION_ATTR timer0_audio_output_isr(void *) { TIMERG0.int_clr_timers.t0 = 1; TIMERG0.hw_timer[0].config.alarm_en = 1; @@ -102,7 +102,7 @@ void CACHED_FUNCTION_ATTR timer0_audio_output_isr(void *) { #endif static void startAudio() { -#if (BYPASS_MOZZI_OUTPUT_BUFFER != true) // for external audio output, set up a timer running a audio rate +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // for external audio output, set up a timer running a audio rate static intr_handle_t s_timer_handle; const int div = 2; timer_config_t config = { @@ -116,19 +116,19 @@ static void startAudio() { }; timer_init(TIMER_GROUP_0, TIMER_0, &config); timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); - timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 80000000UL / AUDIO_RATE / div); + timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 80000000UL / MOZZI_AUDIO_RATE / div); timer_enable_intr(TIMER_GROUP_0, TIMER_0); timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer0_audio_output_isr, nullptr, 0, &s_timer_handle); timer_start(TIMER_GROUP_0, TIMER_0); #else static const i2s_config_t i2s_config = { -# if (ESP32_AUDIO_OUT_MODE == PT8211_DAC) || (ESP32_AUDIO_OUT_MODE == PDM_VIA_I2S) +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), -# elif (ESP32_AUDIO_OUT_MODE == INTERNAL_DAC) +# elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN), # endif - .sample_rate = AUDIO_RATE * PDM_RESOLUTION, + .sample_rate = MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // only the top 8 bits will actually be used by the internal DAC, but using 8 bits straight away seems buggy .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // always use stereo output. mono seems to be buggy, and the overhead is insignifcant on the ESP32 .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB), // this appears to be the correct setting for internal DAC and PT8211, but not for other dacs @@ -139,15 +139,15 @@ static void startAudio() { }; i2s_driver_install(i2s_num, &i2s_config, 0, NULL); -# if (ESP32_AUDIO_OUT_MODE == PT8211_DAC) || (ESP32_AUDIO_OUT_MODE == PDM_VIA_I2S) +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) static const i2s_pin_config_t pin_config = { - .bck_io_num = ESP32_I2S_BCK_PIN, - .ws_io_num = ESP32_I2S_WS_PIN, - .data_out_num = ESP32_I2S_DATA_PIN, + .bck_io_num = MOZZI_I2S_PIN_BCK, + .ws_io_num = MOZZI_I2S_PIN_WS, + .data_out_num = MOZZI_I2S_PIN_DATA, .data_in_num = -1 }; i2s_set_pin((i2s_port_t)i2s_num, &pin_config); -# elif (ESP32_AUDIO_OUT_MODE == INTERNAL_DAC) +# elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) i2s_set_pin((i2s_port_t)i2s_num, NULL); i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); # endif @@ -160,3 +160,5 @@ void stopMozzi() { // TODO: implement me } //// END AUDIO OUTPUT code /////// + +#undef ESP_SAMPLE_SIZE // only used inside this file diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index 9a8fbbaaf..f17c9c3aa 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -24,7 +24,8 @@ all new - MOZZI_ANALOG_READS - MOZZI_COMPATIBILITY_LEVEL - +general: + - Added many config sanity checks. Some may be too strict, if so please mention Other removed stuff: - pauseMozzi() - was still declared but not defined -> not usable, anyway diff --git a/hardware_defines.h b/hardware_defines.h index e663939c1..3a5768960 100644 --- a/hardware_defines.h +++ b/hardware_defines.h @@ -105,12 +105,6 @@ #define NUM_ANALOG_INPUTS 1 #endif -#if IS_AVR() -#define AUDIO_RATE_PLATFORM_DEFAULT 16384 -#else -#define AUDIO_RATE_PLATFORM_DEFAULT 32768 -#endif - #if IS_ESP8266() #define CACHED_FUNCTION_ATTR ICACHE_RAM_ATTR #elif IS_ESP32() diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 5e5ac4d01..88f2e915e 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -7,6 +7,12 @@ #include "../MozziConfigValues.h" // in case not user-included #include "mozzi_macros.h" +/// Step 0: Check for some stuff that user should never configure directly (but may be set, indirectly from the hardware-specific setups) +#if defined(BYPASS_MOZZI_OUTPUT_BUFFER) +#error "BYPASS_MOZZI_OUTPUT_BUFFER may not be customized via config" +#endif + + //// Step 1: Apply missing defaults for generic config options (not the hardware specific ones) #if not defined(MOZZI_COMPATIBILITY_LEVEL) #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_2_0 @@ -45,10 +51,11 @@ //MOZZI_AUDIO_PIN_2_LOW -> hardware specific - /// Step 2: Include the hardware specific checks-and-defaults-header #if IS_AVR() #include "config_checks_avr.h" +#elif IS_ESP32() +#include "config_checks_esp32.h" #else // TODO #error oops @@ -82,10 +89,6 @@ MOZZI_CHECK_POW2(MOZZI_CONTROL_RATE) #warning "Mozzi is configured to use an external void 'audioOutput(const AudioOutput f)' function. Please define one in your sketch" #endif -#if defined(BYPASS_MOZZI_OUTPUT_BUFFER) -#error "BYPASS_MOZZI_OUTPUT_BUFFER may not be customized via config" -#endif - // Hardware-specific checks file should have more narrow checks for most options, below, but is not required to, so let's check for anything that is wildly out of scope: MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC) MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) diff --git a/internal/config_checks_esp32.h b/internal/config_checks_esp32.h new file mode 100644 index 000000000..490285333 --- /dev/null +++ b/internal/config_checks_esp32.h @@ -0,0 +1,68 @@ +#ifndef CONFIG_CHECK_ESP32_H +#define CONFIG_CHECK_ESP32_H + +#if not IS_ESP32() +#error This header should be included for ESP32 architecture, only +#endif + +#if !defined(MOZZI_AUDIO_MODE) +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC) + +#if !defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 32768 +#endif + +#if defined(MOZZI_PWM_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#endif + +#if !defined(MOZZI_ANALOG_READ) +# define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE +#endif + +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) +# if !defined(MOZZI_I2S_PIN_BCK) +# define MOZZI_I2S_PIN_BCK 26 +# endif +# if !defined(MOZZI_I2S_PIN_WS) +# define MOZZI_I2S_PIN_WS 25 +# endif +# if !defined(MOZZI_I2S_PIN_DATA) +# define MOZZI_I2S_PIN_DATA 33 +# endif +#endif + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) +# include +# if !defined(MOZZI_IS2_PORT) +# define MOZZI_I2S_PORT I2S_NUM_0 +# endif +#endif + +#if !defined(MOZZI_AUDIO_BITS) +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) +# define MOZZI_AUDIO_BITS 8 +# else +# define MOZZI_AUDIO_BITS 16 +# endif +#endif + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) +# if !defined(MOZZI_PDM_RESOLUTION) +# define MOZZI_PDM_RESOLUTION 8 +# endif +#else +# define MOZZI_PDM_RESOLUTION 1 // unconditionally, no other value allowed +#endif + +// All modes besides timed external bypass the output buffer! +#if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) +# define BYPASS_MOZZI_OUTPUT_BUFFER true +#endif + +#endif // #ifndef CONFIG_CHECK_ESP32_H From a7cdf791d8fd2e83802d8a6e2dea0ddcae9fb2ea Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Tue, 14 Nov 2023 15:34:09 +0100 Subject: [PATCH 046/215] Temporarily bring back mozzi_config.h to allow intermediate testing Fix some bits in AVR in reaction to that. Seems to work overall, however. --- AudioOutput.h | 2 +- MozziGuts.h | 1 + MozziGuts_impl_AVR.hpp | 19 +++++++------------ internal/config_checks_avr.h | 4 ++-- mozzi_analog.cpp | 1 + mozzi_config.h | 12 ++++++++++++ 6 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 mozzi_config.h diff --git a/AudioOutput.h b/AudioOutput.h index d8b81ad07..69bad2f38 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -39,7 +39,7 @@ #ifndef AUDIOOUTPUT #define AUDIOOUTPUT -#include "MozziGuts.h" +#include "mozzi_config.h" /** The type used to store a single channel of a single frame, internally. For compatibility with earlier versions of Mozzi this is defined as int. * If you do not care about keeping old sketches working, you may be able to save some RAM by using int16_t, instead (on boards where int is larger diff --git a/MozziGuts.h b/MozziGuts.h index cbaeccb7a..551f26be6 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -21,6 +21,7 @@ #endif #include "hardware_defines.h" +#include "mozzi_config.h" #if IS_TEENSY3() || IS_TEENSY4() // required from http://github.com/pedvide/ADC for Teensy 3.* diff --git a/MozziGuts_impl_AVR.hpp b/MozziGuts_impl_AVR.hpp index c06da2e46..90e6669f6 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/MozziGuts_impl_AVR.hpp @@ -233,7 +233,6 @@ ISR(TIMER1_OVF_vect, ISR_BLOCK) { } #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) -# include "AudioConfigHiSpeed14bitPwm.h" inline void audioOutput(const AudioOutput f) { // read about dual pwm at // http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ @@ -258,25 +257,21 @@ inline void audioOutput(const AudioOutput f) { either the OCR1x buffer or OCR1x Compare Register in the same system clock cycle. */ - MOZZI_AUDIO_PIN_1_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_REGISTER; - MOZZI_AUDIO_PIN_1_LOW_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_REGISTER) - 1); + MOZZI_AUDIO_PIN_1_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_CHANNEL; + MOZZI_AUDIO_PIN_1_LOW_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1); } static void setupTimer2(); static void startAudio() { backupPreMozziTimer1(); // pwm on timer 1 - pinMode(MOZZI_AUDIO_CHANNEL_1_PIN, - OUTPUT); // set pin to output for audio, use 3.9k resistor - pinMode(MOZZI_AUDIO_CHANNEL_1_LOW_PIN, - OUTPUT); // set pin to output for audio, use 499k resistor + pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); // set pin to output for audio, use 3.9k resistor + pinMode(MOZZI_AUDIO_PIN_1_LOW, OUTPUT); // set pin to output for audio, use 499k resistor Timer1.initializeCPUCycles( F_CPU/125000, FAST); // set period for 125000 Hz fast pwm carrier frequency = 14 bits - Timer1.pwm(MOZZI_AUDIO_CHANNEL_1_PIN, - 0); // pwm pin, 0% duty cycle, ie. 0 signal - Timer1.pwm(MOZZI_AUDIO_CHANNEL_1_LOW_PIN, - 0); // pwm pin, 0% duty cycle, ie. 0 signal + Timer1.pwm(MOZZI_AUDIO_PIN_1, 0); // pwm pin, 0% duty cycle, ie. 0 signal + Timer1.pwm(MOZZI_AUDIO_PIN_1_LOW, 0); // audio output interrupt on timer 2, sets the pwm levels of timer 1 setupTimer2(); } @@ -310,7 +305,7 @@ static void backupPreMozziTimer2() { // levels of timer 2 static void setupTimer2() { backupPreMozziTimer2(); // to reset while pausing - unsigned long period = F_CPU / AUDIO_RATE; + unsigned long period = F_CPU / MOZZI_AUDIO_RATE; FrequencyTimer2::setPeriodCPUCycles(period); FrequencyTimer2::setOnOverflow(dummy); FrequencyTimer2::enable(); diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index fc04ae1a7..f9d83ecc0 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -41,7 +41,7 @@ #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN #define MOZZI_AUDIO_PIN_1_REGISTER OCR1A # endif -# if !defined(MOZZI_AUDIO_PIN_1) +# if !defined(MOZZI_AUDIO_PIN_1_LOW) #define MOZZI_AUDIO_PIN_1_LOW TIMER1_B_PIN #define MOZZI_AUDIO_PIN_1_LOW_REGISTER OCR1B # endif @@ -50,7 +50,7 @@ #define MOZZI_PWM_RATE 125000 # endif -# if !defined(MOZZI_PWM_RATE) +# if !defined(MOZZI_AUDIO_BITS_PER_CHANNEL) #define MOZZI_AUDIO_BITS_PER_CHANNEL 7 # endif diff --git a/mozzi_analog.cpp b/mozzi_analog.cpp index ae472dbbf..72fd2ab82 100644 --- a/mozzi_analog.cpp +++ b/mozzi_analog.cpp @@ -13,6 +13,7 @@ #include "mozzi_analog.h" #include "hardware_defines.h" +#include "mozzi_config.h" /** NOTE: Since analog input code is heavily hardware dependent, and also heavily interweaved with AUDIO_INPUT, * it was moved to MozziGuts.cpp / MozziGuts_impl_XYZ.hpp for better maintainability. diff --git a/mozzi_config.h b/mozzi_config.h new file mode 100644 index 000000000..aaa21ce85 --- /dev/null +++ b/mozzi_config.h @@ -0,0 +1,12 @@ +/** TODO: Temporarily brought back to life for testing config rework. + * + * The plan still is to have config in user space, instead. + */ + +#include "MozziConfigValues.h" + +//#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +//#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO + +#include "internal/config_check_generic.h" + From 97959911cb0c1bd59eb9d3949577140bb5c9f417 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Wed, 15 Nov 2023 09:47:56 +0100 Subject: [PATCH 047/215] Allow to disable analog read code on AVR --- MozziConfigExample.h | 6 ++++- MozziGuts.cpp | 34 ++++++++++++++++++---------- MozziGuts_impl_AVR.hpp | 15 ++++++++----- MozziGuts_impl_ESP32.hpp | 14 +++++++----- MozziGuts_impl_template.hpp | 39 +++++++++++++++++++++------------ Readme_Mozzi_2_0.md | 2 +- internal/config_check_generic.h | 12 +++++++++- internal/mozzi_macros.h | 18 +++++++++++++++ mozzi_config.h | 1 + 9 files changed, 100 insertions(+), 41 deletions(-) diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 73e5eb0d3..da22a21ca 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -18,6 +18,7 @@ * (should your sketch have more than one .cpp-file, identical options need to be set before each #include ) * * TODO: Fix and complete Doxygen coverage + * TODO: Probably the recommendation to copy this whole file is over the top, perhaps provide stripped-down examples, instead */ #include // needed for the named option values @@ -140,7 +141,10 @@ * disabled, explicitly, to save resources, or in order to implement custom read schemes (e.g. with IO multiplexing). * * For simplicity, mozziAnalogRead() is always defined, but when MOZZI_ANALOG_READ s are disabled or unsupported, it simply relays - * to Arduino's regular analogRead(). + * to Arduino's regular analogRead(). Also setupFastAnalogReads() continues to be defined, for your convenience, but is not called automatically. + * + * As a rough estimate (your numbers may differ a bit, depending on compiler version, etc.), on an ATMEGA328P (aka Arduino Uno), + * disabling analog reads saves 33 bytes of RAM and 340 bytes of FLASH. The performance savings are theorized to be non-measurable, however. * * Currently allowed values are: * - MOZZI_ANALOG_READ_NONE diff --git a/MozziGuts.cpp b/MozziGuts.cpp index 04e4b19e2..66f71ae92 100644 --- a/MozziGuts.cpp +++ b/MozziGuts.cpp @@ -21,8 +21,11 @@ #if (!BYPASS_MOZZI_OUTPUT_BUFFER) static void CACHED_FUNCTION_ATTR defaultAudioOutput(); #endif -static void advanceADCStep(); -static void startSecondADCReadOnCurrentChannel(); +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) +static void advanceADCStep(); // to be provided by platform implementation +static void startSecondADCReadOnCurrentChannel(); // to be provided by platform implementation +static uint8_t adc_count = 0; // needed below +#endif // Include the appropriate implementation #if IS_AVR() @@ -60,9 +63,6 @@ static void startSecondADCReadOnCurrentChannel(); # endif #endif - -static uint8_t adc_count = 0; - ////// BEGIN Output buffering ///// #if BYPASS_MOZZI_OUTPUT_BUFFER == true uint64_t samples_written_to_buffer = 0; @@ -83,6 +83,7 @@ CircularBuffer output_buffer; // fixed size 256 static void CACHED_FUNCTION_ATTR defaultAudioOutput() { #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // in that case, we rely on asynchroneous ADC reads implemented for mozziAnalogRead to get the audio in samples + MOZZI_ASSERT_NOTEQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE); adc_count = 0; startSecondADCReadOnCurrentChannel(); // the current channel is the AUDIO_INPUT pin # endif @@ -98,6 +99,8 @@ jRaskell, bobgardner, theusch, Koshchi, and code by jRaskell. http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=789581 */ +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) + #include "Stack.h" static volatile int analog_readings[NUM_ANALOG_INPUTS]; static Stack adc_channels_to_read; @@ -126,14 +129,9 @@ __attribute__((noinline)) void adcStartReadCycle() { } int mozziAnalogRead(uint8_t pin) { -#if defined(MOZZI_FAST_ANALOG_IMPLEMENTED) pin = adcPinToChannelNum(pin); // allow for channel or pin numbers; on most platforms other than AVR this has no effect. See note on pins/channels adc_channels_to_read.push(pin); return analog_readings[channelNumToIndex(pin)]; -#else -# warning Asynchronouos analog reads not implemented for this platform - return analogRead(pin); -#endif } #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) @@ -171,7 +169,7 @@ inline void advanceADCStep() { } adc_count++; } -#else +#else // no (legacy) audio input /** NOTE: Triggered at CONTROL_RATE via advanceControlLoop(). This interrupt handler cycles through all analog inputs on the adc_channels_to_read Stack, @@ -191,6 +189,15 @@ inline void advanceADCStep() { } #endif +#else +MOZZI_ASSERT_EQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) + +int mozziAnalogRead(uint8_t pin) { + return analogRead(pin); +} + +#endif // MOZZI_ANALOG_READ + ////// END analog input code //////// @@ -202,7 +209,9 @@ inline void advanceControlLoop() { if (!update_control_counter) { update_control_counter = update_control_timeout; updateControl(); +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) adcStartReadCycle(); +#endif } else { --update_control_counter; } @@ -256,9 +265,10 @@ unsigned long mozziMicros() { return audioTicks() * MICROS_PER_AUDIO_TICK; } ////// BEGIN initialization /////// void startMozzi(int control_rate_hz) { +#if !MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) setupMozziADC(); // you can use setupFastAnalogRead() with FASTER_ADC or FASTEST_ADC // in setup() if desired (not for Teensy 3.* ) - setupFastAnalogRead(); +#endif // delay(200); // so AutoRange doesn't read 0 to start with update_control_timeout = MOZZI_AUDIO_RATE / control_rate_hz; startAudio(); diff --git a/MozziGuts_impl_AVR.hpp b/MozziGuts_impl_AVR.hpp index 90e6669f6..d4d670880 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/MozziGuts_impl_AVR.hpp @@ -19,7 +19,7 @@ #endif ////// BEGIN analog input code //////// -#define MOZZI_FAST_ANALOG_IMPLEMENTED +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) extern uint8_t analog_reference; #define getADCReading() ADC /* officially (ADCL | (ADCH << 8)) but the compiler works it out */ @@ -79,6 +79,14 @@ ISR(ADC_vect, ISR_BLOCK) advanceADCStep(); } +void setupMozziADC(int8_t speed) { + ADCSRA |= (1 << ADIE); // adc Enable Interrupt + adcDisconnectAllDigitalIns(); + setupFastAnalogRead(speed); +} + +#endif + void setupFastAnalogRead(int8_t speed) { if (speed == FAST_ADC){ // divide by 16 ADCSRA |= (1 << ADPS2); @@ -95,11 +103,6 @@ void setupFastAnalogRead(int8_t speed) { } } -void setupMozziADC(int8_t speed) { - ADCSRA |= (1 << ADIE); // adc Enable Interrupt - adcDisconnectAllDigitalIns(); -} - ////// END analog input code //////// diff --git a/MozziGuts_impl_ESP32.hpp b/MozziGuts_impl_ESP32.hpp index a5ef98ed8..8ecbc16ad 100644 --- a/MozziGuts_impl_ESP32.hpp +++ b/MozziGuts_impl_ESP32.hpp @@ -15,22 +15,24 @@ #endif ////// BEGIN analog input code //////// -//#define MOZZI_FAST_ANALOG_IMPLEMENTED // not yet +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) + +#error not yet implemented + #define getADCReading() 0 #define channelNumToIndex(channel) channel uint8_t adcPinToChannelNum(uint8_t pin) { return pin; } void adcStartConversion(uint8_t channel) { -#warning Fast analog read not implemented on this platform } void startSecondADCReadOnCurrentChannel() { -#warning Fast analog read not implemented on this platform -} -void setupFastAnalogRead(int8_t speed) { -#warning Fast analog read not implemented on this platform } void setupMozziADC(int8_t speed) { +} +#endif + +void setupFastAnalogRead(int8_t speed) { #warning Fast analog read not implemented on this platform } ////// END analog input code //////// diff --git a/MozziGuts_impl_template.hpp b/MozziGuts_impl_template.hpp index a478cf57e..159393ee8 100644 --- a/MozziGuts_impl_template.hpp +++ b/MozziGuts_impl_template.hpp @@ -40,14 +40,23 @@ ////// BEGIN analog input code //////// -/** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of USE_AUDIO_INPUT (if enabled). - * This template provides empty/dummy implementations to allow you to skip over this section, initially. Once you have an implementation, be sure to enable the - * #define, below: */ -//#define MOZZI_FAST_ANALOG_IMPLEMENTED +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) +/** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of MOZZI_AUDIO_INPUT (if enabled). + * + * It is possible, and even recommended, to skip over this section, initially, when starting a new port. Once you have an implementation, be sure to include something like this + * in your platform configuration checks: + * + * // analog reads shall be enabled by default on platforms that support it + * #if not defined(MOZZI_ANALOG_READ) + * #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD + * #endif + * + * The only function in this section that is always defined is setupFastAnalogRead() (but this, too, may be left empty, initially). + */ // Insert here code to read the result of the latest asynchronous conversion, when it is finished. // You can also provide this as a function returning unsigned int, should it be more complex on your platform -#define getADCReading() 0 +#define getADCReading() GET_MY_PLATFORM_ADC_REGISTER /** NOTE: On "pins" vs. "channels" vs. "indices" * "Pin" is the pin number as would usually be specified by the user in mozziAnalogRead(). @@ -69,25 +78,18 @@ uint8_t adcPinToChannelNum(uint8_t pin) { /** NOTE: Code needed to trigger a conversion on a new channel */ void adcStartConversion(uint8_t channel) { -#warning Fast analog read not implemented on this platform } /** NOTE: Code needed to trigger a subsequent conversion on the latest channel. If your platform has no special code for it, you should store the channel from * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */ void startSecondADCReadOnCurrentChannel() { -#warning Fast analog read not implemented on this platform -} - -/** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize. - * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */ -void setupFastAnalogRead(int8_t speed) { -#warning Fast analog read not implemented on this platform } /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and * possibly calibration. */ void setupMozziADC(int8_t speed) { -#warning Fast analog read not implemented on this platform + setupFastAnalogRead(speed); + // insert further custom code } /* NOTE: Most platforms call a specific function/ISR when conversion is complete. Provide this function, here. @@ -96,6 +98,15 @@ void stm32_adc_eoc_handler() { advanceADCStep(); } */ + +#endif + +/** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize. + * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */ +void setupFastAnalogRead(int8_t speed) { +#warning Fast analog read not implemented on this platform +} + ////// END analog input code //////// ////// BEGIN audio output code ////// diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index f17c9c3aa..7433e92a7 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -21,7 +21,7 @@ simple renames: - CONTROL_RATE: MOZZI_CONTROL_RATE all new - - MOZZI_ANALOG_READS + - MOZZI_ANALOG_READS -> allows to disable, explicitly - MOZZI_COMPATIBILITY_LEVEL general: diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 88f2e915e..84deb2a8f 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -34,7 +34,10 @@ #define MOZZI_CONTROL_RATE 64 #endif -//MOZZI_ANALOG_READ -> hardware specific +//MOZZI_ANALOG_READ -> hardware specific, but we want to insert a warning, if not supported, and user has not explicitly configured anything +#if not defined(MOZZI_ANALOG_READ) +#define MOZZI__ANALOG_READ_NOT_CONFIGURED +#endif #if not defined(MOZZI_AUDIO_INPUT) #define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_NONE @@ -93,6 +96,13 @@ MOZZI_CHECK_POW2(MOZZI_CONTROL_RATE) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC) MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) +#if defined(MOZZI__ANALOG_READ_NOT_CONFIGURED) +# if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) +# warning Asynchronous analog reads not implemented on this platform +# endif +# undef MOZZI__ANALOG_READ_NOT_CONFIGURED +#endif + /// Step 4: Init Read-only defines that depend on other values #if !defined(MOZZI_AUDIO_BIAS) #define MOZZI_AUDIO_BIAS ((uint16_t) 1<<(MOZZI_AUDIO_BITS-1)) diff --git a/internal/mozzi_macros.h b/internal/mozzi_macros.h index 51b157dbb..76c7f882d 100644 --- a/internal/mozzi_macros.h +++ b/internal/mozzi_macros.h @@ -43,4 +43,22 @@ */ #define MOZZI_IS(X, Y) (X == Y) +/** Short-hand for a compile time complaint, if the given define does not have the expected value. + * + * Use this to check - and clarify - complex nested logic inside #fidefs. + * + * Example: @code + * #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_STANDARD) + * [long difficult to read logic, with further nested #if's]] + * #else + * MOZZI_ASSERT_EQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_NONE) + * [more complex logic] + * #endif + * @endcode + */ +#define MOZZI_ASSERT_EQUAL(X, Y) static_assert(X == Y, "Internal error in #if-statement: " #X " != " #Y "."); + +/** See MOZZI_ASSERT_EQUAL, but reversed */ +#define MOZZI_ASSERT_NOTEQUAL(X, Y) static_assert(X != Y, "Internal error in #if-statement: " #X " == " #Y "."); + #endif diff --git a/mozzi_config.h b/mozzi_config.h index aaa21ce85..2319d5b8b 100644 --- a/mozzi_config.h +++ b/mozzi_config.h @@ -7,6 +7,7 @@ //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM //#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO +//#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE #include "internal/config_check_generic.h" From a23ae221633f222ec9021a401a20e9d3527bd9c2 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Wed, 15 Nov 2023 12:54:55 +0100 Subject: [PATCH 048/215] Compiles on ESP8266 --- AudioConfigESP.h | 43 ----------------------- MozziConfigExample.h | 58 ++++++++++++++++++++++++++++++-- MozziGuts_impl_ESP8266.hpp | 58 ++++++++++++++++---------------- hardware_defines.h | 4 +-- internal/config_check_generic.h | 2 ++ internal/config_checks_esp32.h | 4 +-- internal/config_checks_esp8266.h | 50 +++++++++++++++++++++++++++ internal/mozzi_macros.h | 24 ++++++++----- 8 files changed, 156 insertions(+), 87 deletions(-) delete mode 100644 AudioConfigESP.h create mode 100644 internal/config_checks_esp8266.h diff --git a/AudioConfigESP.h b/AudioConfigESP.h deleted file mode 100644 index b2c9855cd..000000000 --- a/AudioConfigESP.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef AUDIOCONFIGESP_H -#define AUDIOCONFIGESP_H - -#if not IS_ESP8266() -#error This header should be included for ESP architecture, only -#endif - -// AUDIO output modes. See README.md -#define PDM_VIA_I2S 1 -#define PDM_VIA_SERIAL 2 -#define EXTERNAL_DAC_VIA_I2S 3 // output via external DAC connected to I2S (PT8211 or similar) - -//******* BEGIN: These are the defines you may want to change. Best not to touch anything outside this range. ************/ -#define ESP_AUDIO_OUT_MODE PDM_VIA_SERIAL -#define PDM_RESOLUTION 2 // 1 corresponds to 32 PDM clocks per sample, 2 corresponds to 64 PDM clocks, etc. (and at some level you're going hit the hardware limits) -//******* END: These are the defines you may want to change. Best not to touch anything outside this range. ************/ - -#if (ESP_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S) -#define PDM_RESOLUTION 1 // DO NOT CHANGE THIS VALUE! Not actually PDM coded, but this define is useful to keep code simple. -#endif - -#if (AUDIO_MODE == HIFI) -#error HIFI mode is not available for this CPU architecture (but check ESP_AUDIO_OUT_MODE, and PDM_RESOLUTION) -#endif - -#if (AUDIO_CHANNELS > 1) -#if (ESP_AUDIO_OUT_MODE != EXTERNAL_DAC_VIA_I2S) -#error Stereo is not available for the configured audio output mode -#endif -#endif - -#if (ESP_AUDIO_OUT_MODE != PDM_VIA_SERIAL) -// NOTE: On ESP / output via I2S, we simply use the I2S buffer as the output -// buffer, which saves RAM, but also simplifies things a lot -// esp. since i2s output already has output rate control -> no need for a -// separate output timer -#define BYPASS_MOZZI_OUTPUT_BUFFER true -#endif - -#define AUDIO_BITS 16 -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) - -#endif // #ifndef AUDIOCONFIGESP_H diff --git a/MozziConfigExample.h b/MozziConfigExample.h index da22a21ca..32b57c79b 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -141,10 +141,11 @@ * disabled, explicitly, to save resources, or in order to implement custom read schemes (e.g. with IO multiplexing). * * For simplicity, mozziAnalogRead() is always defined, but when MOZZI_ANALOG_READ s are disabled or unsupported, it simply relays - * to Arduino's regular analogRead(). Also setupFastAnalogReads() continues to be defined, for your convenience, but is not called automatically. + * to Arduino's regular analogRead(). It is thus quite recommended _not_ to depend on mozziAnalogRead() when disabling this. + * Also setupFastAnalogReads() continues to be defined, for your convenience, but is not called automatically. * * As a rough estimate (your numbers may differ a bit, depending on compiler version, etc.), on an ATMEGA328P (aka Arduino Uno), - * disabling analog reads saves 33 bytes of RAM and 340 bytes of FLASH. The performance savings are theorized to be non-measurable, however. + * disabling analog reads saves 33 bytes of RAM and 340 bytes of FLASH. The performance savings are theorized to be neglegible, however. * * Currently allowed values are: * - MOZZI_ANALOG_READ_NONE @@ -430,3 +431,56 @@ * @section esp32_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM * See @ref external_audio */ + + +/***************************************** ADVANCED SETTTINGS -- ESP8266 *********************************************************** + * + * The settings in the following section applies to the ESP8266 architecture. + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + + +/** @ingroup hardware + * @page hardware_esp8266 Mozzi on ESP32-based boards. + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PDM_VIA_I2S + * - MOZZI_OUTPUT_PDM_VIA_SERIAL + * - MOZZI_OUTPUT_I2S_DAC + * + * The default mode is @ref esp8266_pdm_via_serial . + * + * @note + * This port really does not currently come with a PWM mode! + * + * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_SERIAL + * Output is coded using pulse density modulation, and sent via GPIO2 (Serial1 TX). + * - This output mode uses timer1 for queuing audio sample, so that timer is not available for other uses. + * - Note that this mode has slightly lower effective analog output range than @ref esp8266_pdm_via_i2s, due to start/stop bits being added to the output stream. + * - Supports mono output, only, pins not configurable. + * + * The option @ref MOZZI_PDM_RESOLTUON (default value 2, corresponding to 64 ones and zeros per audio sample) can be used to adjust the output resolution. + * Obviously higher values demand more computation power. + * + * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_I2S + * Output is coded using pulse density modulation, and sent via the I2S pins. The I2S data out pin (GPIO3, which is also "RX") will have the output, + * but *all* I2S output pins (RX, GPIO2 and GPIO15) will be affected. Mozzi tries to set GPIO2 and GPIO15 to input mode, and *at the time of this writing*, this allows + * I2S output on RX even on boards such as the ESP01 (where GPIO15 is tied to Ground). However, it seems safest to assume that this mode may not be useable on boards where + * GPIO2 or GPIO15 are not available as output pins. + * + * Supports mono output, only, pins not configurable. + * + * Resolution may be controlled using MOZZI_PDM_RESOLUTION (see above; default value is 2). + * + * @section esp8266_i2s_dac MOZZI_OUTPUT_I2S_DAC + * Output is sent to an external DAC (such as a PT8211), digitally coded. This is the only mode that supports stereo (@ref MOZZI_AUDIO_CHANNELS). It also needs the least processing power. + * The pins cannot be configured (GPIO3/RX, GPIO2, and GPIO15). + * + * @section esp8266_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ diff --git a/MozziGuts_impl_ESP8266.hpp b/MozziGuts_impl_ESP8266.hpp index c9f925b9f..6c8ca63f2 100644 --- a/MozziGuts_impl_ESP8266.hpp +++ b/MozziGuts_impl_ESP8266.hpp @@ -15,22 +15,22 @@ #endif ////// BEGIN analog input code //////// -//#define MOZZI_FAST_ANALOG_IMPLEMENTED // not yet +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) +#error not yet implemented + #define getADCReading() 0 #define channelNumToIndex(channel) channel uint8_t adcPinToChannelNum(uint8_t pin) { return pin; } void adcStartConversion(uint8_t channel) { -#warning Fast analog read not implemented on this platform } void startSecondADCReadOnCurrentChannel() { -#warning Fast analog read not implemented on this platform -} -void setupFastAnalogRead(int8_t speed) { -#warning Fast analog read not implemented on this platform } void setupMozziADC(int8_t speed) { +} +#endif +void setupFastAnalogRead(int8_t speed) { #warning Fast analog read not implemented on this platform } ////// END analog input code //////// @@ -44,55 +44,55 @@ void setupMozziADC(int8_t speed) { #include uint16_t output_buffer_size = 0; -#if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user -# include "AudioConfigESP.h" +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC) // i.e. not external -# if (ESP_AUDIO_OUT_MODE == PDM_VIA_I2S) +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) # include inline bool canBufferAudioOutput() { - return (i2s_available() >= PDM_RESOLUTION); + return (i2s_available() >= MOZZI_PDM_RESOLUTION); } inline void audioOutput(const AudioOutput f) { - for (uint8_t words = 0; words < PDM_RESOLUTION; ++words) { - i2s_write_sample(pdmCode32(f.l()+AUDIO_BIAS)); + for (uint8_t words = 0; words < MOZZI_PDM_RESOLUTION; ++words) { + i2s_write_sample(pdmCode32(f.l()+MOZZI_AUDIO_BIAS)); } } -# elif (ESP_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S) +# elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) # include inline bool canBufferAudioOutput() { - return (i2s_available() >= PDM_RESOLUTION); + return (i2s_available() >= MOZZI_PDM_RESOLUTION); } inline void audioOutput(const AudioOutput f) { i2s_write_lr(f.l(), f.r()); // Note: i2s_write expects zero-centered output } -# else // (ESP_AUDIO_OUT_MODE == PDM_VIA_SERIAL) +# else +MOZZI_ASSERT_EQUAL(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL) // NOTE: This intermediate step is needed because the output timer is running at a rate higher than AUDIO_RATE, and we need to rely on the (tiny) // serial buffer itself to achieve appropriate rate control void CACHED_FUNCTION_ATTR esp8266_serial_audio_output() { // Note: That unreadble mess is an optimized version of Serial1.availableForWrite() - while ((UART_TX_FIFO_SIZE - ((U1S >> USTXC) & 0xff)) > (PDM_RESOLUTION * 4)) { + while ((UART_TX_FIFO_SIZE - ((U1S >> USTXC) & 0xff)) > (MOZZI_PDM_RESOLUTION * 4)) { defaultAudioOutput(); } } inline void audioOutput(const AudioOutput f) { // optimized version of: Serial1.write(...); - for (uint8_t i = 0; i < PDM_RESOLUTION*4; ++i) { - U1F = pdmCode8(f+AUDIO_BIAS); + for (uint8_t i = 0; i < MOZZI_PDM_RESOLUTION*4; ++i) { + U1F = pdmCode8(f+MOZZI_AUDIO_BIAS); } } # endif #endif static void startAudio() { -#if (EXTERNAL_AUDIO_OUTPUT == true) && (BYPASS_MOZZI_OUTPUT_BUFFER != true) // for external audio output, set up a timer running a audio rate +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // for external audio output, set up a timer running a audio rate timer1_isr_init(); timer1_attachInterrupt(defaultAudioOutput); timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP); - timer1_write(F_CPU / AUDIO_RATE); -#elif (ESP_AUDIO_OUT_MODE == PDM_VIA_SERIAL) + timer1_write(F_CPU / MOZZI_AUDIO_RATE); +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL) Serial1.begin( - AUDIO_RATE * (PDM_RESOLUTION * 40), SERIAL_8N1, + MOZZI_AUDIO_RATE * (MOZZI_PDM_RESOLUTION * 40), SERIAL_8N1, SERIAL_TX_ONLY); // Note: PDM_RESOLUTION corresponds to packets of 32 // encoded bits However, the UART (unfortunately) adds a // start and stop bit each around each byte, thus sending @@ -105,15 +105,15 @@ static void startAudio() { // interval to the time needed to write half of that. PDM_RESOLUTION * 4 bytes // per sample written. timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP); - timer1_write(F_CPU / (AUDIO_RATE * PDM_RESOLUTION)); + timer1_write(F_CPU / (MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION)); #else i2s_begin(); -# if (ESP_AUDIO_OUT_MODE == PDM_VIA_I2S) +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) pinMode(2, INPUT); // Set the two unneeded I2S pins to input mode, to reduce // side effects pinMode(15, INPUT); # endif - i2s_set_rate(AUDIO_RATE * PDM_RESOLUTION); + i2s_set_rate(MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION); if (output_buffer_size == 0) output_buffer_size = i2s_available(); // Do not reset count when stopping / restarting @@ -122,16 +122,16 @@ static void startAudio() { void stopMozzi() { -#if (ESP_AUDIO_OUT_MODE != PDM_VIA_SERIAL) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC) i2s_end(); -#else +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_EXTERNAL_TIMED) timer1_disable(); #endif interrupts(); } -#if ((ESP_AUDIO_OUT_MODE == PDM_VIA_I2S) && (PDM_RESOLUTION != 1)) -# define AUDIOTICK_ADJUSTMENT ((output_buffer_size - i2s_available()) / PDM_RESOLUTION) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) && (MOZZI_PDM_RESOLUTION != 1) +# define AUDIOTICK_ADJUSTMENT ((output_buffer_size - i2s_available()) / MOZZI_PDM_RESOLUTION) #else # define AUDIOTICK_ADJUSTMENT (output_buffer_size - i2s_available()) #endif diff --git a/hardware_defines.h b/hardware_defines.h index 3a5768960..9db53b0af 100644 --- a/hardware_defines.h +++ b/hardware_defines.h @@ -105,9 +105,7 @@ #define NUM_ANALOG_INPUTS 1 #endif -#if IS_ESP8266() -#define CACHED_FUNCTION_ATTR ICACHE_RAM_ATTR -#elif IS_ESP32() +#if IS_ESP8266() || IS_ESP32() #define CACHED_FUNCTION_ATTR IRAM_ATTR #else #define CACHED_FUNCTION_ATTR diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 84deb2a8f..5157d3d74 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -59,6 +59,8 @@ #include "config_checks_avr.h" #elif IS_ESP32() #include "config_checks_esp32.h" +#elif IS_ESP8266() +#include "config_checks_esp8266.h" #else // TODO #error oops diff --git a/internal/config_checks_esp32.h b/internal/config_checks_esp32.h index 490285333..47d91f442 100644 --- a/internal/config_checks_esp32.h +++ b/internal/config_checks_esp32.h @@ -25,7 +25,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) -#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_PDM_VIA_I2S) # if !defined(MOZZI_I2S_PIN_BCK) # define MOZZI_I2S_PIN_BCK 26 # endif @@ -37,7 +37,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) # endif #endif -#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_PDM_VIA_I2S) # include # if !defined(MOZZI_IS2_PORT) # define MOZZI_I2S_PORT I2S_NUM_0 diff --git a/internal/config_checks_esp8266.h b/internal/config_checks_esp8266.h new file mode 100644 index 000000000..7cc06901f --- /dev/null +++ b/internal/config_checks_esp8266.h @@ -0,0 +1,50 @@ +#ifndef CONFIG_CHECK_ESP8266_H +#define CONFIG_CHECK_ESP8266_H + + +#if not IS_ESP8266() +#error This header should be included for ESP architecture, only +#endif + +#if !defined(MOZZI_AUDIO_MODE) +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PDM_VIA_SERIAL +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC) + +#if !defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 32768 +#endif + +#if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 16 +#endif + +#if !defined(MOZZI_ANALOG_READ) +# define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE +#endif + +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL) +# if !defined(PDM_RESOLUTION) +# define MOZZI_PDM_RESOLUTION 2 +# endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16) +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) +# define MOZZI_PDM_RESOLUTION 1 // DO NOT CHANGE THIS VALUE! Not actually PDM coded, but this define is useful to keep code simple. +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16) +#endif + +#define PDM_RESOLUTION 2 // 1 corresponds to 32 PDM clocks per sample, 2 corresponds to 64 PDM clocks, etc. (and at some level you're going hit the hardware limits) + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC) +// NOTE: On ESP / output via I2S, we simply use the I2S buffer as the output +// buffer, which saves RAM, but also simplifies things a lot +// esp. since i2s output already has output rate control -> no need for a +// separate output timer +#define BYPASS_MOZZI_OUTPUT_BUFFER true +#endif + +#endif // #ifndef CONFIG_CHECK_ESP8266_H diff --git a/internal/mozzi_macros.h b/internal/mozzi_macros.h index 76c7f882d..cbd021d97 100644 --- a/internal/mozzi_macros.h +++ b/internal/mozzi_macros.h @@ -5,7 +5,7 @@ // internal dummy that should be distinct from any valid config value -#define MOZZI__INVALID_CONFIG_VALUE 9999976543 +#define MOZZI__INVALID_CONFIG_VALUE 9999976543210 // internal implementation of MOZZI_CHECK_SUPPORTED #define MOZZI__CHECK_SUPPORTED(X, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, ...) \ @@ -30,18 +30,26 @@ /** Compile time check to complain if the given argument is not a power of two */ #define MOZZI_CHECK_POW2(X) static_assert((X & (X - 1)) == 0, #X " must be a power of two"); -/** Simply a way to check if X equal Y, realiably (at compile time). The advantage of this macro is that it will produce an error, in case one or both are defined empty - * (such as because of a programmer's typo) +#define MOZZI__IS(X, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, ...) \ + ((X == A0) || (X == A1) || (X == A2) || (X == A3) || (X == A4) || (X == A5) || (X == A6) || (X == A7) || (X == A8) || (X == A9) || (X == B0) || (X == B1) || (X == B2) || (X == B3) || (X == B4) || (X == B5) || (X == B6) || (X == B7) || (X == B8) || (X == B9)) +/** Short-hand to check if given first value is any of the following values (up to 20). * - * TODO: Gahh, this doesn't work. I thought it did. + * (Orgignally, this macro was intended to also produce an error, should any of the values be non-defined (such as because it's a typo), but alas, the preprocessor would + * let me have that). * * Example: @code - * #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) + * #if MOZZI_IS_ANY(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) * [...] * #endif * @endcode + * + * See also @ref MOZZI_CHECK_SUPPORTED, which throws an error, if the first value is not among the latter values. */ -#define MOZZI_IS(X, Y) (X == Y) +#define MOZZI_IS(X, ...) MOZZI__MACRO_EVAL(MOZZI__IS(X, __VA_ARGS__, \ + MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ + MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ + MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ + MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE)) /** Short-hand for a compile time complaint, if the given define does not have the expected value. * @@ -56,9 +64,9 @@ * #endif * @endcode */ -#define MOZZI_ASSERT_EQUAL(X, Y) static_assert(X == Y, "Internal error in #if-statement: " #X " != " #Y "."); +#define MOZZI_ASSERT_EQUAL(X, Y) static_assert(X == Y, "Internal error in preprocessor logic: " #X " != " #Y "."); /** See MOZZI_ASSERT_EQUAL, but reversed */ -#define MOZZI_ASSERT_NOTEQUAL(X, Y) static_assert(X != Y, "Internal error in #if-statement: " #X " == " #Y "."); +#define MOZZI_ASSERT_NOTEQUAL(X, Y) static_assert(X != Y, "Internal error in preprocessor logic: " #X " == " #Y "."); #endif From 4a960337dadba2cc7b9a98fa994ad707d72a1802 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Wed, 15 Nov 2023 22:46:24 +0100 Subject: [PATCH 049/215] Document output modes & options for all remaining architectures Start porting STM32duino. --- MozziConfigExample.h | 384 ++++++++++++++++++ internal/config_check_generic.h | 2 + .../config_checks_stm32duino.h | 29 +- 3 files changed, 410 insertions(+), 5 deletions(-) rename AudioConfigSTM32duino.h => internal/config_checks_stm32duino.h (75%) diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 32b57c79b..0f94686dd 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -484,3 +484,387 @@ * @section esp8266_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM * See @ref external_audio */ + + + +/***************************************** ADVANCED SETTTINGS -- Arduino Giga/Portenta MBED *********************************************************** + * + * The settings in the following section applies to Arduino Giga/Portenta (MBED architecture) + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + + +/** @ingroup hardware + * @page hardware_mbed Mozzi on MBED-based boards (Arduino Giga / Portenta). + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PDM_VIA_SERIAL + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref mbed_internal_dac . + * + * @section mbed_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * This uses the inbuild DAC on the board. The default is setting is appropriate for the Arduino Giga: 12 bits going to A13 (3.5mm jack connector's tip), + * and in stereo mode to pin A12 (3.5mm jack connector's first ring) additionally. + * + * For other boards is may be appropriate to customize: + * @code + * #define MOZZI_AUDIO_PIN_1 ... // mono / left channel; default: A13 + * #define MOZZI_AUDIO_PIN_1 ... // stereo only: right channel; default: A12 + * #define MOZZI_AUDIO_BITS ... // default is 12 + * @endcode + * + * @section mbed_pdm_via_serial MOZZI_PDM_VIA_SERIAL + * Returns a pulse-density modulated (mono only) signal on one of the hardware UARTs of the board (Serial ports). Default is using the SERIAL2, on pin D18. + * You can confiugre the pins to use, but it must be connected to a hardware UART. Output is written to the TX pin, only, but the RX pin needs to be + * claimed as well. Beware of confusing pinout labelling, for instance SERIAL2_TX iss labelled "TX1" on the Arduino Giga. The audio resolution can be enhanced + * using @ref MOZZI_PDM_RESOLUTION, which is described in more detail here: @esp32_pdm_via_i2s . + * + * Configuration options: + * @code + * #define MOZZI_SERIAL_PIN_TX ... // default: SERIAL2_TX + * #define MOZZI_SERIAL_PIN_RX ... // *must* specify the matching one, if customizing the above; default: SERIAL2_RX + * #define MOZZI_PDM_RESOLUTION ... // default value is 2, for 2*32 ones and zeros per audio sample + * @endcode + * + * @section mbed_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + + +/***************************************** ADVANCED SETTTINGS -- Arduino Uno R4 - Renesas *********************************************************** + * + * The settings in the following section applies to Arduino Uno R4 - Renesas + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + + +/** @ingroup hardware + * @page hardware_renesas Mozzi on Arduino Uno R4 - Renesas. + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref renesas_internal_dac. Further modes may be added in the future. + - Because this board has an on-board DAC (A0), but only one, STEREO is not implemented and Mozzi uses this pin. Usage of other pins using PWM for instance is not implemented yet. + - Two timers are claimed by Mozzi when using the on-board DAC, one when using `EXTERNAL_AUDIO_OUTPUT`. + - `mozziAnalogRead()` returns values in the Renesas' full ADC resolution of 0-16384 rather than AVR's 0-1023. *This might change in the near future for speed purposes.* + + * @section renesas_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * This uses the inbuild DAC on the board on pin A0. Mono output only, and the pin is not configurable. Audio resolution is also fixed at 12 bits (which is what the board supports). + * + * This mode claims two timers (but it is not hardcoded, which ones). + * + * @section renesas_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * MOZZI_OUTPUT_EXTERNAL_TIMED claimes one timer, MOZZI_OUTPUT_EXTERNAL_CUSTOM does not claim any timer. + * See @ref external_audio +*/ + + + + +/***************************************** ADVANCED SETTTINGS -- RP2040 (Raspberry Pi Pico) *********************************************************** + * + * The settings in the following section applies to RP2040 (Raspberry Pi Pico) + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + + +/** @ingroup hardware + * @page hardware_rp2040 Mozzi on RP2040 (Raspberry Pi Pico) + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PDM + * - MOZZI_OUTPUT_I2S_DAC + * + * The default mode is @ref rp2040_pdm . + * + * @section rp2040_pdm MOZZI_OUTPUT_PDM + * Audio output is written to pin 0 (mono) or 0 and 1 (stereo), by default, with 11 bits of ouput resolution. + * One hardware timer interrupt and one DMA channel are claimed (number not hardcoded), a non-exclusive handler is installed on DMA_IRQ_0. + * + * Configuration options: + * @code + * #define MOZZI_AUDIO_PIN_1 ... // default is 0 + * #define MOZZI_AUDIO_BITS ... // output resolution (bits); default is 11 + * // additionally, for stereo: + * #define MOZZI_AUDIO_PIN_2 ... // default is 1 + * @endcode + * + * @section rp2040_i2s_dac MOZZI_OUTPUT_I2S_DAC + * Output to an external DAC, connected via I2S. This uses 16 bit (per audio channel), but can be changed to 8, 16, 24 (left aligned) and 32 resolution. + * Both plain I2S and LSBJ format (PT8211 needs this, for instance) are available. LSBJ format is used by default. The GPIO pins to use can be configured, + * - almost - freely (see below). Two DMA channels are claimed (numbers not hardcoded), non-exclusive handlers are installed on DMA_IRQ_0. + * + * Configuration options: + * @code + * #define MOZZI_AUDIO_BITS ... // available values are 8, 16 (default), 24 (LEFT ALIGN in 32 bits type!!) and 32 bits + * #define MOZZI_I2S_PIN_BCK ... // /BLCK) default is 20 + * //#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) ... // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21 + * #define MOZZI_I2S_PIN_DATA ... // (DOUT) default is 22 + * #define MOZZI_I2S_FORMAT ... // may be MOZZI_I2S_FORMAT_LSBJ (default) or MOZZI_I2S_FORMAT_PLAIN + * @endcode + * + * @section rp2040_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + + + +/***************************************** ADVANCED SETTTINGS -- SAMD21 *********************************************************** + * + * The settings in the following section applies to SAMD21 boards + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + +/** @ingroup hardware + * @page hardware_samd Mozzi on SAMD21 based boards (Arduino Circuitplayground M0 and others) + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref samd_internal_dac , meaning, only boards with an inbuilt DAC are covered by default + * (you could stil use one of the external output modes, however). + * + * @section samd_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * Output resolution is 10 bits by default, and goes to pin DAC0. Only mono output is supported. Within the hardware limits of your board, you can configure the following: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // default is DAC0 + * #define MOZZI_AUDIO_BITS ... // default is 10 + * @endcode + * + * @section samd_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + + + + +/***************************************** ADVANCED SETTTINGS -- STM32(duino) *********************************************************** + * + * The settings in the following section applies to the STM32(duino) architecture. + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + +/** @ingroup hardware +* @page hardware_stm32_disambiguation Mozzi on STM32-based boards - disambiguation +* +* * The situation on STM32-based boards is rather confusing, as there are several competing Arduino cores. Importantly: +* - Some boards use dedicated cores (e.g. Arduino Giga / Portenta @ref hardware_mbed) etc. For those, see the relevant sections (if we support them). +* - There is a series of libmaple-based cores, including [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32). These are highly optimized, +* and provide very complete support, but only for a limited number of boards. Unfortunately, at the time of this writing (2023/04), they are not available for installation +* via the Arduino Board Manager, and they do not currently seem actively maintained. +* For using these with Mozzi, see @ref hardware_stm32_maple +* - A generic Arduino core for STM32 is the [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32). It supports a huge step of boards, and seems to have offical +* backing by STM, but some features of the libmaple based cores are still lacking. To complete confusion, this core now uses the label "STM32duino", which used to be what +* the libmaple cores above were known by (don't blame Mozzi for this mess!). +* For using this with Mozzi, see @ref hardware_stm32duino +* +* */ + +/** @ingroup hardware + * @page hardware_stm32duino Mozzi on STM32duino-based boards. + * + * @note + * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32duino core. + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PWM + * - MOZZI_OUTPUT_PWM_2PIN + * + * The default mode is @ref stm32duino_pwm . + * + * @note + * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32_maple ! + * + * @section stm32duino_pwm MOZZI_OUTPUT_PWM + * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PA8 (mono/left), PA9 (right channel in stereo). + * This mode uses two hardware timers: One for the PWM (Timer 3 when using the default pin configuration), and a second for updating the output at audio rate. + * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this. + * The following settings may be costumized, if desired: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PA8 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 + * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10 + * // For stereo, only: + * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PA9 + * @endcode + * + * @section stm32duino_pwm MOZZI_OUTPUT_2PIN_PWM + * This mode is very similar to @ref stm32duino_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required + * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode. + * + * Customizable configuration options: + * @code + * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PA8 + * #define MOZZI_AUDIO_PIN_2 ... // Low byte of the output. Default: PA9 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 + * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7 + * @endcode + * + * @section stm32duino_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio . + * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2). +*/ + + + +/***************************************** ADVANCED SETTTINGS -- STM32 (libmaple-based core) *********************************************************** + * + * The settings in the following section applies to the STM32 (libmaple-based core) architecture. + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + +/** @ingroup hardware + * @page hardware_stm32_maple Mozzi on STM32duino-based boards. + * + * @note + * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32 "libmaple based" core. + * + * @note + * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32duino ! + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PWM + * - MOZZI_OUTPUT_PWM_2PIN + * + * The default mode is @ref stm32_maple_pwm . + * + * @section stm32_maple_pwm MOZZI_OUTPUT_PWM + * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PB8 (mono/left), PB9 (right channel in stereo). + * This mode uses two hardware timers: One for the PWM (Timer 4 when using the default pin configuration), and a second for updating the output at audio rate. + * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this. + * The following settings may be costumized, if desired: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PA8 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 + * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10 + * // For stereo, only: + * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PA9 + * @endcode + * + * @section stm32_maple_pwm MOZZI_OUTPUT_2PIN_PWM + * This mode is very similar to @ref stm32_maple_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required + * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode. + * + * Customizable configuration options: + * @code + * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PB8 + * #define MOZZI_AUDIO_PIN_2 ... // Low byte of the output. Default: PB9 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 + * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7 + * @endcode + * + * @section stm32_maple_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio + * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2). +*/ + + +/***************************************** ADVANCED SETTTINGS -- Teensy 3.x *********************************************************** + * + * The settings in the following section applies to Teensy 3.x boards + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + +/** @ingroup hardware + * @page hardware_teensy3 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards. + * + * @note + * For Teensy 4.x see @ref hardware_teensy4 + * + * @note + * This port requires the following two libraries (which should be part of a default installtion, however): + * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 3.* by Daniel Gilbert + * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref teensy3_internal_dac . + * + * @section teensy3_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * Output is to the inbuilt DAC on pin 14/DAC. The pinout is not configurable. Output resolution is 12 bits. + * + * @section teensy3_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + +/***************************************** ADVANCED SETTTINGS -- Teensy 4.x *********************************************************** + * + * The settings in the following section applies to Teensy 4.x boards + * + * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or + * are willing to rough it out by yourself. + * +********************************************************************************************************************************/ + +/** @ingroup hardware + * @page hardware_teensy4 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards. + * + * @note + * For Teensy 3.x see @ref hardware_teensy3 + * + * @note + * This port requires the following two libraries (which should be part of a default installtion, however): + * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 4.* by Daniel Gilbert + * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PWM + * + * The default mode is @ref teensy4_pwm . + * + * @section teensy4_pwm MOZZI_OUTPUT_INTERNAL_DAC + * Output is to a GPIO pin (or two in stereo). The output resolution is fixed at 10 bits, and a 146484 kHz carrier frequency. + * The output pins can be configured as: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: A8 + * // For stereo, only: + * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. Default: A9 + * @endcode + * + * @section teensy4_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 5157d3d74..97f87f164 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -61,6 +61,8 @@ #include "config_checks_esp32.h" #elif IS_ESP8266() #include "config_checks_esp8266.h" +#elif IS_STM32DUINO() +#include "config_checks_stm32duino.h" #else // TODO #error oops diff --git a/AudioConfigSTM32duino.h b/internal/config_checks_stm32duino.h similarity index 75% rename from AudioConfigSTM32duino.h rename to internal/config_checks_stm32duino.h index 4494f76b2..61b0fe90a 100644 --- a/AudioConfigSTM32duino.h +++ b/internal/config_checks_stm32duino.h @@ -1,10 +1,31 @@ -#ifndef AUDIOCONFIGSTM32_H -#define AUDIOCONFIGSTM32_H +#ifndef CONFIG_CHECKS_STM32DUINO_H +#define CONFIG_CHECKS_STM32DUINO_H #if not IS_STM32DUINO() #error This header should be included for STM32 (stm32duino.com core), only #endif +#if !defined(MOZZI_AUDIO_MODE) +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) + +#if !defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 32768 +#endif + + + + + + + + + +#if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 16 +#endif + // Audio output pin. If you want to change this, make sure to also set AUDIO_PWM_TIMER to whichever timer is responsible for your PWM pin, and set the other timers to non-conflicting values #define AUDIO_CHANNEL_1_PIN PA8 // Note: PB8 does not appear to be available as a PWM pin with this core. // The timer used for running the audio update loop. This must _not_ be the same timer responsible for PWM on the output pins! NOTE: Timer 3 appears to clash with SPI DMA transfers under some circumstances @@ -27,7 +48,5 @@ #endif #endif -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) - -#endif // #ifndef AUDIOCONFIGSTM32_H +#endif // #ifndef CONFIG_CHECKS_STM32DUINO_H From 2cd43160b1f77790185450e62edbfc692fd57e31 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 16 Nov 2023 22:13:44 +0100 Subject: [PATCH 050/215] STM32duino compiles --- MozziConfigExample.h | 4 +- MozziGuts_impl_STM32duino.hpp | 74 ++++++++++++++++------------- internal/config_checks_stm32duino.h | 63 ++++++++++++------------ mozzi_pgmspace.h | 4 +- 4 files changed, 76 insertions(+), 69 deletions(-) diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 0f94686dd..a7add776d 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -711,7 +711,7 @@ * * @code * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PA8 - * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim, must not be the same of the timer for the above pin. Default TIM2 * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10 * // For stereo, only: * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PA9 @@ -724,7 +724,7 @@ * Customizable configuration options: * @code * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PA8 - * #define MOZZI_AUDIO_PIN_2 ... // Low byte of the output. Default: PA9 + * #define MOZZI_AUDIO_PIN_1_LOW ... // Low byte of the output. Default: PA9 * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7 * @endcode diff --git a/MozziGuts_impl_STM32duino.hpp b/MozziGuts_impl_STM32duino.hpp index aca71c978..b24f5a749 100644 --- a/MozziGuts_impl_STM32duino.hpp +++ b/MozziGuts_impl_STM32duino.hpp @@ -14,8 +14,7 @@ ////// BEGIN analog input code //////// -#define MOZZI_FAST_ANALOG_IMPLEMENTED - +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) // Notes on ADC implementation: So in hours I could not get IRQ-driven ADC to work, much less in a way that should work across the whole STM32 family. // Instead, this code resorts to polling, but contrary to the regular implementation, it sets does so non-blocking. Polling is done from inside audioHook(). // Not terribly efficient, but seems to work ok. @@ -61,9 +60,6 @@ void startSecondADCReadOnCurrentChannel() { conversion_running = true; } -void setupFastAnalogRead(int8_t /*speed*/) { -} - void setupMozziADC(int8_t /*speed*/) { } @@ -77,47 +73,52 @@ void checkADCConversionComplete() { } } +#endif + +void setupFastAnalogRead(int8_t /*speed*/) { +} + ////// END analog input code //////// ////// END analog input code //////// //// BEGIN AUDIO OUTPUT code /////// -#if (EXTERNAL_AUDIO_OUTPUT == true) -HardwareTimer audio_update_timer(TIM2); -#else -HardwareTimer audio_update_timer(AUDIO_UPDATE_TIMER); +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) +HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER); +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) +HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER); HardwareTimer *pwm_timer_ht; -PinName output_pin_1 = digitalPinToPinName(AUDIO_CHANNEL_1_PIN); +PinName output_pin_1 = digitalPinToPinName(MOZZI_AUDIO_PIN_1); uint32_t pwm_timer_channel_1 = STM_PIN_CHANNEL(pinmap_function(output_pin_1, PinMap_TIM)); -# if (AUDIO_MODE == HIFI) -PinName output_pin_1_high = digitalPinToPinName(AUDIO_CHANNEL_1_PIN_HIGH); -uint32_t pwm_timer_channel_1_high = STM_PIN_CHANNEL(pinmap_function(output_pin_1_high, PinMap_TIM)); -# elif (AUDIO_CHANNELS > 1) -PinName output_pin_2 = digitalPinToPinName(AUDIO_CHANNEL_2); +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) +PinName output_pin_1_low = digitalPinToPinName(MOZZI_AUDIO_PIN_1_LOW); +uint32_t pwm_timer_channel_1_low = STM_PIN_CHANNEL(pinmap_function(output_pin_1_low, PinMap_TIM)); +# elif (MOZZI_AUDIO_CHANNELS > 1) +PinName output_pin_2 = digitalPinToPinName(MOZZI_AUDIO_PIN_2); uint32_t pwm_timer_channel_2 = STM_PIN_CHANNEL(pinmap_function(output_pin_2, PinMap_TIM)); # endif -#include "AudioConfigSTM32.h" inline void audioOutput(const AudioOutput f) { -# if (AUDIO_MODE == HIFI) - pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, (f.l()+AUDIO_BIAS) & ((1 << AUDIO_BITS_PER_CHANNEL) - 1)); - pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1_high, (f.l()+AUDIO_BIAS) >> AUDIO_BITS_PER_CHANNEL); +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) + pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_CHANNEL); + pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1_low, (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1)); # else - pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, f.l()+AUDIO_BIAS); -# if (AUDIO_CHANNELS > 1) - pwm_timer_ht->setCaptureCompare(pwm_timer_channel_2, f.r()+AUDIO_BIAS); + pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, f.l()+MOZZI_AUDIO_BIAS); +# if (MOZZI_AUDIO_CHANNELS > 1) + pwm_timer_ht->setCaptureCompare(pwm_timer_channel_2, f.r()+MOZZI_AUDIO_BIAS); # endif #endif } #endif static void startAudio() { +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) audio_update_timer.pause(); //audio_update_timer.setPeriod(1000000UL / AUDIO_RATE); // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors - uint32_t period_cyc = F_CPU / AUDIO_RATE; + uint32_t period_cyc = F_CPU / MOZZI_AUDIO_RATE; uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1); uint16_t overflow = (uint16_t)((period_cyc + (prescaler / 2)) / prescaler); audio_update_timer.setPrescaleFactor(prescaler); @@ -126,42 +127,47 @@ static void startAudio() { audio_update_timer.setCaptureCompare(/* channel */ 1, 1); // Interrupt 1 count after each update audio_update_timer.attachInterrupt(/* channel */ 1, defaultAudioOutput); audio_update_timer.refresh(); +#endif -#if (EXTERNAL_AUDIO_OUTPUT != true) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) // Configure PWM output - pinMode(AUDIO_CHANNEL_1_PIN, OUTPUT); -# if (AUDIO_MODE == HIFI) - pinMode(AUDIO_CHANNEL_1_PIN_HIGH, OUTPUT); -# elif (AUDIO_CHANNELS > 1) - pinMode(AUDIO_CHANNEL_2_PIN, OUTPUT); + pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) + pinMode(MOZZI_AUDIO_PIN_1_LOW, OUTPUT); +# elif (MOZZI_AUDIO_CHANNELS > 1) + pinMode(MOZZI_AUDIO_PIN_2, OUTPUT); # endif -# define MAX_CARRIER_FREQ (F_CPU / (1 << AUDIO_BITS_PER_CHANNEL)) +# define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL)) // static_assert(MAX_CARRIER_FREQ >= AUDIO_RATE); // Unfortunately, we cannot test this at compile time. F_CPU expands to a runtime variable TIM_TypeDef *pwm_timer_tim = (TIM_TypeDef *) pinmap_peripheral(output_pin_1, PinMap_TIM); pwm_timer_ht = new HardwareTimer(pwm_timer_tim); pwm_timer_ht->setMode(pwm_timer_channel_1, TIMER_OUTPUT_COMPARE_PWM1, output_pin_1); -# if MAX_CARRIER_FREQ < (AUDIO_RATE * 5) +# if MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 5) // Generate as fast a carrier as possible pwm_timer_ht->setPrescaleFactor(1); # else // No point in generating arbitrarily high carrier frequencies. In fact, if // there _is_ any headroom, give the PWM pin more time to swing from HIGH to // LOW and BACK, cleanly - pwm_timer_ht->setPrescaleFactor((int)MAX_CARRIER_FREQ / (AUDIO_RATE * 5)); // as fast as possible + pwm_timer_ht->setPrescaleFactor((int)MAX_CARRIER_FREQ / (MOZZI_AUDIO_RATE * 5)); // as fast as possible # endif // Allocate enough room to write all intended bits - pwm_timer_ht->setOverflow(1 << AUDIO_BITS_PER_CHANNEL); - pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, AUDIO_BIAS /*, resolution */); + pwm_timer_ht->setOverflow(1 << MOZZI_AUDIO_BITS_PER_CHANNEL); + pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, MOZZI_AUDIO_BIAS /*, resolution */); pwm_timer_ht->resume(); #endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) audio_update_timer.resume(); +#endif } void stopMozzi() { +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) audio_update_timer.pause(); +#endif } //// END AUDIO OUTPUT code /////// diff --git a/internal/config_checks_stm32duino.h b/internal/config_checks_stm32duino.h index 61b0fe90a..5fc06d365 100644 --- a/internal/config_checks_stm32duino.h +++ b/internal/config_checks_stm32duino.h @@ -6,46 +6,47 @@ #endif #if !defined(MOZZI_AUDIO_MODE) -#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM +# define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM #endif MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) #if !defined(MOZZI_AUDIO_RATE) -#define MOZZI_AUDIO_RATE 32768 +# define MOZZI_AUDIO_RATE 32768 #endif - - - - - - - - -#if !defined(MOZZI_AUDIO_BITS) -# define MOZZI_AUDIO_BITS 16 +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) +# if !defined(MOZZI_AUDIO_UPDATE_TIMER) +# define MOZZI_AUDIO_UPDATE_TIMER TIM2 +# endif #endif -// Audio output pin. If you want to change this, make sure to also set AUDIO_PWM_TIMER to whichever timer is responsible for your PWM pin, and set the other timers to non-conflicting values -#define AUDIO_CHANNEL_1_PIN PA8 // Note: PB8 does not appear to be available as a PWM pin with this core. -// The timer used for running the audio update loop. This must _not_ be the same timer responsible for PWM on the output pins! NOTE: Timer 3 appears to clash with SPI DMA transfers under some circumstances -#define AUDIO_UPDATE_TIMER TIM2 - -#if (AUDIO_MODE == HIFI) -// Second out pin for HIFI mode. This must be on the same timer as AUDIO_CHANNEL_1_PIN! -// Note that by default we are not using adjacent pins. This is to leave the "Serial1" pins available (often used for upload/communication with Arduino IDE). If you don't need that, PA9 is a good choice. -#define AUDIO_CHANNEL_1_PIN_HIGH PA9 -// Total audio bits. -#define AUDIO_BITS 14 -#define AUDIO_BITS_PER_CHANNEL 7 -#else -// The more audio bits you use, the slower the carrier frequency of the PWM signal. 10 bits yields ~ 70kHz on a 72Mhz CPU (which appears to be a reasonable compromise) -#define AUDIO_BITS 10 -#define AUDIO_BITS_PER_CHANNEL AUDIO_BITS -#if (AUDIO_CHANNELS > 1) -// Second out pin for stereo mode. This must be on the same timer as AUDIO_CHANNEL_1_PIN! -#define AUDIO_CHANNEL_2_PIN PA9 +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 PA8 +# endif +# if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_2 PA9 +# endif +# if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 10 +# endif +# define MOZZI_AUDIO_BITS_PER_CHANNEL MOZZI_AUDIO_BITS +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 PA8 +# endif +# if !defined(MOZZI_AUDIO_PIN_1_LOW) +# define MOZZI_AUDIO_PIN_1_LOW PA9 +# endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) +# if !defined(MOZZI_AUDIO_PER_CHANNEL) +# define MOZZI_AUDIO_PER_CHANNEL 7 +# endif +# define MOZZI_AUDIO_BITS MOZZI_AUDIO_BITS_PER_CHANNEL * 2 #endif + +#if !defined(MOZZI_ANALOG_READ) +#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD #endif diff --git a/mozzi_pgmspace.h b/mozzi_pgmspace.h index 4620a0425..a7e4514f5 100644 --- a/mozzi_pgmspace.h +++ b/mozzi_pgmspace.h @@ -14,8 +14,8 @@ template inline T FLASH_OR_RAM_READ(T* address) { #else #include // work around missing std::is_const -template inline bool mozzi_is_const_pointer(T* x) { return false; } -template inline bool mozzi_is_const_pointer(const T* x) { return true; } +template inline bool mozzi_is_const_pointer(T* ) { return false; } +template inline bool mozzi_is_const_pointer(const T* ) { return true; } /** @ingroup core * Helper function to FLASH_OR_RAM_READ(). You do not want to call this, directly. */ template inline T mozzi_pgm_read_wrapper(const T* address) { From a2177f7c387268ad1426520e8201af5e8c48d5f8 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 17 Nov 2023 17:07:51 +0100 Subject: [PATCH 051/215] STM32 (maple) compiles --- AudioConfigSTM32.h | 33 ------------- MozziConfigExample.h | 10 ++-- MozziGuts.cpp | 2 +- MozziGuts_impl_STM32.hpp | 72 ++++++++++++++++------------- Readme_Mozzi_2_0.md | 1 + hardware_defines.h | 13 +++--- internal/config_check_generic.h | 2 + internal/config_checks_stm32maple.h | 56 ++++++++++++++++++++++ mozzi_rand.cpp | 4 +- 9 files changed, 114 insertions(+), 79 deletions(-) delete mode 100644 AudioConfigSTM32.h create mode 100644 internal/config_checks_stm32maple.h diff --git a/AudioConfigSTM32.h b/AudioConfigSTM32.h deleted file mode 100644 index e8a956d42..000000000 --- a/AudioConfigSTM32.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef AUDIOCONFIGSTM32_H -#define AUDIOCONFIGSTM32_H - -#if not IS_STM32() -#error This header should be included for STM32, only -#endif - -// Audio output pin. If you want to change this, make sure to also set AUDIO_PWM_TIMER to whichever timer is responsible for your PWM pin, and set the other timers to non-conflicting values -#define AUDIO_CHANNEL_1_PIN PB8 -#define AUDIO_PWM_TIMER 4 -// The timer used for running the audio update loop. NOTE: Timer 3 appears to clash with SPI DMA transfers under some circumstances -#define AUDIO_UPDATE_TIMER 2 - -#if (AUDIO_MODE == HIFI) -// Second out pin for HIFI mode. This must be on the same timer as AUDIO_CHANNEL_1_PIN! -// Note that by default we are not using adjacent pins. This is to leave the "Serial1" pins available (often used for upload/communication with Arduino IDE). If you don't need that, PA9 is a good choice. -#define AUDIO_CHANNEL_1_PIN_HIGH PB9 -// Total audio bits. -#define AUDIO_BITS 14 -#define AUDIO_BITS_PER_CHANNEL 7 -#else -// The more audio bits you use, the slower the carrier frequency of the PWM signal. 10 bits yields ~ 70kHz on a 72Mhz CPU (which appears to be a reasonable compromise) -#define AUDIO_BITS 10 -#define AUDIO_BITS_PER_CHANNEL AUDIO_BITS -#if (AUDIO_CHANNELS > 1) -#define AUDIO_CHANNEL_2_PIN PB9 -#endif -#endif - -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) - -#endif // #ifndef AUDIOCONFIGSTM32_H - diff --git a/MozziConfigExample.h b/MozziConfigExample.h index a7add776d..8e939bea0 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -142,7 +142,7 @@ * * For simplicity, mozziAnalogRead() is always defined, but when MOZZI_ANALOG_READ s are disabled or unsupported, it simply relays * to Arduino's regular analogRead(). It is thus quite recommended _not_ to depend on mozziAnalogRead() when disabling this. - * Also setupFastAnalogReads() continues to be defined, for your convenience, but is not called automatically. + * Also setupFastAnalogReads() continues to be defined, for your convenience, but is not called automatically. TODO: rethink that! * * As a rough estimate (your numbers may differ a bit, depending on compiler version, etc.), on an ATMEGA328P (aka Arduino Uno), * disabling analog reads saves 33 bytes of RAM and 340 bytes of FLASH. The performance savings are theorized to be neglegible, however. @@ -769,11 +769,12 @@ * The following settings may be costumized, if desired: * * @code - * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PA8 - * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 + * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PB8 + * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set ot the hardware timer connected to the above pin. Default: 4 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default 2 * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10 * // For stereo, only: - * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PA9 + * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PB9 * @endcode * * @section stm32_maple_pwm MOZZI_OUTPUT_2PIN_PWM @@ -784,6 +785,7 @@ * @code * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PB8 * #define MOZZI_AUDIO_PIN_2 ... // Low byte of the output. Default: PB9 + * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set to the number of the hardware timer connect to the above pins. Default: 4 * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7 * @endcode diff --git a/MozziGuts.cpp b/MozziGuts.cpp index 66f71ae92..c1747293e 100644 --- a/MozziGuts.cpp +++ b/MozziGuts.cpp @@ -30,7 +30,7 @@ static uint8_t adc_count = 0; // needed below // Include the appropriate implementation #if IS_AVR() # include "MozziGuts_impl_AVR.hpp" -#elif IS_STM32() +#elif IS_STM32MAPLE() # include "MozziGuts_impl_STM32.hpp" #elif IS_STM32DUINO() # include "MozziGuts_impl_STM32duino.hpp" diff --git a/MozziGuts_impl_STM32.hpp b/MozziGuts_impl_STM32.hpp index bf8164d24..35579b6be 100644 --- a/MozziGuts_impl_STM32.hpp +++ b/MozziGuts_impl_STM32.hpp @@ -13,8 +13,9 @@ #include "HardwareTimer.h" ////// BEGIN analog input code //////// -#define MOZZI_FAST_ANALOG_IMPLEMENTED -//#include // Disabled, here. See AudioConfigSTM32.h +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) + +//#include // Disabled, here. See hardware_defines.h STM32ADC adc(ADC1); uint8_t stm32_current_adc_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform #define getADCReading() adc.getData() @@ -38,13 +39,6 @@ void stm32_adc_eoc_handler() { advanceADCStep(); } -void setupFastAnalogRead(int8_t speed) { - // NOTE: These picks are pretty arbitrary. Further available options are 7_5, 28_5, 55_5, 71_5 and 239_5 (i.e. 7.5 ADC cylces, etc.) - if (speed == FASTEST_ADC) adc.setSampleRate(ADC_SMPR_1_5); - else if (speed == FASTER_ADC) adc.setSampleRate(ADC_SMPR_13_5); - else (adc.setSampleRate(ADC_SMPR_41_5)); -} - void setupMozziADC(int8_t speed) { adc.attachInterrupt(stm32_adc_eoc_handler); } @@ -56,32 +50,40 @@ inline uint8_t STM32PinMap(uint8_t pin) else return pin; } +void setupFastAnalogRead(int8_t speed) { + // NOTE: These picks are pretty arbitrary. Further available options are 7_5, 28_5, 55_5, 71_5 and 239_5 (i.e. 7.5 ADC cylces, etc.) + if (speed == FASTEST_ADC) adc.setSampleRate(ADC_SMPR_1_5); + else if (speed == FASTER_ADC) adc.setSampleRate(ADC_SMPR_13_5); + else (adc.setSampleRate(ADC_SMPR_41_5)); +} +#endif + ////// END analog input code //////// //// BEGIN AUDIO OUTPUT code /////// -#if (EXTERNAL_AUDIO_OUTPUT == true) -HardwareTimer audio_update_timer(2); -#else -HardwareTimer audio_update_timer(AUDIO_UPDATE_TIMER); -HardwareTimer audio_pwm_timer(AUDIO_PWM_TIMER); +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXERNAL_TIMED) +HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER); +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) +HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER); +HardwareTimer audio_pwm_timer(MOZZI_AUDIO_PWM_TIMER); -#include "AudioConfigSTM32.h" inline void audioOutput(const AudioOutput f) { -# if (AUDIO_MODE == HIFI) - pwmWrite(AUDIO_CHANNEL_1_PIN, (f.l()+AUDIO_BIAS) & ((1 << AUDIO_BITS_PER_CHANNEL) - 1)); - pwmWrite(AUDIO_CHANNEL_1_PIN_HIGH, (f.l()+AUDIO_BIAS) >> AUDIO_BITS_PER_CHANNEL); +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) + pwmWrite(MOZZI_AUDIO_PIN_1, (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_CHANNEL); + pwmWrite(MOZZI_AUDIO_PIN_1_LOW, (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1)); # else - pwmWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS); -# if (AUDIO_CHANNELS > 1) - pwmWrite(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS); + pwmWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS); +# if (MOZZI_AUDIO_CHANNELS > 1) + pwmWrite(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS); # endif #endif } #endif static void startAudio() { +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXERNAL_TIMED) audio_update_timer.pause(); //audio_update_timer.setPeriod(1000000UL / AUDIO_RATE); // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors @@ -96,39 +98,43 @@ static void startAudio() { audio_update_timer.attachInterrupt(TIMER_CH1, defaultAudioOutput); audio_update_timer.refresh(); audio_update_timer.resume(); +#endif -#if (EXTERNAL_AUDIO_OUTPUT != true) - pinMode(AUDIO_CHANNEL_1_PIN, PWM); -# if (AUDIO_MODE == HIFI) - pinMode(AUDIO_CHANNEL_1_PIN_HIGH, PWM); -# elif (AUDIO_CHANNELS > 1) - pinMode(AUDIO_CHANNEL_2_PIN, PWM); +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) + pinMode(MOZZI_AUDIO_PIN_1, PWM); +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) + pinMode(MOZZI_AUDIO_PIN_1_LOW, PWM); +# elif (MOZZI_AUDIO_CHANNELS > 1) + pinMode(MOZZI_AUDIO_PIN_2, PWM); # endif -# define MAX_CARRIER_FREQ (F_CPU / (1 << AUDIO_BITS_PER_CHANNEL)) -# if MAX_CARRIER_FREQ < AUDIO_RATE +# define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL)) +# if MAX_CARRIER_FREQ < MOZZI_AUDIO_RATE # error Configured audio resolution is definitely too high at the configured audio rate (and the given CPU speed) -# elif MAX_CARRIER_FREQ < (AUDIO_RATE * 3) +# elif MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 3) # warning Configured audio resolution may be higher than optimal at the configured audio rate (and the given CPU speed) # endif -# if MAX_CARRIER_FREQ < (AUDIO_RATE * 5) +# if MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 5) // Generate as fast a carrier as possible audio_pwm_timer.setPrescaleFactor(1); # else // No point in generating arbitrarily high carrier frequencies. In fact, if // there _is_ any headroom, give the PWM pin more time to swing from HIGH to // LOW and BACK, cleanly - audio_pwm_timer.setPrescaleFactor((int)MAX_CARRIER_FREQ / (AUDIO_RATE * 5)); + audio_pwm_timer.setPrescaleFactor((int)MAX_CARRIER_FREQ / (MOZZI_AUDIO_RATE * 5)); # endif audio_pwm_timer.setOverflow( - 1 << AUDIO_BITS_PER_CHANNEL); // Allocate enough room to write all + 1 << MOZZI_AUDIO_BITS_PER_CHANNEL); // Allocate enough room to write all // intended bits +# undef MAX_CARRIER_FREQ // no longer needed #endif } void stopMozzi() { +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXERNAL_TIMED) audio_update_timer.pause(); +#endif } //// END AUDIO OUTPUT code /////// diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index 7433e92a7..a4907f90a 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -15,6 +15,7 @@ audio modes mapping further - USE_AUDIO_INPUT: MOZZI_AUDIO_INPUT + - IS_STM32() -> IS_STM32MAPLE() simple renames: - AUDIO_RATE: MOZZI_AUDIO_RATE diff --git a/hardware_defines.h b/hardware_defines.h index 9db53b0af..b93fc34e3 100644 --- a/hardware_defines.h +++ b/hardware_defines.h @@ -50,9 +50,9 @@ // STM32 boards (libmaple based) // https://github.com/stevstrong/Arduino_STM32 #if (defined(__arm__) && !IS_TEENSY3() && !IS_TEENSY4() && __has_include("libmaple/libmaple.h")) -#define IS_STM32() 1 +#define IS_STM32MAPLE() 1 #else -#define IS_STM32() 0 +#define IS_STM32MAPLE() 0 #endif // Mbed OS based boards @@ -76,7 +76,7 @@ #define IS_RENESAS() 0 #endif -#if (defined(__arm__) && !IS_STM32() && !IS_TEENSY3() && !IS_TEENSY4() && !IS_RP2040() && !IS_SAMD21() && !IS_MBED() && !IS_RENESAS()) +#if (defined(__arm__) && !IS_STM32MAPLE() && !IS_TEENSY3() && !IS_TEENSY4() && !IS_RP2040() && !IS_SAMD21() && !IS_MBED() && !IS_RENESAS()) #define IS_STM32DUINO() 1 #else #define IS_STM32DUINO() 0 @@ -94,12 +94,13 @@ #define IS_ESP32() 0 #endif -#if !(IS_AVR() || IS_TEENSY3() || IS_TEENSY4() || IS_STM32() || IS_STM32DUINO() || IS_ESP8266() || IS_SAMD21() || IS_ESP32() || IS_RP2040() || IS_MBED() || IS_RENESAS()) +#if !(IS_AVR() || IS_TEENSY3() || IS_TEENSY4() || IS_STM32MAPLE() || IS_STM32DUINO() || IS_ESP8266() || IS_SAMD21() || IS_ESP32() || IS_RP2040() || IS_MBED() || IS_RENESAS()) +// TODO: add an exception for MOZZI_OUTPUT_EXTERNAL_CUSTOM #error Your hardware is not supported by Mozzi or not recognized. Edit hardware_defines.h to proceed. #endif // Hardware detail defines -#if IS_STM32() +#if IS_STM32MAPLE() #define NUM_ANALOG_INPUTS 16 // probably wrong, but mostly needed to allocate an array of readings #elif IS_ESP8266() #define NUM_ANALOG_INPUTS 1 @@ -111,7 +112,7 @@ #define CACHED_FUNCTION_ATTR #endif -#if IS_STM32() +#if IS_STM32MAPLE() // This is a little silly, but with Arduino 1.8.13, including this header inside MozziGuts.cpp does not work (fails to detect the proper include path). // Putting it here, instead, seem to work. #include diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 97f87f164..cd3217b14 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -63,6 +63,8 @@ #include "config_checks_esp8266.h" #elif IS_STM32DUINO() #include "config_checks_stm32duino.h" +#elif IS_STM32MAPLE() +#include "config_checks_stm32maple.h" #else // TODO #error oops diff --git a/internal/config_checks_stm32maple.h b/internal/config_checks_stm32maple.h new file mode 100644 index 000000000..fab281fdf --- /dev/null +++ b/internal/config_checks_stm32maple.h @@ -0,0 +1,56 @@ +#ifndef CONFIG_CHECKS_STM32MAPLE_H +#define CONFIG_CHECKS_STM32MAPLE_H + +#if not IS_STM32MAPLE() +#error This header should be included for STM32 (libmaple based core), only +#endif + +#if !defined(MOZZI_AUDIO_MODE) +# define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) + +#if !defined(MOZZI_AUDIO_RATE) +# define MOZZI_AUDIO_RATE 32768 +#endif + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) +# if !defined(MOZZI_AUDIO_UPDATE_TIMER) +# define MOZZI_AUDIO_UPDATE_TIMER 2 +# endif +# if !defined(MOZZI_AUDIO_PWM_TIMER) +# define MOZZI_AUDIO_PWM_TIMER 4 +# endif +#endif + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 PB8 +# endif +# if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_2 PB9 +# endif +# if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 10 +# endif +# define MOZZI_AUDIO_BITS_PER_CHANNEL MOZZI_AUDIO_BITS +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 PB8 +# endif +# if !defined(MOZZI_AUDIO_PIN_1_LOW) +# define MOZZI_AUDIO_PIN_1_LOW PB9 +# endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) +# if !defined(MOZZI_AUDIO_PER_CHANNEL) +# define MOZZI_AUDIO_PER_CHANNEL 7 +# endif +# define MOZZI_AUDIO_BITS MOZZI_AUDIO_BITS_PER_CHANNEL * 2 +#endif + +#if !defined(MOZZI_ANALOG_READ) +#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD +#endif + + +#endif // #ifndef CONFIG_CHECKS_STM32MAPLE_H diff --git a/mozzi_rand.cpp b/mozzi_rand.cpp index d6f2011fb..8b3c72b78 100644 --- a/mozzi_rand.cpp +++ b/mozzi_rand.cpp @@ -2,7 +2,7 @@ #include "hardware_defines.h" -#if IS_STM32() +#if IS_STM32MAPLE() //#include extern STM32ADC adc; #elif IS_ESP8266() @@ -126,7 +126,7 @@ void randSeed() { z=longRandom(); //analogReference(analog_reference_orig); // change back to original ADCSRA |= (1 << ADIE); // adc re-Enable Interrupt -#elif IS_STM32() +#elif IS_STM32MAPLE() // Unfortunately the internal temp sensor on STM32s does _not_ appear to create a lot of noise. // Ironically, the calls to calibrate help induce some random noise. You're still fairly likely to produce two equal // random seeds in two subsequent runs, however. From de0d96110e35abbb2e5ca17b92eeec2178b2968e Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 17 Nov 2023 21:28:57 +0100 Subject: [PATCH 052/215] MBED compiles --- AudioConfigMBED.h | 45 ------------------- MozziConfigExample.h | 2 +- MozziGuts_impl_MBED.hpp | 76 +++++++++++++++------------------ internal/config_check_generic.h | 2 + internal/config_checks_mbed.h | 61 ++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 88 deletions(-) delete mode 100644 AudioConfigMBED.h create mode 100644 internal/config_checks_mbed.h diff --git a/AudioConfigMBED.h b/AudioConfigMBED.h deleted file mode 100644 index eb7d93947..000000000 --- a/AudioConfigMBED.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef AUDIOCONFIGMBED_H -#define AUDIOCONFIGMBED_H - -#if not IS_MBED() -#error This header should be included for MBED OS boards, only -#endif - -#if (AUDIO_MODE == HIFI) -#error HIFI mode is not available for this CPU architecture (but several high quality output options are available) -#endif - -// Audio output options -#define INTERNAL_DAC 1 // output using internal DAC driven via DMA. Output is only possible on the DAC pins (A12, and A13 on the Giga) -#define PDM_VIA_SERIAL 2 // output PDM coded sample on a hardware serial UART. NOTE: currently to be considered experimental. Tune is not correct for all combinatinos of AUDIO_RATE & PDM_RESOLUTION - // Also NOTE that you will almost certainly want to use at least some basic RC filter circuit with this mode - -// Set output mode -#define MBED_AUDIO_OUT_MODE INTERNAL_DAC - -#if (MBED_AUDIO_OUT_MODE == PDM_VIA_SERIAL) -// For use in PDM_VIA_SERIAL, only: Peripheral to use. Note that only the TX channel is actually used, but sine this is a hardware UART, the corresponding -// RX channel needs to be claimed, as well. NOTE: This does not necessarily correspond to the labeling on your board! E.g. SERIAL2_TX is TX1 on the Arduino Giga. -#define PDM_SERIAL_UART_TX_CHANNEL_1 SERIAL2_TX -#define PDM_SERIAL_UART_RX_CHANNEL_1 SERIAL2_RX -#endif - -/// User config end. Do not modify below this line - -#if (MBED_AUDIO_OUT_MODE == INTERNAL_DAC) -#define AUDIO_BITS 12 -#define AUDIO_CHANNEL_1_PIN A13 -#define AUDIO_CHANNEL_2_PIN A12 -#define BYPASS_MOZZI_OUTPUT_BUFFER true -#elif (MBED_AUDIO_OUT_MODE == PDM_VIA_SERIAL) -#define AUDIO_BITS 16 // well, used internally, at least. The pins will not be able to actually produce this many bits -#define PDM_RESOLUTION 2 -#define BYPASS_MOZZI_OUTPUT_BUFFER true -#else -#error Invalid output mode configured in AudioConfigMBED.h -#endif - -//#define BYPASS_MOZZI_INPUT_BUFFER true -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) - -#endif // #ifndef AUDIOCONFIGMBED_H diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 8e939bea0..d0b039cbd 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -515,7 +515,7 @@ * For other boards is may be appropriate to customize: * @code * #define MOZZI_AUDIO_PIN_1 ... // mono / left channel; default: A13 - * #define MOZZI_AUDIO_PIN_1 ... // stereo only: right channel; default: A12 + * #define MOZZI_AUDIO_PIN_2 ... // stereo only: right channel; default: A12 * #define MOZZI_AUDIO_BITS ... // default is 12 * @endcode * diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index ea1878f57..56b2370fc 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -23,7 +23,7 @@ #include -AdvancedADC adc(AUDIO_INPUT_PIN); +AdvancedADC adc(MOZZI_AUDIO_INPUT_PIN); Sample inbuf[CHUNKSIZE]; int inbufpos=0; @@ -44,18 +44,19 @@ AudioOutputStorage_t readAudioInput(){ static void startAudioInput() { - if (!adc.begin(AN_RESOLUTION_12, AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) { + if (!adc.begin(AN_RESOLUTION_12, MOZZI_AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) { Serial.println("Failed to start analog acquisition!"); while (1); } } +#else +static void startAudioInput() {}; // dummy to ease coding #endif - +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of USE_AUDIO_INPUT (if enabled). * This template provides empty/dummy implementations to allow you to skip over this section, initially. Once you have an implementation, be sure to enable the - * #define, below: */ -//#define MOZZI_FAST_ANALOG_IMPLEMENTED + * #define, above */ // Insert here code to read the result of the latest asynchronous conversion, when it is finished. // You can also provide this as a function returning unsigned int, should it be more complex on your platform @@ -74,20 +75,17 @@ static void startAudioInput() { * Implement adcPinToChannelNum() and channelNumToIndex() to perform the appropriate mapping. */ // NOTE: Theoretically, adcPinToChannelNum is public API for historical reasons, thus cannot be replaced by a define -#define channelNumToIndex(channel) channel uint8_t adcPinToChannelNum(uint8_t pin) { return pin; } /** NOTE: Code needed to trigger a conversion on a new channel */ void adcStartConversion(uint8_t channel) { -#warning Fast analog read not implemented on this platform } /** NOTE: Code needed to trigger a subsequent conversion on the latest channel. If your platform has no special code for it, you should store the channel from * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */ void startSecondADCReadOnCurrentChannel() { -#warning Fast analog read not implemented on this platform } /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize. @@ -99,27 +97,16 @@ void setupFastAnalogRead(int8_t speed) { /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and * possibly calibration. */ void setupMozziADC(int8_t speed) { -#warning Fast analog read not implemented on this platform - #if (USE_AUDIO_INPUT) - startAudioInput(); - #endif } -/* NOTE: Most platforms call a specific function/ISR when conversion is complete. Provide this function, here. - * From inside its body, simply call advanceADCStep(). E.g.: -void stm32_adc_eoc_handler() { - advanceADCStep(); -} -*/ - - +#endif ////// END analog input code //////// ////// BEGIN audio output code ////// -#if (EXTERNAL_AUDIO_OUTPUT == true) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) -#define US_PER_AUDIO_TICK (1000000L / AUDIO_RATE) +#define US_PER_AUDIO_TICK (1000000L / MOZZI_AUDIO_RATE) #include mbed::Ticker audio_output_timer; @@ -132,20 +119,21 @@ inline void defaultAudioOutputCallback() { static void startAudio() { audio_output_timer.attach_us(&defaultAudioOutputCallback, US_PER_AUDIO_TICK); + startAudioInput(), } void stopMozzi() { audio_output_timer.detach(); } -#elif (MBED_AUDIO_OUT_MODE == INTERNAL_DAC) +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) #include -AdvancedDAC dac1(AUDIO_CHANNEL_1_PIN); +AdvancedDAC dac1(MOZZI_AUDIO_PIN_1); Sample buf1[CHUNKSIZE]; -#if (AUDIO_CHANNELS > 1) -AdvancedDAC dac2(AUDIO_CHANNEL_2_PIN); +#if (MOZZI_AUDIO_CHANNELS > 1) +AdvancedDAC dac2(MOZZI_AUDIO_PIN_2); Sample buf2[CHUNKSIZE]; #endif int bufpos = 0; @@ -161,21 +149,21 @@ inline void commitBuffer(Sample buffer[], AdvancedDAC &dac) { inline void audioOutput(const AudioOutput f) { if (bufpos >= CHUNKSIZE) { commitBuffer(buf1, dac1); -#if (AUDIO_CHANNELS > 1) +#if (MOZZI_AUDIO_CHANNELS > 1) commitBuffer(buf2, dac2); #endif bufpos = 0; } - buf1[bufpos] = f.l()+AUDIO_BIAS; -#if (AUDIO_CHANNELS > 1) - buf2[bufpos] = f.r()+AUDIO_BIAS; + buf1[bufpos] = f.l()+MOZZI_AUDIO_BIAS; +#if (MOZZI_AUDIO_CHANNELS > 1) + buf2[bufpos] = f.r()+MOZZI_AUDIO_BIAS; #endif ++bufpos; } bool canBufferAudioOutput() { return (bufpos < CHUNKSIZE || (dac1.available() -#if (AUDIO_CHANNELS > 1) +#if (MOZZI_AUDIO_CHANNELS > 1) && dac2.available() #endif )); @@ -183,45 +171,46 @@ bool canBufferAudioOutput() { static void startAudio() { //NOTE: DAC setup currently affected by https://github.com/arduino-libraries/Arduino_AdvancedAnalog/issues/35 . Don't expect this to work, until using a fixed version fo Arduino_AdvancedAnalog! - if (!dac1.begin(AN_RESOLUTION_12, AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) { + if (!dac1.begin(AN_RESOLUTION_12, MOZZI_AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) { Serial.println("Failed to start DAC1 !"); while (1); } -#if (AUDIO_CHANNELS > 1) - if (!dac2.begin(AN_RESOLUTION_12, AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) { +#if (MOZZI_AUDIO_CHANNELS > 1) + if (!dac2.begin(AN_RESOLUTION_12, MOZZI_AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) { Serial.println("Failed to start DAC2 !"); while (1); } #endif + startAudioInput(); } void stopMozzi() { dac1.stop(); -#if (AUDIO_CHANNELS > 1) +#if (MOZZI_AUDIO_CHANNELS > 1) dac2.stop(); #endif } -#elif (MBED_AUDIO_OUT_MODE == PDM_VIA_SERIAL) +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL) #include -mbed::BufferedSerial serial_out1(digitalPinToPinName(PDM_SERIAL_UART_TX_CHANNEL_1), digitalPinToPinName(PDM_SERIAL_UART_RX_CHANNEL_1)); -uint8_t buf[PDM_RESOLUTION*4]; +mbed::BufferedSerial serial_out1(digitalPinToPinName(MOZZI_SERIAL_PIN_TX), digitalPinToPinName(MOZZI_SERIAL_PIN_RX)); +uint8_t buf[MOZZI_PDM_RESOLUTION*4]; bool canBufferAudioOutput() { return serial_out1.writable(); } inline void audioOutput(const AudioOutput f) { - for (uint8_t i = 0; i < PDM_RESOLUTION*4; ++i) { - buf[i] = pdmCode8(f.l()+AUDIO_BIAS); + for (uint8_t i = 0; i < MOZZI_PDM_RESOLUTION*4; ++i) { + buf[i] = pdmCode8(f.l()+MOZZI_AUDIO_BIAS); } - serial_out1.write(&buf, PDM_RESOLUTION*4); + serial_out1.write(&buf, MOZZI_PDM_RESOLUTION*4); } static void startAudio() { - serial_out1.set_baud(AUDIO_RATE*PDM_RESOLUTION*40); // NOTE: 40 = 4 * (8 bits + stop-bits) + serial_out1.set_baud(MOZZI_AUDIO_RATE*MOZZI_PDM_RESOLUTION*40); // NOTE: 40 == 4 * (8 bits + stop-bits) serial_out1.set_format(8, mbed::BufferedSerial::None, 1); } @@ -232,3 +221,6 @@ void stopMozzi() { #endif ////// END audio output code ////// + +#undef CHUNKSIZE +#undef US_PER_AUDIO_TICK diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index cd3217b14..0db8456a6 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -61,6 +61,8 @@ #include "config_checks_esp32.h" #elif IS_ESP8266() #include "config_checks_esp8266.h" +#elif IS_MBED() +#include "config_checks_mbed.h" #elif IS_STM32DUINO() #include "config_checks_stm32duino.h" #elif IS_STM32MAPLE() diff --git a/internal/config_checks_mbed.h b/internal/config_checks_mbed.h new file mode 100644 index 000000000..0441f1bc6 --- /dev/null +++ b/internal/config_checks_mbed.h @@ -0,0 +1,61 @@ +#ifndef CONFIG_CHECK_MBED_H +#define CONFIG_CHECK_MBED_H + +#if not IS_MBED() +#error This header should be included for MBED architecture, only +#endif + +#if !defined(MOZZI_AUDIO_MODE) +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_INTERNAL_DAC) + +#if !defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 32768 +#endif + +#if defined(MOZZI_PWM_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#endif + +#if !defined(MOZZI_ANALOG_READ) +# define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE +#endif + +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD) + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) +# if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 12 +# endif +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 A13 +# endif +# if !defined(MOZZI_AUDIO_PIN_2) +# define MOZZI_AUDIO_PIN_2 A12 +# endif +#endif + +#if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 16 +#endif + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL) +# if !defined(MOZZI_PDM_RESOLUTION) +# define MOZZI_PDM_RESOLUTION 2 +# endif +# if !defined(MOZZI_SERIAL_PIN_TX) +# define MOZZI_SERIAL_PIN_TX SERIAL2_TX +# endif +# if !defined(MOZZI_SERIAL_PIN_RX) +# define MOZZI_SERIAL_PIN_RX SERIAL2_RX +# endif +#endif + +// All modes besides timed external bypass the output buffer! +#if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) +# define BYPASS_MOZZI_OUTPUT_BUFFER true +#endif + +#endif // #ifndef CONFIG_CHECK_MBED_H From 503f819bb20114180c41158ce0e87406ecd2ecc3 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 17 Nov 2023 22:23:26 +0100 Subject: [PATCH 053/215] Renesas compiles --- AudioConfigRenesas.h | 25 -------------- MozziGuts_impl_RENESAS.hpp | 59 ++++++++++++++++++-------------- internal/config_check_generic.h | 11 ++++-- internal/config_checks_mbed.h | 1 + internal/config_checks_renesas.h | 38 ++++++++++++++++++++ 5 files changed, 82 insertions(+), 52 deletions(-) delete mode 100644 AudioConfigRenesas.h create mode 100644 internal/config_checks_renesas.h diff --git a/AudioConfigRenesas.h b/AudioConfigRenesas.h deleted file mode 100644 index 2fb3523c0..000000000 --- a/AudioConfigRenesas.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef AUDIOCONFIGRENESAS_H -#define AUDIOCONFIGRENESAS_H - -#if not IS_RENESAS() -#error This header should be included for Arduino FSB board (Uno R4/Renesa) family, only -#endif - - - - -#define AUDIO_CHANNEL_1_PIN A0 -#if (AUDIO_CHANNELS > 1) -#define AUDIO_CHANNEL_2_PIN 10 -#endif - -#define AUDIO_BITS 12 // outputting resolution of the on-bard DAC. Other values are *NOT* expected to work. - -#define AUDIO_BITS_PER_CHANNEL AUDIO_BITS - -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) - -#define BYPASS_MOZZI_OUTPUT_BUFFER true // Mozzi initial buffer are not of the good type, so we bypass it and create our own - -#endif // #ifndef AUDIOCONFIGRENESAS_H - diff --git a/MozziGuts_impl_RENESAS.hpp b/MozziGuts_impl_RENESAS.hpp index f5c0e4c34..ddc9edeaf 100644 --- a/MozziGuts_impl_RENESAS.hpp +++ b/MozziGuts_impl_RENESAS.hpp @@ -19,6 +19,7 @@ ////// BEGIN analog input code //////// +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) #define channelNumToIndex(channel) channel-14 // A0=14 void const *const p_context = 0; // unused but needed for the ADC call @@ -32,8 +33,6 @@ void adc_callback(adc_callback_args_t *p_args) { #include "MozziGuts_impl_RENESAS_ADC.hpp" -#define MOZZI_FAST_ANALOG_IMPLEMENTED - #define getADCReading() readADC(r4_pin) uint8_t adcPinToChannelNum(uint8_t pin) { @@ -56,7 +55,7 @@ void setupFastAnalogRead(int8_t speed) { void setupMozziADC(int8_t speed) { IRQManager::getInstance().addADCScanEnd(&adc, NULL); // this is needed to change some config inside the ADC, even though we do not give the callback here (doing so crashes the board). The callback is declared to the ADC by: R_ADC_CallbackSet(&(_adc->ctrl), adc_callback, p_context, p_callback_memory); in MozziGuts_impl_RENESAS_ADC.hpp. } - +#endif ////// END analog input code //////// @@ -78,9 +77,11 @@ As a consequence we need to artificially empty the buffer at the same rate that it. */ +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) FspTimer timer; +#endif -#if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) CircularBuffer output_buffer; #include "MozziGuts_impl_RENESAS_analog.hpp" #endif @@ -88,13 +89,14 @@ CircularBuffer output_buffer; //////////////// TIMER //////////////// -#if EXTERNAL_AUDIO_OUTPUT == true +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) void timer_callback_dummy(timer_callback_args_t __attribute__((unused)) *args){defaultAudioOutput();}; -#else +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) //void timer_callback_dummy(timer_callback_args_t __attribute__((unused)) *args){ void timer_callback_dummy(timer_callback_args_t __attribute__((unused)) *args){output_buffer.read();}; // to empty the buffer (the dac does not take care of it), a bit a waste of timer... #endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) void timer_init() { uint8_t type; int8_t tindex = FspTimer::get_available_timer(type); @@ -104,14 +106,15 @@ void timer_init() { } if (tindex >= 0) { - timer.begin(TIMER_MODE_PERIODIC, type, tindex, AUDIO_RATE, 50.0,timer_callback_dummy); + timer.begin(TIMER_MODE_PERIODIC, type, tindex, MOZZI_AUDIO_RATE, 50.0,timer_callback_dummy); timer.setup_overflow_irq(); } - -#if EXTERNAL_AUDIO_OUTPUT != true // we need to set up another timer for dac caring + +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) + // we need to set up another timer for dac caring // note: it is running at the same speed than the other one, but could not manage // to get the other one updating the dac and removing the samples from the buffer… - tindex = FspTimer::get_available_timer(type); + tindex = FspTimer::get_available_timer(type); if (tindex < 0) { tindex = FspTimer::get_available_timer(type, true); @@ -119,28 +122,31 @@ void timer_init() { if (tindex >= 0) { FspTimer::force_use_of_pwm_reserved_timer(); - timer_dac.begin(TIMER_MODE_PERIODIC, type, tindex, AUDIO_RATE, 50.0); - timer_dac.setup_overflow_irq(); - dtc_cfg_extend.activation_source = timer_dac.get_cfg()->cycle_end_irq; - timer_dac.open(); -#endif - timer.open(); + timer_dac.begin(TIMER_MODE_PERIODIC, type, tindex, MOZZI_AUDIO_RATE, 50.0); + timer_dac.setup_overflow_irq(); + dtc_cfg_extend.activation_source = timer_dac.get_cfg()->cycle_end_irq; + timer_dac.open(); } - } - +# endif // TODO: This endif used to be two lines up from here (above timer.open), which does not make sense syntactically, for external output + timer.open(); +} +#endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) inline void audioOutput(const AudioOutput f) { - output_buffer.write(f+AUDIO_BIAS); + output_buffer.write(f+MOZZI_AUDIO_BIAS); } -#define canBufferAudioOutput() (!output_buffer.isFull()) - +# define canBufferAudioOutput() (!output_buffer.isFull()) +#endif static void startAudio() { -#if EXTERNAL_AUDIO_OUTPUT != true - dac_creation(AUDIO_CHANNEL_1_PIN); +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) + dac_creation(MOZZI_AUDIO_PIN_1); #endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) timer_init(); // this need to be done between the DAC creation and initialization in the case where the on-board DAC is used, hence the ugly repetition here. -#if EXTERNAL_AUDIO_OUTPUT != true +#endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) dac_init(); R_DTC_Open(&dtc_ctrl, &dtc_cfg); R_DTC_Enable(&dtc_ctrl); @@ -151,11 +157,14 @@ static void startAudio() { R_DTC_Reconfigure(&dtc_ctrl, dtc_cfg.p_info); timer_dac.start(); #endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) timer.start(); - +#endif } void stopMozzi() { +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) timer.stop(); +#endif } //// END AUDIO OUTPUT code /////// diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index 0db8456a6..a29b0884f 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -63,13 +63,20 @@ #include "config_checks_esp8266.h" #elif IS_MBED() #include "config_checks_mbed.h" +#elif IS_RENESAS() +#include "config_checks_renesas.h" +#elif IS_RP2040() +#include "config_checks_rp2040.h" +#elif IS_SAMD21() +#include "config_checks_samd21.h" #elif IS_STM32DUINO() #include "config_checks_stm32duino.h" #elif IS_STM32MAPLE() #include "config_checks_stm32maple.h" +#elif IS_TEENSY3() || IS_TEENSY4 +#include "config_checks_teensy.h" #else -// TODO -#error oops +#error Problem detecting hardware #endif diff --git a/internal/config_checks_mbed.h b/internal/config_checks_mbed.h index 0441f1bc6..d212bb3c1 100644 --- a/internal/config_checks_mbed.h +++ b/internal/config_checks_mbed.h @@ -22,6 +22,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE #endif +// yes, correct: async "single" reads are not implemented, but audio input is MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD) diff --git a/internal/config_checks_renesas.h b/internal/config_checks_renesas.h new file mode 100644 index 000000000..f77fd0e27 --- /dev/null +++ b/internal/config_checks_renesas.h @@ -0,0 +1,38 @@ +#ifndef CONFIG_CHECK_RENESAS_H +#define CONFIG_CHECK_RENESAS_H + +#if not IS_RENESAS() +#error This header should be included for RENESAS (Arduino Uno R4) architecture, only +#endif + +#if !defined(MOZZI_AUDIO_MODE) +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC) + +#if !defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 32768 +#endif + +#if defined(MOZZI_PWM_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#endif + +#if !defined(MOZZI_ANALOG_READ) +# define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD +#endif + +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) +# if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 12 +# endif +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 A0 +# endif +# define BYPASS_MOZZI_OUTPUT_BUFFER true +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) + +#endif // #ifndef CONFIG_CHECK_MBED_H From 3234efaa20ba317425845f014a530a688b78ddf7 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 18 Nov 2023 13:37:34 +0100 Subject: [PATCH 054/215] Compiles on Teensy 3.1/4.0 --- AudioConfigTeensy3_12bit.h | 25 -------------- AudioConfigTeensy4.h | 17 ---------- MozziConfigExample.h | 10 ++++-- MozziGuts_impl_TEENSY.hpp | 51 ++++++++++++++-------------- internal/config_check_generic.h | 2 +- internal/config_checks_teensy.h | 60 +++++++++++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 70 deletions(-) delete mode 100644 AudioConfigTeensy3_12bit.h delete mode 100644 AudioConfigTeensy4.h create mode 100644 internal/config_checks_teensy.h diff --git a/AudioConfigTeensy3_12bit.h b/AudioConfigTeensy3_12bit.h deleted file mode 100644 index 0f9a7d550..000000000 --- a/AudioConfigTeensy3_12bit.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef AUDIOCONFIGTEENSY3_12BIT_H -#define AUDIOCONFIGTEENSY3_12BIT_H - -#warning If you get a compilation error you should probably update Teensyduino to its latest version - -/** @ingroup core -*/ -/* Used internally to put the 0-biased generated audio into the centre of the output range (12 bits on Teensy 3) */ -#define AUDIO_BIAS ((uint16_t) 2048) -#define AUDIO_BITS 12 - -#if !defined(AUDIO_CHANNEL_1_PIN) && defined(__arm__) && defined(CORE_TEENSY) -#if defined(__MKL26Z64__) -#define AUDIO_CHANNEL_1_PIN A12 -#elif defined(__MK20DX128__) || defined(__MK20DX256__) -#define AUDIO_CHANNEL_1_PIN A14 -#elif defined(__MK64FX512__) || defined(__MK66FX1M0__) -#define AUDIO_CHANNEL_1_PIN A21 -#else -#error "Unknown Teensy" -#endif -#endif - -#endif // #ifndef AUDIOCONFIGTEENSY3_12BIT_H - diff --git a/AudioConfigTeensy4.h b/AudioConfigTeensy4.h deleted file mode 100644 index e320d385d..000000000 --- a/AudioConfigTeensy4.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef AUDIOCONFIGTEENSY4_H -#define AUDIOCONFIGTEENSY4_H - -#warning If you get a compilation error you should probably update Teensyduino to its latest version - -/** @ingroup core -*/ -/* Used internally to put the 0-biased generated audio into the centre of the output range (10 bits on Teensy 4 using PWM) */ -#define AUDIO_BIAS ((uint16_t) 512) -#define AUDIO_BITS 10 - -#define AUDIO_CHANNEL_1_PIN A8 -#define AUDIO_CHANNEL_2_PIN A9 - - -#endif // #ifndef AUDIOCONFIGTEENSY4_H - diff --git a/MozziConfigExample.h b/MozziConfigExample.h index d0b039cbd..e9de3dc3e 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -19,6 +19,7 @@ * * TODO: Fix and complete Doxygen coverage * TODO: Probably the recommendation to copy this whole file is over the top, perhaps provide stripped-down examples, instead + * TODO: Move all the hardware depended stuff to the corresponding config_checks_xyz.h, to increase the chances that doc and implementation remain in sync */ #include // needed for the named option values @@ -824,7 +825,12 @@ * The default mode is @ref teensy3_internal_dac . * * @section teensy3_internal_dac MOZZI_OUTPUT_INTERNAL_DAC - * Output is to the inbuilt DAC on pin 14/DAC. The pinout is not configurable. Output resolution is 12 bits. + * Output is to the inbuilt DAC. Output resolution is 12 bits. Mono, only. The DAC output pin differs from board to boards. + * In most cases the appropriate pin will be set outmatically. If needed, you can specify the DAC pin, explicitly: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // Default: A14, A12, or A21, depending on board + * @endcode * * @section teensy3_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM * See @ref external_audio @@ -857,7 +863,7 @@ * * The default mode is @ref teensy4_pwm . * - * @section teensy4_pwm MOZZI_OUTPUT_INTERNAL_DAC + * @section teensy4_pwm MOZZI_OUTPUT_PWM * Output is to a GPIO pin (or two in stereo). The output resolution is fixed at 10 bits, and a 146484 kHz carrier frequency. * The output pins can be configured as: * diff --git a/MozziGuts_impl_TEENSY.hpp b/MozziGuts_impl_TEENSY.hpp index ef0262d22..04c18ac73 100644 --- a/MozziGuts_impl_TEENSY.hpp +++ b/MozziGuts_impl_TEENSY.hpp @@ -14,18 +14,16 @@ # error "Wrong implementation included for this platform" #endif -// required from http://github.com/pedvide/ADC for Teensy 3.* -#include "IntervalTimer.h" -#include -#include "teensyPinMap.h" - #if (IS_TEENSY3() && F_CPU != 48000000) #warning \ "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino and 48MHz on Teensy 3! Results may vary with other speeds." #endif ////// BEGIN analog input code //////// -#define MOZZI_FAST_ANALOG_IMPLEMENTED +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) +// required from http://github.com/pedvide/ADC for Teensy 3.* +#include + ADC *adc; // adc object uint8_t teensy_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform int8_t teensy_adc=0; @@ -69,45 +67,48 @@ void adcStartConversion(uint8_t channel) { static void startSecondADCReadOnCurrentChannel() { adc->startSingleRead(teensy_pin,teensy_adc); } +#endif // MOZZI_ANALOG_READ ////// END analog input code //////// //// BEGIN AUDIO OUTPUT code /////// +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) +#include "IntervalTimer.h" IntervalTimer timer1; - -#if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user -#if IS_TEENSY3() -#include "AudioConfigTeensy3_12bit.h" -#elif IS_TEENSY4() -#include "AudioConfigTeensy4.h" #endif + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC) inline void audioOutput(const AudioOutput f) { - analogWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS); -#if (AUDIO_CHANNELS > 1) - analogWrite(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS); -#endif + analogWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS); +# if (MOZZI_AUDIO_CHANNELS > 1) + analogWrite(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS); +# endif } #endif static void startAudio() { -#if IS_TEENSY3() +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC) +# if IS_TEENSY3() analogWriteResolution(12); -#elif IS_TEENSY4() +# elif IS_TEENSY4() analogWriteResolution(10); -# if (!EXTERNAL_AUDIO_OUTPUT) - analogWriteFrequency(AUDIO_CHANNEL_1_PIN, 146484.38f); -# if (AUDIO_CHANNELS > 1) - analogWriteFrequency(AUDIO_CHANNEL_2_PIN, 146484.38f); -# endif // end #if (AUDIO_CHANNELS > 1) -# endif // end #if (!EXTERNAL_AUDIO_OUTPUT) + analogWriteFrequency(MOZZI_AUDIO_PIN_1, 146484.38f); +# if (MOZZI_AUDIO_CHANNELS > 1) + analogWriteFrequency(MOZZI_AUDIO_PIN_2, 146484.38f); +# endif // end #if (MOZZI_AUDIO_CHANNELS > 1) +# endif // TEENSY3/4 +#endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) + timer1.begin(defaultAudioOutput, 1000000. / MOZZI_AUDIO_RATE); #endif - timer1.begin(defaultAudioOutput, 1000000. / AUDIO_RATE); } void stopMozzi() { +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) timer1.end(); +#endif interrupts(); } //// END AUDIO OUTPUT code /////// diff --git a/internal/config_check_generic.h b/internal/config_check_generic.h index a29b0884f..502c6ae13 100644 --- a/internal/config_check_generic.h +++ b/internal/config_check_generic.h @@ -73,7 +73,7 @@ #include "config_checks_stm32duino.h" #elif IS_STM32MAPLE() #include "config_checks_stm32maple.h" -#elif IS_TEENSY3() || IS_TEENSY4 +#elif (IS_TEENSY3() || IS_TEENSY4()) #include "config_checks_teensy.h" #else #error Problem detecting hardware diff --git a/internal/config_checks_teensy.h b/internal/config_checks_teensy.h new file mode 100644 index 000000000..0913876d7 --- /dev/null +++ b/internal/config_checks_teensy.h @@ -0,0 +1,60 @@ +#ifndef CONFIG_CHECK_TEENSY_H +#define CONFIG_CHECK_TEENSY_H + +#if !(IS_TEENSY3() || IS_TEENSY4()) +#error This header should be included for Teensy (3.x or 4.x) boards, only +#endif + +#if IS_TEENSY3() +# if !defined(MOZZI_AUDIO_MODE) +# define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC +# endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC) +#elif IS_TEENSY4() +# if !defined(MOZZI_AUDIO_MODE) +# define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM +# endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM) +#endif + +#if !defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 32768 +#endif + +#if defined(MOZZI_PWM_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#endif + +#if !defined(MOZZI_ANALOG_READ) +# define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD +#endif + +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) + +#include "teensyPinMap.h" + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) +# define MOZZI_AUDIO_BITS 12 // not configurable +# if !defined(MOZZI_AUDIO_PIN_1) +# if defined(__MKL26Z64__) +# define MOZZI_AUDIO_PIN_1 A12 +# elif defined(__MK20DX128__) || defined(__MK20DX256__) +# define MOZZI_AUDIO_PIN_1 A14 +# elif defined(__MK64FX512__) || defined(__MK66FX1M0__) +# define MOZZI_AUDIO_PIN_1 A21 +# else +# error DAC pin not know for this board. Please define MOZZI_AUDIO_PIN_1 as appropriate +# endif +# endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) +# define MOZZI_AUDIO_BITS 10 // not configurable +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 A8 +# endif +# if !defined(MOZZI_AUDIO_PIN_2) +# define MOZZI_AUDIO_PIN_2 A9 +# endif +#endif + +#endif // #ifndef CONFIG_CHECK_TEENSY_H From 727a14b18dd0c997a513bac6ddddb20a16caeb91 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 18 Nov 2023 13:50:15 +0100 Subject: [PATCH 055/215] SAMD compiles --- AudioConfigSAMD21.h | 15 ------------- MozziGuts_impl_SAMD.hpp | 29 +++++++++++++------------ internal/config_checks_renesas.h | 4 ++-- internal/config_checks_samd21.h | 37 ++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 31 deletions(-) delete mode 100644 AudioConfigSAMD21.h create mode 100644 internal/config_checks_samd21.h diff --git a/AudioConfigSAMD21.h b/AudioConfigSAMD21.h deleted file mode 100644 index 61984f19b..000000000 --- a/AudioConfigSAMD21.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef AUDIOCONFIGSAMD21_H -#define AUDIOCONFIGSAMD21_H - -/* Note: SAMD21 has 12 bits ADC, but only 10 bits DAC. See https://github.com/sensorium/Mozzi/issues/75 */ -#define AUDIO_BITS 10 - -/** @ingroup core -*/ -/* Used internally to put the 0-biased generated audio into the centre of the output range (10 bits) */ -#define AUDIO_BIAS ((uint16_t) 1 << (AUDIO_BITS - 1)) - -#define AUDIO_CHANNEL_1_PIN DAC0 - -#endif // #ifndef AUDIOCONFIGSAMD21_H - diff --git a/MozziGuts_impl_SAMD.hpp b/MozziGuts_impl_SAMD.hpp index 03cc61910..4602cc920 100644 --- a/MozziGuts_impl_SAMD.hpp +++ b/MozziGuts_impl_SAMD.hpp @@ -15,29 +15,27 @@ #endif ////// BEGIN analog input code //////// -//#define MOZZI_FAST_ANALOG_IMPLEMENTED // not yet +#if MOZZI_IS(MOZZI_ANALOG_READ, NOZZI_ANALOG_READ_STANDARD) #define getADCReading() 0 #define channelNumToIndex(channel) channel uint8_t adcPinToChannelNum(uint8_t pin) { return pin; } void adcStartConversion(uint8_t channel) { -#warning Fast analog read not implemented on this platform } void startSecondADCReadOnCurrentChannel() { -#warning Fast analog read not implemented on this platform } void setupFastAnalogRead(int8_t speed) { -#warning Fast analog read not implemented on this platform } void setupMozziADC(int8_t speed) { -#warning Fast analog read not implemented on this platform } +#endif ////// END analog input code //////// //// BEGIN AUDIO OUTPUT code /////// +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) // These are ARM SAMD21 Timer 5 routines to establish a sample rate interrupt static bool tcIsSyncing() { return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY; @@ -106,29 +104,32 @@ void samd21AudioOutput() { #ifdef __cplusplus } #endif +#endif // MOZZI_AUDIO_MODE -#if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user -#include "AudioConfigSAMD21.h" +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) inline void audioOutput(const AudioOutput f) { - analogWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS); + analogWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS); } #endif static void startAudio() { -#ifdef ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) +# ifdef ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS { static const int CPLAY_SPEAKER_SHUTDOWN = 11; pinMode(CPLAY_SPEAKER_SHUTDOWN, OUTPUT); digitalWrite(CPLAY_SPEAKER_SHUTDOWN, HIGH); } -#endif - analogWriteResolution(AUDIO_BITS); -#if (EXTERNAL_AUDIO_OUTPUT != true) - analogWrite(AUDIO_CHANNEL_1_PIN, 0); +# endif + + analogWriteResolution(MOZZI_AUDIO_BITS); + analogWrite(MOZZI_AUDIO_PIN_1, 0); #endif - tcConfigure(AUDIO_RATE); +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) + tcConfigure(MOZZI_AUDIO_RATE); +#endif } void stopMozzi() { diff --git a/internal/config_checks_renesas.h b/internal/config_checks_renesas.h index f77fd0e27..7f3f20a59 100644 --- a/internal/config_checks_renesas.h +++ b/internal/config_checks_renesas.h @@ -32,7 +32,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_RE # define MOZZI_AUDIO_PIN_1 A0 # endif # define BYPASS_MOZZI_OUTPUT_BUFFER true -#endif MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) +#endif -#endif // #ifndef CONFIG_CHECK_MBED_H +#endif // #ifndef CONFIG_CHECK_RENESAS_H diff --git a/internal/config_checks_samd21.h b/internal/config_checks_samd21.h new file mode 100644 index 000000000..88a50c228 --- /dev/null +++ b/internal/config_checks_samd21.h @@ -0,0 +1,37 @@ +#ifndef CONFIG_CHECK_SAMD21_H +#define CONFIG_CHECK_SAMD21_H + +#if not IS_SAMD21() +#error This header should be included for SAMD21 architecture (Arduino Circuitplayground M0 and others), only +#endif + +#if !defined(MOZZI_AUDIO_MODE) +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC) + +#if !defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 32768 +#endif + +#if defined(MOZZI_PWM_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#endif + +#if !defined(MOZZI_ANALOG_READ) +# define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE +#endif + +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) +# if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 10 +# endif +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 DAC0 +# endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) +#endif + +#endif // #ifndef CONFIG_CHECK_SAMD21_H From 6da50a626d3314a777a5474ca3632e716c15b828 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 18 Nov 2023 21:52:21 +0100 Subject: [PATCH 056/215] RP2040 compiles --- AudioConfigRP2040.h | 53 --------------- MozziConfigExample.h | 2 +- MozziConfigValues.h | 7 +- MozziGuts.cpp | 7 ++ MozziGuts_impl_ESP32.hpp | 1 - MozziGuts_impl_RP2040.hpp | 116 +++++++++++++++++--------------- internal/config_checks_rp2040.h | 57 ++++++++++++++++ 7 files changed, 130 insertions(+), 113 deletions(-) delete mode 100644 AudioConfigRP2040.h create mode 100644 internal/config_checks_rp2040.h diff --git a/AudioConfigRP2040.h b/AudioConfigRP2040.h deleted file mode 100644 index eed5201b4..000000000 --- a/AudioConfigRP2040.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef AUDIOCONFIGRP2040_H -#define AUDIOCONFIGRP2040_H - -#if not IS_RP2040() -#error This header should be included for RP2040, only -#endif - - -// AUDIO output modes -#define PWM_VIA_BARE_CHIP 1 // output using one of the gpio of the board -#define EXTERNAL_DAC_VIA_I2S 2 // output via external DAC connected to I2S (PT8211 or similar) - -//******* BEGIN: These are the defines you may want to change. Best not to touch anything outside this range. ************/ -#define RP2040_AUDIO_OUT_MODE PWM_VIA_BARE_CHIP -//******* END: These are the defines you may want to change. Best not to touch anything outside this range. ************/ - - -#if (RP2040_AUDIO_OUT_MODE == PWM_VIA_BARE_CHIP) -#define AUDIO_CHANNEL_1_PIN 0 -#if (AUDIO_CHANNELS > 1) -// Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. -#define AUDIO_CHANNEL_2_PIN 1 -#endif - -// The more audio bits you use, the slower the carrier frequency of the PWM signal. 11 bits yields ~ 60kHz on a 133Mhz CPU (which appears to be a reasonable compromise) -#define AUDIO_BITS 11 -#endif - -#if (RP2040_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S) -// ****** BEGIN: These are define you may want to change. Best not to touch anything outside this range. ************/ -#define BCLK_PIN 20 -#define WS_PIN (pBCLK+1) // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK -#define DOUT_PIN 22 -#define LSBJ_FORMAT false // some DAC, like the PT8211, use a variant of I2S data format called LSBJ - // set this to true to use this kind of DAC or false for plain I2S. -#define AUDIO_BITS 16 // available values are 8, 16, 24 (LEFT ALIGN in 32 bits type!!) and 32 bits -// ****** END: These are define you may want to change. Best not to touch anything outside this range. ************/ - -#define BYPASS_MOZZI_OUTPUT_BUFFER true - -// Configuration of the I2S port, especially DMA. Set in stone here as default of the library when this was written. -// Probably do not change if you are not sure of what you are doing -#define BUFFERS 8 // number of DMA buffers used -#define BUFFER_SIZE 256 // total size of the buffer, in samples -#endif - - -#define AUDIO_BITS_PER_CHANNEL AUDIO_BITS - -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) - -#endif // #ifndef AUDIOCONFIGRP2040_H - diff --git a/MozziConfigExample.h b/MozziConfigExample.h index e9de3dc3e..492a85ee2 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -604,7 +604,7 @@ * #define MOZZI_AUDIO_PIN_1 ... // default is 0 * #define MOZZI_AUDIO_BITS ... // output resolution (bits); default is 11 * // additionally, for stereo: - * #define MOZZI_AUDIO_PIN_2 ... // default is 1 + * #define MOZZI_AUDIO_PIN_2 ... // default is 1; this must be on the same PWM slice as the first pin (i.e. neighboring) * @endcode * * @section rp2040_i2s_dac MOZZI_OUTPUT_I2S_DAC diff --git a/MozziConfigValues.h b/MozziConfigValues.h index d311ad1ad..8470158d4 100644 --- a/MozziConfigValues.h +++ b/MozziConfigValues.h @@ -26,8 +26,11 @@ TODO: Fix documentation #define MOZZI_AUDIO_INPUT_NONE 201 #define MOZZI_AUDIO_INPUT_STANDARD 202 -#define MOZZI_ANALOG_READ_NONE 201 -#define MOZZI_ANALOG_READ_STANDARD 202 +#define MOZZI_ANALOG_READ_NONE 301 +#define MOZZI_ANALOG_READ_STANDARD 302 + +#define MOZZI_I2S_FORMAT_PLAIN 401 +#define MOZZI_I2S_FORMAT_LSBJ 402 // defined with some space in between, just in case. This should be numerically ordered. #define MOZZI_COMPATIBILITY_1_1 1100 diff --git a/MozziGuts.cpp b/MozziGuts.cpp index c1747293e..5fe2676ee 100644 --- a/MozziGuts.cpp +++ b/MozziGuts.cpp @@ -275,3 +275,10 @@ void startMozzi(int control_rate_hz) { } ////// END initialization /////// + +// reduce Macro leakage +#undef LOOP_YIELD +#undef BYPASS_MOZZI_OUTPUT_BUFFER +#undef AUDIO_HOOK_HOOK +#undef AUDIOTICK_ADJUSTMENT +#undef MOZZI__LEGACY_AUDIO_INPUT_IMPL diff --git a/MozziGuts_impl_ESP32.hpp b/MozziGuts_impl_ESP32.hpp index 8ecbc16ad..172e38a7f 100644 --- a/MozziGuts_impl_ESP32.hpp +++ b/MozziGuts_impl_ESP32.hpp @@ -16,7 +16,6 @@ ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) - #error not yet implemented #define getADCReading() 0 diff --git a/MozziGuts_impl_RP2040.hpp b/MozziGuts_impl_RP2040.hpp index 096a292ca..22fa58299 100644 --- a/MozziGuts_impl_RP2040.hpp +++ b/MozziGuts_impl_RP2040.hpp @@ -15,10 +15,11 @@ # error "Wrong implementation included for this platform" #endif +#include ////// BEGIN analog input code //////// -#define MOZZI_FAST_ANALOG_IMPLEMENTED +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) /** Implementation notes: * - So nobody on the nets seems to have quite figured out, how to run the RP2040 ADC in "regular" asynchronous mode. @@ -28,7 +29,6 @@ */ #include -#include #define getADCReading() rp2040_adc_result #define channelNumToIndex(channel) channel @@ -116,6 +116,8 @@ void rp2040_adc_queue_handler() { dma_channel_set_trans_count(rp2040_adc_dma_chan, 1, true); // set up for another read advanceADCStep(); } +#endif // MOZZI_ANALOG_READ + ////// END analog input code //////// @@ -123,16 +125,17 @@ void rp2040_adc_queue_handler() { #define LOOP_YIELD tight_loop_contents(); // apparently needed, among other things, to service the alarm pool -#if (RP2040_AUDIO_OUT_MODE == PWM_VIA_BARE_CHIP) || (EXTERNAL_AUDIO_OUTPUT == true) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) #include -#if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user + +# if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) inline void audioOutput(const AudioOutput f) { - pwm_set_gpio_level(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS); -#if (AUDIO_CHANNELS > 1) - pwm_set_gpio_level(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS); -#endif + pwm_set_gpio_level(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS); +# if (MOZZI_AUDIO_CHANNELS > 1) + pwm_set_gpio_level(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS); +# endif } -#endif // #if (EXTERNAL_AUDIO_OUTPUT != true) +# endif // MOZZI_OUTPUT_PWM #include /** Implementation notes: @@ -155,76 +158,74 @@ void audioOutputCallback(uint) { } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update)); } -#elif (RP2040_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S) +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) #include I2S i2s(OUTPUT); - inline bool canBufferAudioOutput() { return (i2s.availableForWrite()); } inline void audioOutput(const AudioOutput f) { -#if (AUDIO_BITS == 8) -#if (AUDIO_CHANNELS > 1) +# if (MOZZI_AUDIO_BITS == 8) +# if (MOZZI_AUDIO_CHANNELS > 1) i2s.write8(f.l(), f.r()); -#else +# else i2s.write8(f.l(), 0); -#endif +# endif -#elif (AUDIO_BITS == 16) -#if (AUDIO_CHANNELS > 1) +# elif (MOZZI_AUDIO_BITS == 16) +# if (MOZZI_AUDIO_CHANNELS > 1) i2s.write16(f.l(), f.r()); -#else +# else i2s.write16(f.l(), 0); -#endif +# endif -#elif (AUDIO_BITS == 24) -#if (AUDIO_CHANNELS > 1) +# elif (MOZZI_AUDIO_BITS == 24) +# if (MOZZI_AUDIO_CHANNELS > 1) i2s.write24(f.l(), f.r()); -#else +# else i2s.write24(f.l(), 0); -#endif +# endif -#elif (AUDIO_BITS == 32) -#if (AUDIO_CHANNELS > 1) +# elif (MOZZI_AUDIO_BITS == 32) +# if (MOZZI_AUDIO_CHANNELS > 1) i2s.write32(f.l(), f.r()); -#else +# else i2s.write32(f.l(), 0); -#endif -#else - #error The number of AUDIO_BITS set in AudioConfigRP2040.h is incorrect -#endif +# endif +# else +# error Invalid number of MOZZI_AUDIO_BITS configured +# endif - } #endif static void startAudio() { -#if (RP2040_AUDIO_OUT_MODE == PWM_VIA_BARE_CHIP) || (EXTERNAL_AUDIO_OUTPUT == true) // EXTERNAL AUDIO needs the timers set here -#if (EXTERNAL_AUDIO_OUTPUT != true) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) // calling analogWrite for the first time will try to init the pwm frequency and range on all pins. We don't want that happening after we've set up our own, // so we start off with a dummy call to analogWrite: - analogWrite(AUDIO_CHANNEL_1_PIN, AUDIO_BIAS); + analogWrite(MOZZI_AUDIO_PIN_1, MOZZI_AUDIO_BIAS); // Set up fast PWM on the output pins // TODO: This is still very crude! pwm_config c = pwm_get_default_config(); pwm_config_set_clkdiv(&c, 1); // Fastest we can get: PWM clock running at full CPU speed - pwm_config_set_wrap(&c, 1l << AUDIO_BITS); // 11 bits output resolution means FCPU / 2048 values per second, which is around 60kHz for 133Mhz clock speed. - pwm_init(pwm_gpio_to_slice_num(AUDIO_CHANNEL_1_PIN), &c, true); - gpio_set_function(AUDIO_CHANNEL_1_PIN, GPIO_FUNC_PWM); - gpio_set_drive_strength(AUDIO_CHANNEL_1_PIN, GPIO_DRIVE_STRENGTH_12MA); // highest we can get -# if (AUDIO_CHANNELS > 1) -# if ((AUDIO_CHANNEL_1_PIN / 2) != (AUDIO_CHANNEL_2_PIN / 2)) -# error Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. Adjust AudioConfigRP2040.h . + pwm_config_set_wrap(&c, 1l << MOZZI_AUDIO_BITS); // 11 bits output resolution means FCPU / 2048 values per second, which is around 60kHz for 133Mhz clock speed. + pwm_init(pwm_gpio_to_slice_num(MOZZI_AUDIO_PIN_1), &c, true); + gpio_set_function(MOZZI_AUDIO_PIN_1, GPIO_FUNC_PWM); + gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get +# if (MOZZI_AUDIO_CHANNELS > 1) +# if ((MOZZI_AUDIO_PIN_1 / 2) != (MOZZI_AUDIO_PIN_1 / 2)) +# error Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. Adjust MOZZI_AUDIO_PIN_1/2 . # endif - gpio_set_function(AUDIO_CHANNEL_2_PIN, GPIO_FUNC_PWM); - gpio_set_drive_strength(AUDIO_CHANNEL_2_PIN, GPIO_DRIVE_STRENGTH_12MA); // highest we can get + gpio_set_function(MOZZI_AUDIO_PIN_2, GPIO_FUNC_PWM); + gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get # endif #endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) for (audio_update_alarm_num = 0; audio_update_alarm_num < 4; ++audio_update_alarm_num) { if (!hardware_alarm_is_claimed(audio_update_alarm_num)) { hardware_alarm_claim(audio_update_alarm_num); @@ -232,26 +233,26 @@ static void startAudio() { break; } } - micros_per_update = 1000000l / AUDIO_RATE; + micros_per_update = 1000000l / MOZZI_AUDIO_RATE; do { next_audio_update = make_timeout_time_us(micros_per_update); // See audioOutputCallback(), above. In _theory_ some interrupt stuff might delay us, here, causing us to miss the first beat (and everything that follows) } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update)); -#elif (RP2040_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S) - i2s.setBCLK(BCLK_PIN); - i2s.setDATA(DOUT_PIN); - i2s.setBitsPerSample(AUDIO_BITS); +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) + i2s.setBCLK(MOZZI_I2S_PIN_BCK); + i2s.setDATA(MOZZI_I2S_PIN_DATA); + i2s.setBitsPerSample(MOZZI_AUDIO_BITS); -#if (AUDIO_BITS > 16) - i2s.setBuffers(BUFFERS, (size_t) (BUFFER_SIZE/BUFFERS), 0); -#else - i2s.setBuffers(BUFFERS, (size_t) (BUFFER_SIZE/BUFFERS/2), 0); -#endif -#if (LSBJ_FORMAT == true) +# if (MOZZI_AUDIO_BITS > 16) + i2s.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS), 0); +# else + i2s.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS/2), 0); +# endif +# if MOZZI_IS(MOZZI_I2S_FORMAT, MOZZI_I2S_FORMAT_LSBJ) i2s.setLSBJFormat(); -#endif - i2s.begin(AUDIO_RATE); +# endif + i2s.begin(MOZZI_AUDIO_RATE); #endif } @@ -264,3 +265,6 @@ void stopMozzi() { } ////// END audio output code ////// + +#undef MOZZI_RP2040_BUFFERS +#undef MOZZI_RP2040_BUFFER_SIZE diff --git a/internal/config_checks_rp2040.h b/internal/config_checks_rp2040.h new file mode 100644 index 000000000..a6f056785 --- /dev/null +++ b/internal/config_checks_rp2040.h @@ -0,0 +1,57 @@ +#ifndef CONFIG_CHECK_RP2040_H +#define CONFIG_CHECK_RP2040_H + + +#if not IS_RP2040() +#error This header should be included for RP2040 architecture (Raspberry Pi Pico and others), only +#endif + +#if !defined(MOZZI_AUDIO_MODE) +# define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM +#endif +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_I2S_DAC) + +#if !defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 32768 +#endif + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) +# if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 11 +# endif +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 0 +# endif +# if !defined(MOZZI_AUDIO_PIN_2) +# define MOZZI_AUDIO_PIN_2 1 +# endif +#endif + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) +# if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 16 +# endif +# if !defined(MOZZI_I2S_PIN_BCK) +# define MOZZI_I2S_PIN_BCK 20 +# endif +//# define MOZZI_IS_PIN_WS(MOZZI_I2S_PIN_BCK + 1) // implicit +# if !defined(MOZZI_I2S_PIN_DATA) +# define MOZZI_I2S_PIN_DATA 22 +# endif +# if !defined(MOZZI_I2S_FORMAT) +# define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_PLAIN +# endif +MOZZI_CHECK_SUPPORTED(MOZZI_I2S_FORMAT, MOZZI_I2S_FORMAT_PLAIN, MOZZI_I2S_FORMAT_LSBJ) +# define BYPASS_MOZZI_OUTPUT_BUFFER true +# define MOZZI_RP2040_BUFFERS 8 // number of DMA buffers used +# define MOZZI_RP2040_BUFFER_SIZE 256 // total size of the buffer, in samples +#endif + +#if !defined(MOZZI_ANALOG_READ) +# define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD +#endif + +MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_ANALOG_READ_STANDARD) + +#endif // #ifndef CONFIG_CHECK_RP2040_H From 13daab68dce829a5214491507b3edfa168e64c06 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 19 Nov 2023 00:24:18 +0100 Subject: [PATCH 057/215] Start reorganizing port documentation --- MozziConfigExample.h | 217 ------------------ MozziGuts.h | 2 +- MozziGuts_impl_AVR.hpp | 4 +- MozziGuts_impl_ESP32.hpp | 5 +- MozziGuts_impl_ESP8266.hpp | 3 +- MozziGuts_impl_MBED.hpp | 2 +- MozziGuts_impl_SAMD.hpp | 1 + MozziGuts_impl_template.hpp | 43 ++-- README.md | 72 +----- ...heck_generic.h => config_checks_generic.h} | 6 +- internal/config_checks_stm32duino.h | 79 +++++++ internal/config_checks_stm32maple.h | 67 ++++++ internal/config_checks_teensy.h | 78 +++++++ internal/config_checks_template.h | 88 +++++++ 14 files changed, 354 insertions(+), 313 deletions(-) rename internal/{config_check_generic.h => config_checks_generic.h} (96%) create mode 100644 internal/config_checks_template.h diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 492a85ee2..0e63a43da 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -143,7 +143,6 @@ * * For simplicity, mozziAnalogRead() is always defined, but when MOZZI_ANALOG_READ s are disabled or unsupported, it simply relays * to Arduino's regular analogRead(). It is thus quite recommended _not_ to depend on mozziAnalogRead() when disabling this. - * Also setupFastAnalogReads() continues to be defined, for your convenience, but is not called automatically. TODO: rethink that! * * As a rough estimate (your numbers may differ a bit, depending on compiler version, etc.), on an ATMEGA328P (aka Arduino Uno), * disabling analog reads saves 33 bytes of RAM and 340 bytes of FLASH. The performance savings are theorized to be neglegible, however. @@ -660,219 +659,3 @@ */ - - -/***************************************** ADVANCED SETTTINGS -- STM32(duino) *********************************************************** - * - * The settings in the following section applies to the STM32(duino) architecture. - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - -/** @ingroup hardware -* @page hardware_stm32_disambiguation Mozzi on STM32-based boards - disambiguation -* -* * The situation on STM32-based boards is rather confusing, as there are several competing Arduino cores. Importantly: -* - Some boards use dedicated cores (e.g. Arduino Giga / Portenta @ref hardware_mbed) etc. For those, see the relevant sections (if we support them). -* - There is a series of libmaple-based cores, including [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32). These are highly optimized, -* and provide very complete support, but only for a limited number of boards. Unfortunately, at the time of this writing (2023/04), they are not available for installation -* via the Arduino Board Manager, and they do not currently seem actively maintained. -* For using these with Mozzi, see @ref hardware_stm32_maple -* - A generic Arduino core for STM32 is the [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32). It supports a huge step of boards, and seems to have offical -* backing by STM, but some features of the libmaple based cores are still lacking. To complete confusion, this core now uses the label "STM32duino", which used to be what -* the libmaple cores above were known by (don't blame Mozzi for this mess!). -* For using this with Mozzi, see @ref hardware_stm32duino -* -* */ - -/** @ingroup hardware - * @page hardware_stm32duino Mozzi on STM32duino-based boards. - * - * @note - * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32duino core. - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_PWM - * - MOZZI_OUTPUT_PWM_2PIN - * - * The default mode is @ref stm32duino_pwm . - * - * @note - * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32_maple ! - * - * @section stm32duino_pwm MOZZI_OUTPUT_PWM - * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PA8 (mono/left), PA9 (right channel in stereo). - * This mode uses two hardware timers: One for the PWM (Timer 3 when using the default pin configuration), and a second for updating the output at audio rate. - * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this. - * The following settings may be costumized, if desired: - * - * @code - * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PA8 - * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim, must not be the same of the timer for the above pin. Default TIM2 - * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10 - * // For stereo, only: - * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PA9 - * @endcode - * - * @section stm32duino_pwm MOZZI_OUTPUT_2PIN_PWM - * This mode is very similar to @ref stm32duino_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required - * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode. - * - * Customizable configuration options: - * @code - * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PA8 - * #define MOZZI_AUDIO_PIN_1_LOW ... // Low byte of the output. Default: PA9 - * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 - * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7 - * @endcode - * - * @section stm32duino_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio . - * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2). -*/ - - - -/***************************************** ADVANCED SETTTINGS -- STM32 (libmaple-based core) *********************************************************** - * - * The settings in the following section applies to the STM32 (libmaple-based core) architecture. - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - -/** @ingroup hardware - * @page hardware_stm32_maple Mozzi on STM32duino-based boards. - * - * @note - * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32 "libmaple based" core. - * - * @note - * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32duino ! - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_PWM - * - MOZZI_OUTPUT_PWM_2PIN - * - * The default mode is @ref stm32_maple_pwm . - * - * @section stm32_maple_pwm MOZZI_OUTPUT_PWM - * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PB8 (mono/left), PB9 (right channel in stereo). - * This mode uses two hardware timers: One for the PWM (Timer 4 when using the default pin configuration), and a second for updating the output at audio rate. - * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this. - * The following settings may be costumized, if desired: - * - * @code - * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PB8 - * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set ot the hardware timer connected to the above pin. Default: 4 - * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default 2 - * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10 - * // For stereo, only: - * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PB9 - * @endcode - * - * @section stm32_maple_pwm MOZZI_OUTPUT_2PIN_PWM - * This mode is very similar to @ref stm32_maple_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required - * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode. - * - * Customizable configuration options: - * @code - * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PB8 - * #define MOZZI_AUDIO_PIN_2 ... // Low byte of the output. Default: PB9 - * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set to the number of the hardware timer connect to the above pins. Default: 4 - * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 - * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7 - * @endcode - * - * @section stm32_maple_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio - * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2). -*/ - - -/***************************************** ADVANCED SETTTINGS -- Teensy 3.x *********************************************************** - * - * The settings in the following section applies to Teensy 3.x boards - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - -/** @ingroup hardware - * @page hardware_teensy3 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards. - * - * @note - * For Teensy 4.x see @ref hardware_teensy4 - * - * @note - * This port requires the following two libraries (which should be part of a default installtion, however): - * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 3.* by Daniel Gilbert - * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_INTERNAL_DAC - * - * The default mode is @ref teensy3_internal_dac . - * - * @section teensy3_internal_dac MOZZI_OUTPUT_INTERNAL_DAC - * Output is to the inbuilt DAC. Output resolution is 12 bits. Mono, only. The DAC output pin differs from board to boards. - * In most cases the appropriate pin will be set outmatically. If needed, you can specify the DAC pin, explicitly: - * - * @code - * #define MOZZI_AUDIO_PIN_1 ... // Default: A14, A12, or A21, depending on board - * @endcode - * - * @section teensy3_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio -*/ - -/***************************************** ADVANCED SETTTINGS -- Teensy 4.x *********************************************************** - * - * The settings in the following section applies to Teensy 4.x boards - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - -/** @ingroup hardware - * @page hardware_teensy4 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards. - * - * @note - * For Teensy 3.x see @ref hardware_teensy3 - * - * @note - * This port requires the following two libraries (which should be part of a default installtion, however): - * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 4.* by Daniel Gilbert - * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_PWM - * - * The default mode is @ref teensy4_pwm . - * - * @section teensy4_pwm MOZZI_OUTPUT_PWM - * Output is to a GPIO pin (or two in stereo). The output resolution is fixed at 10 bits, and a 146484 kHz carrier frequency. - * The output pins can be configured as: - * - * @code - * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: A8 - * // For stereo, only: - * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. Default: A9 - * @endcode - * - * @section teensy4_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio -*/ diff --git a/MozziGuts.h b/MozziGuts.h index 551f26be6..0056c51ca 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -31,7 +31,7 @@ #include "mozzi_analog.h" -#include "internal/config_check_generic.h" +#include "internal/config_checks_generic.h" #if (STEREO_HACK == true) extern int audio_out_1, audio_out_2; diff --git a/MozziGuts_impl_AVR.hpp b/MozziGuts_impl_AVR.hpp index d4d670880..e877c87b0 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/MozziGuts_impl_AVR.hpp @@ -85,8 +85,6 @@ void setupMozziADC(int8_t speed) { setupFastAnalogRead(speed); } -#endif - void setupFastAnalogRead(int8_t speed) { if (speed == FAST_ADC){ // divide by 16 ADCSRA |= (1 << ADPS2); @@ -103,6 +101,8 @@ void setupFastAnalogRead(int8_t speed) { } } +#endif + ////// END analog input code //////// diff --git a/MozziGuts_impl_ESP32.hpp b/MozziGuts_impl_ESP32.hpp index 172e38a7f..b20c92772 100644 --- a/MozziGuts_impl_ESP32.hpp +++ b/MozziGuts_impl_ESP32.hpp @@ -29,11 +29,10 @@ void startSecondADCReadOnCurrentChannel() { } void setupMozziADC(int8_t speed) { } -#endif - void setupFastAnalogRead(int8_t speed) { -#warning Fast analog read not implemented on this platform } + +#endif ////// END analog input code //////// diff --git a/MozziGuts_impl_ESP8266.hpp b/MozziGuts_impl_ESP8266.hpp index 6c8ca63f2..3d4f3c11d 100644 --- a/MozziGuts_impl_ESP8266.hpp +++ b/MozziGuts_impl_ESP8266.hpp @@ -29,10 +29,9 @@ void startSecondADCReadOnCurrentChannel() { } void setupMozziADC(int8_t speed) { } -#endif void setupFastAnalogRead(int8_t speed) { -#warning Fast analog read not implemented on this platform } +#endif ////// END analog input code //////// diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index 56b2370fc..f9784bad8 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -54,6 +54,7 @@ static void startAudioInput() {}; // dummy to ease coding #endif #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) +#error not yet implemented /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of USE_AUDIO_INPUT (if enabled). * This template provides empty/dummy implementations to allow you to skip over this section, initially. Once you have an implementation, be sure to enable the * #define, above */ @@ -91,7 +92,6 @@ void startSecondADCReadOnCurrentChannel() { /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize. * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */ void setupFastAnalogRead(int8_t speed) { -#warning Fast analog read not implemented on this platform } /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and diff --git a/MozziGuts_impl_SAMD.hpp b/MozziGuts_impl_SAMD.hpp index 4602cc920..b885a28fe 100644 --- a/MozziGuts_impl_SAMD.hpp +++ b/MozziGuts_impl_SAMD.hpp @@ -16,6 +16,7 @@ ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, NOZZI_ANALOG_READ_STANDARD) +#error not yet implemented #define getADCReading() 0 #define channelNumToIndex(channel) channel uint8_t adcPinToChannelNum(uint8_t pin) { diff --git a/MozziGuts_impl_template.hpp b/MozziGuts_impl_template.hpp index 159393ee8..154c1ee29 100644 --- a/MozziGuts_impl_template.hpp +++ b/MozziGuts_impl_template.hpp @@ -16,9 +16,9 @@ * Files involved: * 1. Modify hardware_defines.h, adding a macro to detect your target platform * 2. Modify MozziGuts.cpp to include MozziGuts_impl_YOURPLATFORM.hpp - * 3. Modify MozziGuts.h to include AudioConfigYOURPLATFORM.h - * 4. Copy this file to MozziGuts_impl_YOURPLATFORM.hpp and adjust as necessary - * (If your platform is very similar to an existing port, it may instead be better to modify the existing MozziGuts_impl_XYZ.hpp/AudioConfigYOURPLATFORM.h, + * 3. Modify internal/config_checks_generic.h to include internal/config_checks_YOURPLATFORM.h + * 4. Copy this file to MozziGuts_impl_YOURPLATFORM.hpp and adjust as necessary, same for internal/config_checks_template.h + * (If your platform is very similar to an existing port, it may instead be better to modify the existing MozziGuts_impl_XYZ.hpp/config_checks_XYZ.h, * instead of steps 2-3.). * Some platforms may need small modifications to other files as well, e.g. mozzi_pgmspace.h * @@ -51,8 +51,9 @@ * #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD * #endif * - * The only function in this section that is always defined is setupFastAnalogRead() (but this, too, may be left empty, initially). + * Also, of course, remove the #error line, below */ +#error not yet implemented // Insert here code to read the result of the latest asynchronous conversion, when it is finished. // You can also provide this as a function returning unsigned int, should it be more complex on your platform @@ -99,14 +100,13 @@ void stm32_adc_eoc_handler() { } */ -#endif - /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize. * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */ void setupFastAnalogRead(int8_t speed) { -#warning Fast analog read not implemented on this platform } +#endif + ////// END analog input code //////// ////// BEGIN audio output code ////// @@ -121,23 +121,34 @@ void setupFastAnalogRead(int8_t speed) { * analog reads for instance. */ //#define AUDIO_HOOK_HOOK -#if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user -/** NOTE: This is the function that actually write a sample to the output. In case of EXTERNAL_AUDIO_OUTPUT == true, it is provided by the library user, instead. */ +/* NOTE: Code sections that are needed for a certain audio mode, only, should be guarded as follows (in this example, code will compile for the + * two modes MOZZI_OUTPUT_PWM, and MOZZI_OUTPUT_INTERNAL_DAC (should your port happen to support these two). + * + * Keep in mind that you probably want to support MOZZI_OUTPUT_EXTERNAL_TIMED, and MOZZI_OUTPUT_EXTERNAL_CUSTOM, too, which is usually very + * easy: For both, do *not* provide an audioOutput() function, as this will be provided by the user. For MOZZI_OUTPUT_EXTERNAL_TIMED make sure some + * timer is set up to call defaultAudioOutput() at MOZZI_AUDIO_RATE. For MOZZI_OUTPUT_EXTERNAL_CUSTOM, nothing else will be needed. */ + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC) // just an example! +/** NOTE: This is the function that actually write a sample to the output. In case of the two EXTERNAL modes, it is provided by the library user, instead. */ inline void audioOutput(const AudioOutput f) { - // e.g. analogWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS); -#if (AUDIO_CHANNELS > 1) - // e.g. analogWrite(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS); -#endif + // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_1_PIN, f.l()+MOZZI_AUDIO_BIAS); +# if (MOZZI_AUDIO_CHANNELS > 1) + // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_2_PIN, f.r()+MOZZI_AUDIO_BIAS); +# endif } #endif static void startAudio() { // Add here code to get audio output going. This usually involves: // 1) setting up some DAC mechanism (e.g. setting up a PWM pin with appropriate resolution - // 2a) setting up a timer to call defaultAudioOutput() at AUDIO_RATE + // 2a) setting up a timer to call defaultAudioOutput() at MOZZI_AUDIO_RATE // OR 2b) setting up a buffered output queue such as I2S (see ESP32 / ESP8266 for examples for this setup) -#if (EXTERNAL_AUDIO_OUTPUT != true) - // remember that the user may configure EXTERNAL_AUDIO_OUTPUT, in which case, you'll want to provide step 2a), and only that. +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) + // [...] +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) + // [...] +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) + // remember that the user may configure MOZZI_OUTPUT_EXTERNAL_TIMED, in which case, you'll want to provide step 2a), and only that. #endif } diff --git a/README.md b/README.md index 5bcdc23d9..a25b5c1d7 100644 --- a/README.md +++ b/README.md @@ -190,79 +190,15 @@ Various examples from [Pure Data](http://puredata.info/) by Miller Puckette ## Hardware specific notes -### STM32 -The situation on STM32-based boards is rather confusing, as there are several competing Arduino cores. Importantly: -- Some boards use dedicated cores (e.g. Arduino Giga / Protenta) etc. For those, see the relevant sections (if we support them) -- There is a series of libmaple-based cores, including [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32). These are highly optimized, and provide very complete support, but only for a limited number of boards. Unfortunately, at the time of this writing (2023/04), they are not available for installation via the Arduino Board Manager, and they do not currently seem actively maintained. -- A generic Arduino core for STM32 is the [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32). It supports a huge step of boards, and seems to have offical backing by STM, but some features of the libmaple based cores are still lacking. To complete confusion, this core now uses the label "STM32duino", which used to be what the libmaple cores above were known by (don't blame Mozzi for this mess!). - -Mozzi supports both of the latter, but currently not at the same level of completeness. - -#### STM32 libmaple based -port by Thomas Friedrichsmeier - -Compiles for and runs on a STM32F103C8T6 blue pill board, with a bunch of caveats (see below), i.e. on a board _without_ a -real DAC. Should probably run on any other board supported by [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32) (although this theory is untested). - -*NOTE* that at the time of this writing, [Stev Strong's slightliy more recent fork of this core](https://github.com/stevstrong/Arduino_STM32/) does *not* work with -Mozzi, apparently due to a bug in pwmWrite(). - -- You will need a very recent checkout of the Arduino_STM32 repository, otherwise compilation will fail. -- Audio output is to pin PB8, by default (HIFI-mode: PB8 and PB9) -- If you want to use MIDI, be sure to replace "MIDI_CREATE_DEFAULT_INSTANCE()" with "MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI)" (or Serial2) -- Timers 4 (PWM output), and 2 (audio rate) are used by default. -- The STM32-specific options (pins, timers) can be configured in AudioConfigSTM32.h -- Default audio resolution is currently set to 10 bits, which yields 70khZ PWM frequency on a 72MHz CPU. HIFI mode is 2*7bits at up to 560Khz (but limited to 5 times audio rate) -- AUDIO_INPUT is completely untested (but implemented in theory) -- Note that AUDIO_INPUT and mozziAnalogRead() return values in the STM32's full ADC resolution of 0-4095 rather than AVR's 0-1023. -- twi_nonblock is not ported - -#### STM32 STM32duino -port by Thomas Friedrichsmeier - -Tested on a STM32F103C8T6 blue pill board as well as an STM32F411CE black pill board, i.e. on sboards _without_ a -real DAC. Compiles and runs, with a bunch of caveats (see below). Should probably run on any other board supported by the -[STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32) (although this theory is untested). -When trying any other board, you probably want to check the platform specific settings (see below), carefully, importantly, whether the desired output resolution is -achievable, and whether the desired output pins are PWM capable. - -- Audio output is PWM-based to pin PA8, by default (HIFI-mode: PA8 and PA9) -- Timers 3 (PWM output), and 2 (audio rate) are used by default. -- The STM32-specific options (pins, timers) can be configured in AudioConfigSTM32duino.h -- Default audio resolution is currently set to 10 bits, which yields 70khZ PWM frequency on a 72MHz CPU. IMPORTANT: Should your CPU be slower, you will need to lower the audio resolution! -- HIFI mode is 2*7bits at up to 560Khz with a 72MHz CPU (but limited to 5 times audio rate) -- Analog input implementation is somewhat experimental, and may not be able to service a whole lot of pins (contributions welcome) -- AUDIO_INPUT is completely untested (but implemented in theory) -- Note that AUDIO_INPUT and mozziAnalogRead() return values in the STM32's full ADC resolution (the exact range depending on the board in use) rather than AVR's 0-1023. -- twi_nonblock is not ported +TODO link to hardware section in API docs +TODO list just the basic headers, here. ### Teensy 3.0/3.1/3.2/3.4/3.5/LC -This port is working with the latest version of Teensyduino (1.8.5) -Extra libraries required for use with Teensy 3.*: -These are included in the standard Teensyduino install unless you explicitly disable them -- [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 3.* by Daniel Gilbert -- [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva - -Some of the differences for Teensy 3.* which will affect users include: - -- On Teeensy 3.0/3.1/3.2/Audio output is on pin A14/DAC, in STANDARD or STANDARD_PLUS audio modes. - These modes are identical on Teensy 3.0/3.1/3.2, as the output is via DAC rather than PWM. -- Output is 12 bits in STANDARD and STANDARD_PLUS modes, up from nearly 9 bits for Atmel based boards. HIFI audio, which works by summing two output pins, is not available on Teensy 3.0/3.1. -- twi_nonblock code by Marije Baalman for non-blocking I2C is not compatible with Teensy 3.0/3.1/3.2. ### Teensy 4.0/4.1 -port by Thomas Combriat - -This port is working with the latest version of Teensyduino (1.8.5) -Extra libraries required for use with Teensy 4.*: -These are included in the standard Teensyduino install unless you explicitly disable them -- [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 3.* by Daniel Gilbert -- [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva -Some of the differences for Teensy 4.*: - -- Contrary to the Teensy 3, the Teensy 4 do not have any DAC. The output is done on pin A8 (PWM) by default (editable in `AudioConfigTeensy4.h` +### STM32 ### SAMD21 architecture (Arduino Circuitplayground M0 and others) port by Adrian Freed @@ -294,7 +230,7 @@ port by Thomas Friedrichsmeier - _Any_ WiFi-activity can cause severe spikes in power consumption. This can cause audible "ticking" artifacts, long before any other symptoms. - If you do not require WiFi in your sketch, you should turn it off, _explicitly_, using `WiFi.mode(WIFI_OFF)`. - A juicy enough, well regulated power supply, and a stabilizing capacitor between VCC and Gnd can help a lot. - - As the (PDM) output signal is digital, a single transistor can be used to amplify it to an independent voltage level. + - As the (PDM) output signal is digital, a single (fast!) transistor can be used to amplify it to an independent voltage level. - The audio output resolution is always 16 bits on this platform, _internally_. Thus, in updateAudio(), you should scale your output samples to a full 16 bit range. The effective number of output bits cannot easily be quantified, due to PDM coding. - audioHook() calls `yield()` once for every audio sample generated. Thus, as long as your audio output buffer does not run empty, you should not need any additional `yield()`s inside `loop()`. diff --git a/internal/config_check_generic.h b/internal/config_checks_generic.h similarity index 96% rename from internal/config_check_generic.h rename to internal/config_checks_generic.h index 502c6ae13..df29fe621 100644 --- a/internal/config_check_generic.h +++ b/internal/config_checks_generic.h @@ -80,9 +80,9 @@ #endif -/// Step 2b: Minimal special handling for MOZZI_OUTPUT_EXTERNAL -#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL) && !defined(MOZZI_AUDIO_BITS) -#define MOZZI_AUDIO_BITS 16 +/// Step 2b: Minimal special handling for MOZZI_OUTPUT_EXTERNAL_TIMED/CUSTOM +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) && !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 16 #endif diff --git a/internal/config_checks_stm32duino.h b/internal/config_checks_stm32duino.h index 5fc06d365..3c3f1d419 100644 --- a/internal/config_checks_stm32duino.h +++ b/internal/config_checks_stm32duino.h @@ -1,6 +1,85 @@ #ifndef CONFIG_CHECKS_STM32DUINO_H #define CONFIG_CHECKS_STM32DUINO_H +/** @ingroup hardware +* @page hardware_stm32_disambiguation Mozzi on STM32-based boards - disambiguation +* +* * The situation on STM32-based boards is rather confusing, as there are several competing Arduino cores. Importantly: +* - Some boards use dedicated cores (e.g. Arduino Giga / Portenta @ref hardware_mbed) etc. For those, see the relevant sections (if we support them). +* - There is a series of libmaple-based cores, including [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32). These are highly optimized, +* and provide very complete support, but only for a limited number of boards. Unfortunately, at the time of this writing (2023/04), they are not available for installation +* via the Arduino Board Manager, and they do not currently seem actively maintained. +* For using these with Mozzi, see @ref hardware_stm32_maple +* - A generic Arduino core for STM32 is the [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32). It supports a huge set of boards, and seems to have offical +* backing by STM, but some features of the libmaple based cores are still lacking. To complete confusion, this core now uses the label "STM32duino", which used to be what +* the libmaple cores above were known by (don't blame Mozzi for this mess!). +* For using this with Mozzi, see @ref hardware_stm32duino +* */ + +/** @ingroup hardware + * @page hardware_stm32duino Mozzi on STM32duino-based boards. + * + * port by Thomas Friedrichsmeier + * + * @note + * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32duino core. + * + * @section stm32duino_status Port status and usage notes + * Tested on a STM32F103C8T6 blue pill board as well as an STM32F411CE black pill board, i.e. on sboards _without_ a + * real DAC. Compiles and runs, with a bunch of caveats (see below). Should probably run on any other board supported by the + * [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32) (although this theory is untested). + * When trying any other board, you probably want to check the platform specific settings (see below), carefully, importantly, whether the desired output resolution is + * achievable, and whether the desired output pins are PWM capable. + * + * - @ref MOZZI_ANALOG_READ input implementation is somewhat experimental, and may not be able to service a whole lot of pins (contributions welcome) + * - @ref MOZZI_AUDIO_INPUT is completely untested (but implemented in theory; feedback welcome!) + * - getAudioInput() and mozziAnalogRead() return values in the STM32's full ADC resolution (the exact range depending on the board in use) rather than AVR's 0-1023. + * - twi_nonblock is not ported + * + * @section stm32duino_output_modes Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PWM + * - MOZZI_OUTPUT_PWM_2PIN + * + * The default mode is @ref stm32duino_pwm . + * + * @note + * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32_maple ! + * + * @section stm32duino_pwm MOZZI_OUTPUT_PWM + * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PA8 (mono/left), PA9 (right channel in stereo). + * This mode uses two hardware timers: One for the PWM (Timer 3 when using the default pin configuration), and a second for updating the output at audio rate. + * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this. + * The following settings may be costumized, if desired: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PA8 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim, must not be the same of the timer for the above pin. Default TIM2 + * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10 + * // For stereo, only: + * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PA9 + * @endcode + * + * @section stm32duino_pwm MOZZI_OUTPUT_2PIN_PWM + * This mode is very similar to @ref stm32duino_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required + * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode. + * Output is at 2*7 bits at up to 560kHz carrier frequency (but limited to 5 times audio rate). + * + * Customizable configuration options: + * @code + * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PA8 + * #define MOZZI_AUDIO_PIN_1_LOW ... // Low byte of the output. Default: PA9 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 + * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7 + * @endcode + * + * @section stm32duino_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio . + * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2). +*/ + #if not IS_STM32DUINO() #error This header should be included for STM32 (stm32duino.com core), only #endif diff --git a/internal/config_checks_stm32maple.h b/internal/config_checks_stm32maple.h index fab281fdf..27b08736f 100644 --- a/internal/config_checks_stm32maple.h +++ b/internal/config_checks_stm32maple.h @@ -1,6 +1,73 @@ #ifndef CONFIG_CHECKS_STM32MAPLE_H #define CONFIG_CHECKS_STM32MAPLE_H +/** @ingroup hardware + * @page hardware_stm32_maple Mozzi on STM32duino-based boards. + * port by Thomas Friedrichsmeier + * + * @note + * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32 "libmaple based" core. + * + * @note + * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32duino ! + * + * @section stm32_maple_status Status and peculiarities of this port + * Compiles for and runs on a STM32F103C8T6 blue pill board, with a bunch of caveats (see below), i.e. on a board _without_ a + * real DAC. Should probably run on any other board supported by [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32) (although this theory is untested). + * + * @note that at the time of this writing, [Stev Strong's slightliy more recent fork of this core](https://github.com/stevstrong/Arduino_STM32/) does *not* work with + * Mozzi, apparently due to a bug in pwmWrite(). + * + * - If you want to use MIDI, be sure to replace "MIDI_CREATE_DEFAULT_INSTANCE()" with "MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI)" (or Serial2) + * - @ref MOZZI_AUDIO_INPUT_STANDARD is implemented in theory, but untested (feedback welcome) + * - getAudioInput() and mozziAnalogRead() return values in the STM32's full ADC resolution of 0-4095 rather than AVR's 0-1023. + *- twi_nonblock is not ported + * + * @section stm32_output_modes Output modes + * + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PWM + * - MOZZI_OUTPUT_PWM_2PIN + * + * The default mode is @ref stm32_maple_pwm . + * + * @section stm32_maple_pwm MOZZI_OUTPUT_PWM + * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PB8 (mono/left), PB9 (right channel in stereo). + * This mode uses two hardware timers: One for the PWM (Timer 4 when using the default pin configuration), and a second for updating the output at audio rate. + * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this. + * The following settings may be costumized, if desired: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PB8 + * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set ot the hardware timer connected to the above pin. Default: 4 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default 2 + * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10 + * // For stereo, only: + * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PB9 + * @endcode + * + * @section stm32_maple_2pin_pwm MOZZI_OUTPUT_2PIN_PWM + * This mode is very similar to @ref stm32_maple_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required + * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode. + * Output is at 2*7 bits at up to 560kHz carrier frequency (but limited to 5 times audio rate). + * + * Customizable configuration options: + * @code + * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PB8 + * #define MOZZI_AUDIO_PIN_2 ... // Low byte of the output. Default: PB9 + * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set to the number of the hardware timer connect to the above pins. Default: 4 + * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2 + * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7 + * @endcode + * + * @section stm32_maple_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio + * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2). +*/ + + #if not IS_STM32MAPLE() #error This header should be included for STM32 (libmaple based core), only #endif diff --git a/internal/config_checks_teensy.h b/internal/config_checks_teensy.h index 0913876d7..ea7143e5d 100644 --- a/internal/config_checks_teensy.h +++ b/internal/config_checks_teensy.h @@ -1,10 +1,88 @@ #ifndef CONFIG_CHECK_TEENSY_H #define CONFIG_CHECK_TEENSY_H +/** @ingroup hardware + * @page hardware_teensy3 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards. + * + * port by Thomas Combriat + * + * @note + * For Teensy 4.x see @ref hardware_teensy4 + * + * @section teensy3_status Port status and ussage notes + * This port requires the following two libraries (which should be part of a default installtion, however): + * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 3.* by Daniel Gilbert + * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva + * + * Some of the differences for Teensy 3.* which will affect users include: + * - twi_nonblock code by Marije Baalman for non-blocking I2C is not compatible with Teensy 3.0/3.1/3.2. + * + * @section teensy3_output Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref teensy3_internal_dac . + * + * @section teensy3_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * Output is to the inbuilt DAC. Output resolution is 12 bits. Mono, only. The DAC output pin differs from board to boards. + * In most cases the appropriate pin will be set outmatically. If needed, you can specify the DAC pin, explicitly: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // Default: A14, A12, or A21, depending on board + * @endcode + * + * @section teensy3_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + + +/** @ingroup hardware + * @page hardware_teensy4 Mozzi on Teensy 4.x boards. + * + * port by Thomas Combriat + * + * @note + * For Teensy 3.x see @ref hardware_teensy3 + * + * @section teensy4_status Port status and ussage notes + * This port requires the following two libraries (which should be part of a default installtion, however): + * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 4.* by Daniel Gilbert + * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva + * + * Contrary to the Teensy 3, the Teensy 4 do not have any DAC. The output is done on pin A8 (PWM) by default (see below). + * twi_nonblock is not ported. + * + * @section teensy3_output Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PWM + * + * The default mode is @ref teensy4_pwm . + * + * @section teensy4_pwm MOZZI_OUTPUT_PWM + * Output is to a GPIO pin (or two in stereo). The output resolution is fixed at 10 bits, and a 146484 kHz carrier frequency. + * The output pins can be configured as: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: A8 + * // For stereo, only: + * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. Default: A9 + * @endcode + * + * @section teensy4_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + + #if !(IS_TEENSY3() || IS_TEENSY4()) #error This header should be included for Teensy (3.x or 4.x) boards, only #endif + + #if IS_TEENSY3() # if !defined(MOZZI_AUDIO_MODE) # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC diff --git a/internal/config_checks_template.h b/internal/config_checks_template.h new file mode 100644 index 000000000..f957545f0 --- /dev/null +++ b/internal/config_checks_template.h @@ -0,0 +1,88 @@ +/** NOTE Template only: Copy and adjust this file when adding a new port. + * + * More instructions on the process are to be found in MozziGuts_impl_template.hpp. Read those first! + * + * What this file shall do: + * 1) Set default values for certain configurable options. Try to stick to the defines already in use as much as possible, + * so configuration is consistent across ports. + * 2) Have some checks for configuration values that are not supported on this port + * 3) Document some details of your port + */ + +/** NOTE: All ports need to provide a default for this */ +#if not defined(MOZZI_AUDIO_MODE) +# define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM +#endif +/** NOTE: And all ports should allow only supported output modes. Note that MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM +are usually trivial to implement, so we'll assume your port allows them, too: */ +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) + +/** NOTE: All ports need to provide a default for this. 32768 is reasonable on most modern MCUs, but 16384 may be useful for weaker MCUs. */ +#if not defined(MOZZI_AUDIO_RATE) +# define MOZZI_AUDIO_RATE 32768 +#endif + +/** NOTE: *If* your port has an implementation for asynchronous analog reads, these shall be enabled by default. */ +#if not defined(MOZZI_ANALOG_READ) +# define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD +#endif +/** NOTE: *Otherwise* you may additionally document that as not-yet-supported like so: */ +// MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ) + +/** NOTE: Example for additional config options depending on a specific output mode: */ +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_INTERNAL_DAC) +# if !defined(MOZZI_AUDIO_PIN_1) +# define MOZZI_AUDIO_PIN_1 5 +# endif +/** NOTE: All ports need to provide a default for this, for all audio modes _except_ for the external ones: */ +# if !defined(MOZZI_AUDIO_BITS) +# define MOZZI_AUDIO_BITS 10 +# endif +/** NOTE: If only mono is supported in this output mode: */ +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO) +#endif + +/** NOTE: You may also set further, implementation-specific defines, here. E.g. BYPASS_MOZZI_OUTPUT_BUFFER. Defines that are purely + * specific to your port (i.e. only needed inside MozziGuts_impt_YOURPLATFORM.h, should be #undef'ed at the end of that file. */ + + +/** NOTE: The following is an example documentation for your port. In order not to end up in the real documentation, the comment starts + * with "/*", only. Change that to "/**" to enable documentation to be extracted. */ + +/* @ingroup hardware + * @page hardware_MYPORT Mozzi on MYPORT architecture based boards (e.g. MOST PROMINENT BOARD) + * + * Port added by YOUR_NAME. + * + * @section MYPORT_status Status of this port and usage notes + * This port has been tested on BOARD A, BOARD B, but is expected to work on other boards using this family of MCUs, too. + * The default MOZZI_AUDIO_RATE is set to 32678 Hz. Asynchronous analog reads are not yet implemented, so be careful + * not to use mozziAnalogRead() too much. Also @ref MOZZI_AUDIO_INPUT is not available. + * + * When connecting external circuitry, keep in mind that the GPIO pins on this CPU are rated at a max of 3 mA. Be careful + * not to over-stress them. It is further recommended not to make use of feature X when using Mozzi, as it will + * introduce considerable noise into the audio. + * + * Also, something else to keep in mind about this port. + * + * @section MYPORT_output_modes Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref MYPORT_internal_dac , meaning, only boards with an inbuilt DAC are covered by default + * (you could stil use one of the external output modes, however). + * + * @section MYPORT_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * Output resolution is 10 bits by default, and goes to pin DAC0. Hardware timer 1 is claimed by Mozzi. + * Only mono output is supported. Within the hardware limits of your board, you can configure the following: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // default is DAC0 + * #define MOZZI_AUDIO_BITS ... // default is 10 + * @endcode + * + * @section MYPORT_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ From 1c4567f8543634a75fefe8869e9930f7553cc43a Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 19 Nov 2023 10:54:47 +0100 Subject: [PATCH 058/215] De-duplicate documentation --- MozziConfigExample.h | 451 ++----------------------------- README.md | 167 +++--------- internal/config_checks_avr.h | 79 +++++- internal/config_checks_esp32.h | 65 +++++ internal/config_checks_esp8266.h | 56 ++++ internal/config_checks_mbed.h | 51 ++++ internal/config_checks_renesas.h | 33 +++ internal/config_checks_rp2040.h | 56 ++++ internal/config_checks_samd21.h | 30 ++ internal/config_checks_teensy.h | 2 +- mozzi_config.h | 9 +- 11 files changed, 437 insertions(+), 562 deletions(-) diff --git a/MozziConfigExample.h b/MozziConfigExample.h index 0e63a43da..b9c0eb538 100644 --- a/MozziConfigExample.h +++ b/MozziConfigExample.h @@ -1,30 +1,23 @@ -/*! @ingroup core - * @file MozziConfigExample.h +/*! @defgroup config Mozzi Configuration options + * @section Mozzi Configuration * * @brief Mozzi Configuration * * @note * It is generally safe to leave the Mozzi Configuration unchanged, and that's very much recommended _until_ you have a very specific need to customize something. + * Contrary to past versions of Mozzi, all configuration options have a (usually sensible) default value, so you do not have to configure _anything_, unless you + * actually want to change something. + * + * Configuring Mozzi is mostly done using various preprocessor definitions. This approach is used to move as much of the processing involved to compile time, in order + * to save Flash, RAM, and CPU use at runtime. This section lists various global options, but in addition, most ports allow additional hardware dependent + * configuration options. See @ref hardware. + * + * Several configuration examples are provided in the "config" folder of the Mozzi sources. You may want to look at these, first. * - * Usage: - * - either: - * 1. Copy this file to your sketch directory - * 2. Adjust as desired, uncommenting only those options that you intend to change from their default value - * 3. #include it in your sketch **before** #include - * (must be included in each .cpp-file using Mozzi inside your sketch, if more than one) - * - or: - * 1. Copy only the sections you want to customize - * 2. Put them near the top of your sketch **before** #include - * (should your sketch have more than one .cpp-file, identical options need to be set before each #include ) - * * TODO: Fix and complete Doxygen coverage - * TODO: Probably the recommendation to copy this whole file is over the top, perhaps provide stripped-down examples, instead - * TODO: Move all the hardware depended stuff to the corresponding config_checks_xyz.h, to increase the chances that doc and implementation remain in sync */ -#include // needed for the named option values - -/** @ingroup core +/** @ingroup config * @def MOZZI_COMPATIBILITY_LEVEL * * Mozzi generally tries to keep your old sketches working, but we continue to find new (and hopefully better) approaches to old problems. @@ -39,9 +32,8 @@ * @note * MOZZI_COMPATIBILITY_V1_1 does not guarantee, that *everything* from Mozzi 1.1 will continue to work, just that we're doing a reasonable effort. */ -//#define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_LATEST -/** @ingroup core +/** @ingroup config * @def MOZZI_AUDIO_MODE * * @brief Configure how Mozzi outputs generated sounds. @@ -52,7 +44,7 @@ * hardware setup is correct. Similarly, if you observe problems running your "real" sketch, it is often a good idea ot test your sketch with the default audio mode, * too (by leaving this option, and preferrably all others, unset). * - * TODO: link to specific documentation for each option/platform, here, and/or spell out, what is supported, where + * Refer to the @ref hardware specific documentation for which modes are supported on your hardware, and further details! * * Supported values: * - MOZZI_OUTPUT_PWM Output using pulse width modulation (PWM) on a GPIO pin. This is the default on most platforms. @@ -70,10 +62,9 @@ * * TODO: Adding an R2R-DAC option would be cool, http://blog.makezine.com/2008/05/29/makeit-protodac-shield-fo/ , some discussion on Mozzi-users. */ -//#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM -/** @ingroup core +/** @ingroup config * @def MOZZI_AUDIO_CHANNELS * * This sets allows to change from a single/mono audio output channel to @@ -88,11 +79,9 @@ * @note At the time of this writing, only MOZZI_MONO and MOZZI_STEREO are supported. The value of * MOZZI_MONO is 1 and the value of MOZZI_STEREO is 2, so future extensions are also expected * to set this to the number of available channels, and it's ok to use numerical comparison. */ -//#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO - -/** @ingroup core +/** @ingroup config * @def MOZZI_AUDIO_RATE * * @brief Defines the audio rate, i.e. rate of samples output per second. @@ -112,11 +101,10 @@ * It is advised to use only MOZZI_AUDIO_RATE in new code, however. * TODO: Only do the above, if MozziGuts.h, rather than Mozzi.h was included? */ -//#define MOZZI_AUDIO_RATE 32768 -/** @ingroup core +/** @ingroup config * @def MOZZI_CONTROL_RATE * * @brief Control rate setting. @@ -132,10 +120,9 @@ * * TODO: If a definition of CONTROL_RATE is detected, apply that with a warning. */ -//#define MOZZI_CONTROL_RATE 256 -/** @ingroup core +/** @ingroup config * @def MOZZI_ANALOG_READ * * Whether to compile in support for non-blocking analog reads. This is enabled by default on platforms that support it, but may be @@ -153,10 +140,9 @@ * - MOZZI_ANALOG_READ_STANDARD * Analog read implementation enabled (currently there is only the "standard" method, but future versions might allow additional choice, here). */ -//#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE -/** @ingroup core +/** @ingroup config * @def MOZZI_AUDIO_INPUT * * Whether to enable built in audio input feature. This is not supported on all platforms, and @@ -172,105 +158,16 @@ * * Further reading and config: @ref getAudioInput() @ref MOZZI_AUDIO_INPUT_PIN */ -//#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD - -/** @ingroup core +/** @ingroup config * @def MOZZI_AUDIO_INPUT_PIN * * This sets which analog input channel to use for audio input, if you have enabled MOZZI_AUDIO_INPUT, above. * Not all pins may be available for this, be sure to check the documentation for your platform. */ -//#define MOZZI_AUDIO_INPUT_PIN 0 - - - - -/***************************************** ADVANCED SETTTINGS -- AVR *********************************************************** - * - * The settings in the following section applies to the AVR architecture (classic Arduino, and further 8bit ATMEGA based boards), - * only. - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - - -/** @ingroup hardware - * @page hardware_avr Mozzi on classic Arduino, Teensy (2.x and 3.x), Arduino Mega, and other 8 bit "AVR"/ATMEGA architecture boards - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware. In all cases, Timer 1 is claimed, and - * is not available for any other purpose: - * - MOZZI_OUTPUT_PWM - * - MOZZI_OUTPUT_2PIN_PWM - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - * In all cases, except MOZZI_OUTPUT_EXTERNAL_CUSTOM, Timer 1 is claimed, and is not available for any other purpose. - * - * @section avr_pwm MOZZI_OUTPUT_PWM - * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured - * within this tight limit. In particular, the default setup on the - * Arduino UNO is: - * - Mono: Pin 9 -> configurable using MOZZI_AUDIO_PIN_1 - * - Stereo: Pin 9 (left) and Pin 10 (right) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_2 - * For pinouts on other boards, refer to config/known_16bit_timers. - * - * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE: MOZZI_PWM_RATE. - * - * The available sample resolution is 488, i.e. almost 9 bits, providing some headroom above the 8 bit table resolution - * currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate. - * - * @section avr_2pin_pwm MOZZI_OUTPUT_2PIN_PWM - * In this mode, output is split across two pins (again, both connected to Timer 1), with each outputting 7 bits for a total of 14. This allows for - * much better dynamic range, providing much more definition than can be achieved using @ref avr_pwm , while using - * only modestly more processing power. Further, it allows for a much higher PWM carrier rate can be much higher (125 kHz by default; see @ref - * MOZZI_PWM_RATE), which is well beyond the audible range. - * - * On the downside, this mode requires an extra hardware timer (Timer2 in addition to Timer1), which may increase compatibility - * problems with other Arduino libraries that also require a timer. Further, a more elaborate hardware setup is needed, making it less convenient - * for rapid prototyping: - * - * In hardware, add the two signals through a 3.9k resistor on the "high" pin and 499k resistor on "low" pin. - * Use 0.5% resistors or select the most accurate from a batch. It is further recommended to place a 4.7nF capacitor between the summing junction - * of the resistors and ground. This is discussed in much more detail on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ - * Also, there are higher quality output circuits are on the site. - * - * On the classic Arduino Uno, the default pinout in this mode is: - * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW - * - * Here is table of the default pins on some other boards. Rows with an x on it have actually been tested (and importantly, the outcome recoreded; - * input welcome on further boards.) - * - * resistor.....3.9k......499k \n - * x................9..........10...............Arduino Uno \n - * x................9..........10...............Arduino Duemilanove \n - * x................9..........10...............Arduino Nano \n - * x................9..........10...............Arduino Leonardo \n - * x................9..........10...............Ardweeny \n - * x................9..........10...............Boarduino \n - * x...............11.........12...............Freetronics EtherMega \n - * .................11.........12...............Arduino Mega \n - * .................14.........15...............Teensy \n - * .............B5(14)...B6(15)...........Teensy2 \n - * x...........B5(25)...B6(26)...........Teensy2++ \n - * .................13.........12...............Sanguino \n - * - * For pinouts on other AVR boards, config/known_16bit_timers might contain some hints. - * - * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE, and is much higher (125kHz), by default: MOZZI_PWM_RATE. - * - * The default sample resolution is 7 bits per pin, for a total of 14 bits. This can be configured within hardware limits (@ref MOZZI_PWM_RATE) using - * MOZZI_AUDIO_BITS_PER_CHANNEL, but beware that increasing this will require even more accuracy in our output resistors (see the linked documentation, above). - * - * @section avr_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio -*/ - -/** @ingroup core +/** @ingroup config * @def MOZZI_PWM_RATE * * Only for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_PWM and MOZZI_OUTPUT_2PIN_PWM. On some platforms, the rate at which PWM signals are repeated may be higher @@ -282,9 +179,8 @@ * In other words, increasing this improves the signal quality at less cost than doubling the audio rate itself. However, increasing this too far will limit the dynamic resolution of the samples that can be * written to the output pin(s): 2 ^ (output bits) * MOZZI_PWM_RATE cannot be higher than the CPU frequency! */ -//#define MOZZI_PWM_RATE 65356 -/** @ingroup core +/** @ingroup config * @def MOZZI_AUDIO_BITS_PER_CHANNEL * * Only for MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM. Sample resolution per channel to use in 2 pin output, given in bits (i.e. total resolution is twice as much). @@ -292,9 +188,8 @@ * * See @ref hardware_avr for a more detailed description. */ -//#define MOZZI_AUDIO_BITS_PER_CHANNEL 8 -/** @ingroup core +/** @ingroup config * @def MOZZI_AUDIO_PIN_1 * * Only for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_PWM and MOZZI_OUTPUT_2PIN_PWM: The IO pin to use as (first) audio output. This **must** be attached to Timer1. @@ -349,7 +244,7 @@ */ -/** @ingroup core +/** @ingroup config * @def MOZZI_AUDIO_BITS * * Output resolution of audio samples. In most cases you should leave this value untouched (for the defaults that get applied, see @ref hardware . @@ -357,305 +252,7 @@ * of 16 bits. * * @note - * At the time of this writng single audio samples are stored as "int", unconditionally. This limits MOZZI_AUDIO_BITS to a maximumg of 16 bits on + * At the time of this writng single audio samples are stored as "int", unconditionally. This limits MOZZI_AUDIO_BITS to a maximum of 16 bits on * some 8 bit boards! */ -//#define MOZZI_AUDIO_BITS 16 - - - - -/***************************************** ADVANCED SETTTINGS -- ESP32 *********************************************************** - * - * The settings in the following section applies to the ESP32 architecture. - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - - -/** @ingroup hardware - * @page hardware_esp32 Mozzi on ESP32-based boards. - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_PDM_VIA_I2S - * - MOZZI_OUTPUT_I2S_DAC - * - MOZZI_OUTPUT_INTERNAL_DAC - * - * The default mode is @ref esp32_internal_dac . - * - * @note - * This port really does not currently come with a PWM mode! - * - * @section esp32_internal_dac MOZZI_OUTPUT_INTERNAL_DAC - * The internal DAC has 8 bit resolution, and outputs to GPIO pins 25 and 26 (non-configurable). For simplicity of code, both pins are always used. - * In a mono configuration, both pins output the same sample. - * - * TODO: We could really use this to hack in a 2 PIN mode! - * - * @note - * The number 25 refers to "GPIO 25" or sometimes labelled "D25". Confusingly, many boards come with an additional, totally different numbering scheme on top of that. - * - * Internally, the inbuilt DAC is connected via an I2S interface. Which interface number to use can be configured using: - * - * @code - * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0) - * @endcode - * - * @section esp32_i2s_dac MOZZI_OUTPUT_I2S_DAC - * This mode outputs to a PT8211 (or compatible) I2S DAC, which allows for very high quality (mono or stereo) output. Communication needs the BCK, WS, and DATA(out) pins - * of one I2S interface. Presumably, any pins qualify, and you can configure this using: - * @code - * #define MOZZI_I2S_PIN_BCK ... // (default: 26) - * #define MOZZI_I2S_PIN_WS ... // (default: 15) - * #define MOZZI_I2S_PIN_DATA ... // (default: 33) - * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0) - * @endcode - * - * See the note above (@ref esp_internal_dac) regarding pin numbering. Also, please always test the default pinout, should a custom setting fail! - * - * As a technical note, I2S support in the ESP32 SDK has been reworked since this was implemented in Mozzi, and Mozzi uses the "legacy" implementation "i2s.h". - * This should not be an issue, unless you want to connect additional I2S components, yourself. In which case contributions are certainly welcome! - * - * @section esp32_pdm_via_i2s MOZZI_OUTPUT_PDM_VIA_I2S - * This mode uses the same setup as @ref esp32_i2s_dac, but rather than using an external DAC, the communication signal itself is modulated in PDM - * (pulse density modulation) encoded form. Thus not extra hardware is needed, and the signal is output on the DATA pin (see above). The BCK and - * WS pins are also claimed, but should be left non-connected, and do not produce anything meaningful. This can only be used in mono mode. - * - * Output resolution may be adjusted by defining MOZZI_PDM_RESOLUTION , where the default value of 4 means that each audio sample is encoded into four 32 bit blocks - * of ones and zeros. Obviously, more is potentially better, but at the cost of considerable computation power. - * - * @section esp32_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio -*/ - - -/***************************************** ADVANCED SETTTINGS -- ESP8266 *********************************************************** - * - * The settings in the following section applies to the ESP8266 architecture. - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - - -/** @ingroup hardware - * @page hardware_esp8266 Mozzi on ESP32-based boards. - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_PDM_VIA_I2S - * - MOZZI_OUTPUT_PDM_VIA_SERIAL - * - MOZZI_OUTPUT_I2S_DAC - * - * The default mode is @ref esp8266_pdm_via_serial . - * - * @note - * This port really does not currently come with a PWM mode! - * - * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_SERIAL - * Output is coded using pulse density modulation, and sent via GPIO2 (Serial1 TX). - * - This output mode uses timer1 for queuing audio sample, so that timer is not available for other uses. - * - Note that this mode has slightly lower effective analog output range than @ref esp8266_pdm_via_i2s, due to start/stop bits being added to the output stream. - * - Supports mono output, only, pins not configurable. - * - * The option @ref MOZZI_PDM_RESOLTUON (default value 2, corresponding to 64 ones and zeros per audio sample) can be used to adjust the output resolution. - * Obviously higher values demand more computation power. - * - * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_I2S - * Output is coded using pulse density modulation, and sent via the I2S pins. The I2S data out pin (GPIO3, which is also "RX") will have the output, - * but *all* I2S output pins (RX, GPIO2 and GPIO15) will be affected. Mozzi tries to set GPIO2 and GPIO15 to input mode, and *at the time of this writing*, this allows - * I2S output on RX even on boards such as the ESP01 (where GPIO15 is tied to Ground). However, it seems safest to assume that this mode may not be useable on boards where - * GPIO2 or GPIO15 are not available as output pins. - * - * Supports mono output, only, pins not configurable. - * - * Resolution may be controlled using MOZZI_PDM_RESOLUTION (see above; default value is 2). - * - * @section esp8266_i2s_dac MOZZI_OUTPUT_I2S_DAC - * Output is sent to an external DAC (such as a PT8211), digitally coded. This is the only mode that supports stereo (@ref MOZZI_AUDIO_CHANNELS). It also needs the least processing power. - * The pins cannot be configured (GPIO3/RX, GPIO2, and GPIO15). - * - * @section esp8266_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio -*/ - - - -/***************************************** ADVANCED SETTTINGS -- Arduino Giga/Portenta MBED *********************************************************** - * - * The settings in the following section applies to Arduino Giga/Portenta (MBED architecture) - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - - -/** @ingroup hardware - * @page hardware_mbed Mozzi on MBED-based boards (Arduino Giga / Portenta). - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_PDM_VIA_SERIAL - * - MOZZI_OUTPUT_INTERNAL_DAC - * - * The default mode is @ref mbed_internal_dac . - * - * @section mbed_internal_dac MOZZI_OUTPUT_INTERNAL_DAC - * This uses the inbuild DAC on the board. The default is setting is appropriate for the Arduino Giga: 12 bits going to A13 (3.5mm jack connector's tip), - * and in stereo mode to pin A12 (3.5mm jack connector's first ring) additionally. - * - * For other boards is may be appropriate to customize: - * @code - * #define MOZZI_AUDIO_PIN_1 ... // mono / left channel; default: A13 - * #define MOZZI_AUDIO_PIN_2 ... // stereo only: right channel; default: A12 - * #define MOZZI_AUDIO_BITS ... // default is 12 - * @endcode - * - * @section mbed_pdm_via_serial MOZZI_PDM_VIA_SERIAL - * Returns a pulse-density modulated (mono only) signal on one of the hardware UARTs of the board (Serial ports). Default is using the SERIAL2, on pin D18. - * You can confiugre the pins to use, but it must be connected to a hardware UART. Output is written to the TX pin, only, but the RX pin needs to be - * claimed as well. Beware of confusing pinout labelling, for instance SERIAL2_TX iss labelled "TX1" on the Arduino Giga. The audio resolution can be enhanced - * using @ref MOZZI_PDM_RESOLUTION, which is described in more detail here: @esp32_pdm_via_i2s . - * - * Configuration options: - * @code - * #define MOZZI_SERIAL_PIN_TX ... // default: SERIAL2_TX - * #define MOZZI_SERIAL_PIN_RX ... // *must* specify the matching one, if customizing the above; default: SERIAL2_RX - * #define MOZZI_PDM_RESOLUTION ... // default value is 2, for 2*32 ones and zeros per audio sample - * @endcode - * - * @section mbed_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio -*/ - - -/***************************************** ADVANCED SETTTINGS -- Arduino Uno R4 - Renesas *********************************************************** - * - * The settings in the following section applies to Arduino Uno R4 - Renesas - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - - -/** @ingroup hardware - * @page hardware_renesas Mozzi on Arduino Uno R4 - Renesas. - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_INTERNAL_DAC - * - * The default mode is @ref renesas_internal_dac. Further modes may be added in the future. - - Because this board has an on-board DAC (A0), but only one, STEREO is not implemented and Mozzi uses this pin. Usage of other pins using PWM for instance is not implemented yet. - - Two timers are claimed by Mozzi when using the on-board DAC, one when using `EXTERNAL_AUDIO_OUTPUT`. - - `mozziAnalogRead()` returns values in the Renesas' full ADC resolution of 0-16384 rather than AVR's 0-1023. *This might change in the near future for speed purposes.* - - * @section renesas_internal_dac MOZZI_OUTPUT_INTERNAL_DAC - * This uses the inbuild DAC on the board on pin A0. Mono output only, and the pin is not configurable. Audio resolution is also fixed at 12 bits (which is what the board supports). - * - * This mode claims two timers (but it is not hardcoded, which ones). - * - * @section renesas_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * MOZZI_OUTPUT_EXTERNAL_TIMED claimes one timer, MOZZI_OUTPUT_EXTERNAL_CUSTOM does not claim any timer. - * See @ref external_audio -*/ - - - - -/***************************************** ADVANCED SETTTINGS -- RP2040 (Raspberry Pi Pico) *********************************************************** - * - * The settings in the following section applies to RP2040 (Raspberry Pi Pico) - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - - -/** @ingroup hardware - * @page hardware_rp2040 Mozzi on RP2040 (Raspberry Pi Pico) - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_PDM - * - MOZZI_OUTPUT_I2S_DAC - * - * The default mode is @ref rp2040_pdm . - * - * @section rp2040_pdm MOZZI_OUTPUT_PDM - * Audio output is written to pin 0 (mono) or 0 and 1 (stereo), by default, with 11 bits of ouput resolution. - * One hardware timer interrupt and one DMA channel are claimed (number not hardcoded), a non-exclusive handler is installed on DMA_IRQ_0. - * - * Configuration options: - * @code - * #define MOZZI_AUDIO_PIN_1 ... // default is 0 - * #define MOZZI_AUDIO_BITS ... // output resolution (bits); default is 11 - * // additionally, for stereo: - * #define MOZZI_AUDIO_PIN_2 ... // default is 1; this must be on the same PWM slice as the first pin (i.e. neighboring) - * @endcode - * - * @section rp2040_i2s_dac MOZZI_OUTPUT_I2S_DAC - * Output to an external DAC, connected via I2S. This uses 16 bit (per audio channel), but can be changed to 8, 16, 24 (left aligned) and 32 resolution. - * Both plain I2S and LSBJ format (PT8211 needs this, for instance) are available. LSBJ format is used by default. The GPIO pins to use can be configured, - * - almost - freely (see below). Two DMA channels are claimed (numbers not hardcoded), non-exclusive handlers are installed on DMA_IRQ_0. - * - * Configuration options: - * @code - * #define MOZZI_AUDIO_BITS ... // available values are 8, 16 (default), 24 (LEFT ALIGN in 32 bits type!!) and 32 bits - * #define MOZZI_I2S_PIN_BCK ... // /BLCK) default is 20 - * //#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) ... // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21 - * #define MOZZI_I2S_PIN_DATA ... // (DOUT) default is 22 - * #define MOZZI_I2S_FORMAT ... // may be MOZZI_I2S_FORMAT_LSBJ (default) or MOZZI_I2S_FORMAT_PLAIN - * @endcode - * - * @section rp2040_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio -*/ - - - -/***************************************** ADVANCED SETTTINGS -- SAMD21 *********************************************************** - * - * The settings in the following section applies to SAMD21 boards - * - * It is generally not recommended to change anything, here, unless you really know, what you are doing and/or - * are willing to rough it out by yourself. - * -********************************************************************************************************************************/ - -/** @ingroup hardware - * @page hardware_samd Mozzi on SAMD21 based boards (Arduino Circuitplayground M0 and others) - * - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: - * - MOZZI_OUTPUT_EXTERNAL_TIMED - * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_INTERNAL_DAC - * - * The default mode is @ref samd_internal_dac , meaning, only boards with an inbuilt DAC are covered by default - * (you could stil use one of the external output modes, however). - * - * @section samd_internal_dac MOZZI_OUTPUT_INTERNAL_DAC - * Output resolution is 10 bits by default, and goes to pin DAC0. Only mono output is supported. Within the hardware limits of your board, you can configure the following: - * - * @code - * #define MOZZI_AUDIO_PIN_1 ... // default is DAC0 - * #define MOZZI_AUDIO_BITS ... // default is 10 - * @endcode - * - * @section samd_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM - * See @ref external_audio -*/ - diff --git a/README.md b/README.md index a25b5c1d7..bf9d131ca 100644 --- a/README.md +++ b/README.md @@ -74,9 +74,9 @@ Teensy 4.0 4.1 | A8 | yes Gemma M0 | A0 | yes Adafruit Playground Express | Built in Speaker | yes Sanguino | 13 | - -STM32F1 maple core (see "Hardware specific notes", below) | PB8 | yes -STM32F1 STM core (see "Hardware specific notes", below) | PA8 | yes -STM32F4 STM core (see "Hardware specific notes", below) | PA8 | yes +STM32F1 maple core | PB8 | yes +STM32F1 STM core | PA8 | yes +STM32F4 STM core | PA8 | yes ESP8266 *see details* | GPIO2 | yes RP2040 | 0 | yes @@ -99,8 +99,9 @@ void updateControl(){ // your control code } -int updateAudio(){ - // your audio code which returns an int between -244 and 243 +AudioOutput_t updateAudio() { + // your audio code which returns a 0-centered integer, typically in the 8bit or 16-bit range + return MonoOutput::from16Bit( [myvalue] ); } void loop() { @@ -122,21 +123,20 @@ Look for code and usage changes [here](extras/NEWS.txt). *** -## Caveats and Workarounds - -#### AVR +## General caveats and Workarounds * While Mozzi is running, calling `delay()`, `delayMicroseconds()`, or other functions which wait or cycle through loops can cause audio glitches. -Mozzi provides `EventDelay()` for scheduling instead of `delay`. - -* `analogRead()` is replaced by `mozziAnalogRead()`, which works in the background instead of blocking the processor. +Mozzi provides `EventDelay()` for scheduling instead of `delay`. In general, make sure to write non-blocking code! -* Mozzi interferes with `analogWrite()`. In `STANDARD` and `STANDARD_PLUS` audio modes, Mozzi takes over Timer1 (pins 9 and 10), but you can use the Timer2 pins, 3 and 11 (your board may differ). In `HIFI` mode, Mozzi uses Timer1 (or Timer4 on some boards), and Timer2, so pins 3 and 11 are also out. -If you need `analogWrite()`, you can do PWM output on any digital pins using the technique in *Mozzi>examples>11.Communication>Sinewave_PWM_pins_HIFI*. +* `analogRead()` is a time-consuming operation especially on the classic AVR boards. Mozzi provides `mozziAnalogRead()` as a drop-in replacement, which works in the +background instead of blocking the processor. +* Depending on the hardware and configured audio output mode, Mozzi will usually claim one or more hardware timers. This may affect, among other things, the ability to +use `analogWrite()`. Check the [Hardware Section of the Documentation](https://sensorium.github.io/Mozzi/doc/html/group__hardware.html) to options to configure ressource +usage. + - If you need `analogWrite()`, you can do PWM output on any digital pins using the technique in *Mozzi>examples>11.Communication>Sinewave_PWM_pins_HIFI*. -#### Last Resort -The timers can be made available with `stopMozzi()`, which stops audio interrupts, until you call `startMozzi()`. +* As last resort, the timers can be made available with `stopMozzi()`, which stops audio interrupts, until you call `startMozzi()`. *** @@ -150,6 +150,9 @@ It’s explained more thoroughly (for Windows) [here](http://www.instructables.c If you still need more speed, Arduino 1.0.5 produces slightly faster code. +Mozzi itself offers many helpers for producing faster code, such as Fixed-Point integer maths, fast replacements for `map()`, `random()`, `millis()`, and other functions. +Be sure to use these! + *** ## Using external chips to produce the sound @@ -188,121 +191,25 @@ Various examples from [Pure Data](http://puredata.info/) by Miller Puckette [Practical synthesis tutorials](http://www.obiwannabe.co.uk/) by Andy Farnell -## Hardware specific notes - -TODO link to hardware section in API docs -TODO list just the basic headers, here. - -### Teensy 3.0/3.1/3.2/3.4/3.5/LC - - -### Teensy 4.0/4.1 - -### STM32 - -### SAMD21 architecture (Arduino Circuitplayground M0 and others) -port by Adrian Freed - -- Currently, only output on the inbuilt DAC (pin DAC0) is supported. So, obviously, boards without a DAC are not yet convered (in theory you can still use EXTERNAL_AUDIO_OUTPUT) -- Output resolution is fixed at 10 bits. If your board supports more, configure in AudioConfigSAMD21.h -- mozziAnalogRead() and AUDIO_INPUT are not implemented (contributions welcome) -- We don't have a lot of data, which boards this port has been tested on. Success or not, let us know, if you are using Mozzi on SAMD21 boards - -### ESP8266 -port by Thomas Friedrichsmeier - -- Since flash memory is not built into the ESP8266, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform. -- Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. -- AUDIO_INPUT is not implemented. -- twi_nonblock is not ported -- Several audio output modes exist, the default being PDM_VIA_SERIAL (configurable in AudioConfigESP.h): - - PDM_VIA_SERIAL: Output is coded using pulse density modulation, and sent via GPIO2 (Serial1 TX). - - This output mode uses timer1 for queuing audio sample, so that timer is not available for other uses. - - Note that this mode has slightly lower effective analog output range than PDM_VIA_I2S, due to start/stop bits being added to the output stream. - - PDM_VIA_I2S: Output is coded using pulse density modulation, and sent via the I2S pins. The I2S data out pin (GPIO3, which is also "RX") will have the output, - but *all* I2S output pins (RX, GPIO2 and GPIO15) will be affected. Mozzi tries to set GPIO2 and GPIO15 to input mode, and *at the time of this writing*, this allows - I2S output on RX even on boards such as the ESP01 (where GPIO15 is tied to Gnd). However, it seems safest to assume that this mode may not be useable on boards where - GPIO2 or GPIO15 are not available as output pins. - - EXTERNAL_DAC_VIA_I2S: Output is sent to an external DAC (such as a PT8211), digitally coded. This is the only mode that supports STEREO. It also needs the least processing power. -- There is no "HIFI_MODE" in addition to the above output options. For high quality output, either use an external DAC, or increase the PDM_RESOLUTION value. -- Note that the ESP8266 pins can output less current than the other supported CPUs. The maximum is 12mA, with a recommendation to stay below 6mA. - - WHEN CONNECTING A HEADPHONE, DIRECTLY, USE APPROPRIATE CURRENT LIMITING RESISTORS (>= 500Ohms). -- _Any_ WiFi-activity can cause severe spikes in power consumption. This can cause audible "ticking" artifacts, long before any other symptoms. - - If you do not require WiFi in your sketch, you should turn it off, _explicitly_, using `WiFi.mode(WIFI_OFF)`. - - A juicy enough, well regulated power supply, and a stabilizing capacitor between VCC and Gnd can help a lot. - - As the (PDM) output signal is digital, a single (fast!) transistor can be used to amplify it to an independent voltage level. -- The audio output resolution is always 16 bits on this platform, _internally_. Thus, in updateAudio(), you should scale your output samples to a full 16 bit range. The effective number of output bits cannot easily - be quantified, due to PDM coding. -- audioHook() calls `yield()` once for every audio sample generated. Thus, as long as your audio output buffer does not run empty, you should not need any additional `yield()`s inside `loop()`. - -### ESP32 -port by Dieter Vandoren and Thomas Friedrichsmeier - -- Since flash memory is not built into the ESP32, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform. -- Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. -- AUDIO_INPUT is not implemented. -- twi_nonblock is not ported -- Currently, three audio output modes exist, the default being INTERNAL_DAC (configurable in AudioConfigESP32.h). *The configuration details may still be subject to change; please be prepared to make some minimal adjustments to your code, when upgrading Mozzi*: - - INTERNAL_DAC: Output using the built-in DAC on GPIO pins 25 and 26. - - 8 bits resolution, mono (on both pins) or stereo - - For simplicity of code, both pins are always used, even in mono output mode - - PT8211_DAC: Output is sent via I2S in a format suitable for the PT8211 external EXTERNAL_DAC - - 16 bits resolution, mono or stereo. Remember to shift your audio accordingly. - - Output pins can be configured in AudioConfigESP32.h. Default is BCK: 26, WS: 15, DATA: 33 - - PDM_VIA_I2S: Output is converted using pulse density modulation, sent to the I2S data pin. No external hardware needed. - - 16 bits resolution. Remember to shift your audio accordingly. - - Output (DATA) pin can be configured in AudioConfigESP32.h. Default 33. Note that the BCK and WS pins are also used in this mode. - - The PDM_RESOLUTION parameter can be used to reduce noise at the cost of more CPU power. - - Mono, only. -- "HIFI_MODE" is not currently implemented, but could conceivably be realized for the INTERNAL_DAC mode. Patches welcome. -- WIFI-activity not yet tested, but likely the same notes as for ESP8266 apply. Consider turning off WIFI. -- The implementation of audioTicks() may be slightly inaccurate on this platform. - -### RP2040 (Raspberry Pi Pico) -port by Thomas Friedrichsmeier - -Compiles and runs using [this core](https://github.com/earlephilhower/arduino-pico). Can probably be ported to the Mbed core for RP2040, relatively easily, as it relies mostly -on the RP2040 SDK API. Tested on a Pi Pico. - -- This is a recent addition, implementation details may still change (currently just PWM driven by a timer; this may be worth changing to a DMA driven output) -- Wavetables and samples are not kept in progmem on this platform. While apparently speed (of the external flash) is not much of an issue, the data always seems to be copied into RAM, anyway. -- Currently, two audio output modes exist (configurable in AudioConfigRP2040.h) in addition to using an user-defined `audioOutput` function, with the default being PWM_VIA_BARE_CHIP: - - PWM_VIA_BARE_CHIP: PWM audio output on pin 0, by default, with 11 bits default output resolution - - One hardware timer interrupt and one DMA channel are claimed (number not hardcoded), a non-exclusive handler is installed on DMA_IRQ_0. - - HIFI_MODE not yet implemented (although that should not be too hard to do). - - EXTERNAL_DAC_VIA_I2S: I2S output to be connected to an external DAC - - 16 bits resolution by default (configurable in AudioConfigRP2040.h), 8, 16, 24 (left aligned) and 32 resolution are available. - - Both plain I2S and LSBJ_FORMAT (for the PT8211 for instance) are available (configurable in AudioConfigRP2040.h), default is LSBJ. - - Outputs pins can be configured in AudioConfigRP2040.h. Default is BCK: 20, WS: 21, DATA: 22. - - Two DMA channels are claimed (numbers not hardcoded), non-exclusive handlers are installed on DMA_IRQ_0. - - At the time of writing, LSBJ is only available with github arduino-pico core. -- Note that AUDIO_INPUT and mozziAnalogRead() return values in the RP2040's full ADC resolution of 0-4095 rather than AVR's 0-1023. -- twi_nonblock is not ported -- Code uses only one CPU core - -### Arduino Giga/MBED -port by Thomas Friedrichsmeier & Thomas Combriat - -Compiles and runs using Arduino's standard and Arduino_AdvancedAnalog libraries. This port is still **experimental**, testing reveals some instabilities for some configurations (in particular with USE_AUDIO_INPUT) that are under active investigations. - -- This port is not complete yet, in particular: - - Asynchroneous analog reads are not implemented (yet), `mozziAnalogRead()` relays to `analogRead()`. - - HIFI mode is not implemented. -- In addition to using an user-defined `audioOutput()` by setting `EXTERNAL_AUDIO_OUTPUT` to `true` in mozzi_config.h, two bare chip output modes exist (configurable in AudioConfigMBED.h): - - INTERNAL_DAC: uses the DAC present on the board and outputs by default on pin A13 (3.5mm jack connector's tip). Stereo mode uses pin A12 (3.5mm jack connector's first ring) additionally. - - PDM_VIA_SERIAL: returns a pulse-density modulated signal on one of the hardware UART of the board (Serial ports). Default is using the SERIAL2, on pin D18. -- This port should support other MBED based Arduino boards like the Arduino Portenta, in *theory*. It has only been tested on the giga but feedbacks are welcome! - -### Arduino Uno R4 -port by Thomas Combriat - -Compiles and runs using Arduino's standard library (Renesas 0.8.7 at the time of this writing). - -- A few particularities: - - - Because this board has an on-board DAC (A0), but only one, STEREO is not implemented and Mozzi uses this pin. Usage of other pins using PWM for instance is not implemented yet. - - Two timers are claimed by Mozzi when using the on-board DAC, one when using `EXTERNAL_AUDIO_OUTPUT`. - - `mozziAnalogRead()` returns values in the Renesas' full ADC resolution of 0-16384 rather than AVR's 0-1023. *This might change in the near future for speed purposes.* +## Hardware compatibility and hardware specific notes + +While originating on the 8 bit AVR based "classic Arduino" boards, Mozzi supports a wide variety of different MCUs, these days, including: + - Classic AVR boards: Arduino Uno, Duemilanove, Nano, Nano 33, Pro Mini, Leonardo, Mega, many others, and countless clones, Teensy 1 and 2.x, ... + - Various Teensy 3.x boards: Teensy 3.0/3.1/3.2/3.4/3.5/LC + - Teensy 4.x boards: Teensy 4.0 and 4.1 are known to work, future boards stand good chances of working with Mozzi out of the box + - STM32-based boards: Confusingly, several popular Arduino cores exist for these MCUs - and Mozzi supports several. Refer to the documentation + linked below. Mozzi has been tested on the popule STM32F1 "blue pill" and STM32F4 "black pill" boards, but should support a very wide range + of further boards out of the box. + - SAMD21-based boards: Tested on the Arduino Circuitplayground M0, expect to work on others, too. + - ESP8266: Should run on the whole range of boards, including the minimal ESP-01 + - ESP32: Should run on the wohle range of boards + - Arduiono Giga/MBED: The Arduino Giga, and - in untested theory - the Arduion Portenta + - RP2040: The Raspberry Pi Pico and other boards using RP2040 + - Arduino Uno R4: The new Uno, based on a 32-bit Renesas MCU + +Since the hardware capatibilies of these boards are vastly different, the ports, too, differ in their internals and their capabilities. Importantly, +of course, they also differ in what pin(s) are used for audio output by default. Refer to the [Hardware Section of the Documentation](https://sensorium.github.io/Mozzi/doc/html/group__hardware.html) for the details +applicable to your hardware. *** diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index f9d83ecc0..70163c880 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -1,7 +1,82 @@ /** For Mozzi-internal use: Apply hardware specific config defaults and config checks: AVR */ -// Step 1: Apply missing defaults -// NOTE: This step is actually required for all ports +/** @ingroup hardware + * @page hardware_avr Mozzi on classic Arduino, Teensy 2.x, Arduino Mega, and other 8 bit "AVR"/ATMEGA architecture boards + * + * @section avr_status Port status and notes + * This is the original "port" of Mozzi, and thus very elaborate. The main challenges on this platform, compared to other MCUs, are limitations in + * flash, RAM, and CPU power. + * + * @section avr_output Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware. In all cases, Timer 1 is claimed, and + * is not available for any other purpose: + * - MOZZI_OUTPUT_PWM + * - MOZZI_OUTPUT_2PIN_PWM + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * + * In all cases, except MOZZI_OUTPUT_EXTERNAL_CUSTOM, Timer 1 is claimed, and is not available for any other purpose. + * + * @section avr_pwm MOZZI_OUTPUT_PWM + * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured + * within this tight limit. In particular, the default setup on the + * Arduino UNO is: + * - Mono: Pin 9 -> configurable using MOZZI_AUDIO_PIN_1 + * - Stereo: Pin 9 (left) and Pin 10 (right) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_2 + * For pinouts on other boards, refer to config/known_16bit_timers. + * + * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE: MOZZI_PWM_RATE. + * + * The available sample resolution is 488, i.e. almost 9 bits, providing some headroom above the 8 bit table resolution + * currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate. + * + * @section avr_2pin_pwm MOZZI_OUTPUT_2PIN_PWM + * In this mode, output is split across two pins (again, both connected to Timer 1), with each outputting 7 bits for a total of 14. This allows for + * much better dynamic range, providing much more definition than can be achieved using @ref avr_pwm , while using + * only modestly more processing power. Further, it allows for a much higher PWM carrier rate can be much higher (125 kHz by default; see @ref + * MOZZI_PWM_RATE), which is well beyond the audible range. + * + * On the downside, this mode requires an extra hardware timer (Timer2 in addition to Timer1), which may increase compatibility + * problems with other Arduino libraries that also require a timer. Further, a more elaborate hardware setup is needed, making it less convenient + * for rapid prototyping: + * + * TODO: Move this bit to a dedicated page on output circuits? + * In hardware, add the two signals through a 3.9k resistor on the "high" pin and 499k resistor on "low" pin. + * Use 0.5% resistors or select the most accurate from a batch. It is further recommended to place a 4.7nF capacitor between the summing junction + * of the resistors and ground. This is discussed in much more detail on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ + * Also, there are higher quality output circuits are on the site. + * + * On the classic Arduino Uno, the default pinout in this mode is: + * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW + * + * Here is table of the default pins on some other boards. Rows with an x on it have actually been tested (and importantly, the outcome recoreded; + * input welcome on further boards.) + * + * resistor.....3.9k......499k \n + * x................9..........10...............Arduino Uno \n + * x................9..........10...............Arduino Duemilanove \n + * x................9..........10...............Arduino Nano \n + * x................9..........10...............Arduino Leonardo \n + * x................9..........10...............Ardweeny \n + * x................9..........10...............Boarduino \n + * x...............11.........12...............Freetronics EtherMega \n + * .................11.........12...............Arduino Mega \n + * .................14.........15...............Teensy \n + * .............B5(14)...B6(15)...........Teensy2 \n + * x...........B5(25)...B6(26)...........Teensy2++ \n + * .................13.........12...............Sanguino \n + * + * For pinouts on other AVR boards, config/known_16bit_timers might contain some hints. + * + * Rate of the PWM output can be controlled separately from @ref MOZZI_AUDIO_RATE, and is much higher (125kHz), by default: @ref MOZZI_PWM_RATE. + * + * The default sample resolution is 7 bits per pin, for a total of 14 bits. This can be configured within hardware limits (@ref MOZZI_PWM_RATE) using + * @ref MOZZI_AUDIO_BITS_PER_CHANNEL, but beware that increasing this will require even more accuracy in our output resistors (see the linked documentation, above). + * + * @section avr_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + #if not defined(MOZZI_AUDIO_MODE) #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM diff --git a/internal/config_checks_esp32.h b/internal/config_checks_esp32.h index 47d91f442..1d462385f 100644 --- a/internal/config_checks_esp32.h +++ b/internal/config_checks_esp32.h @@ -1,6 +1,71 @@ #ifndef CONFIG_CHECK_ESP32_H #define CONFIG_CHECK_ESP32_H +/** @ingroup hardware + * @page hardware_esp32 Mozzi on ESP32-based boards. + * + * port by Dieter Vandoren and Thomas Friedrichsmeier + * + * @section esp32_status Port status and notes + * - Since flash memory is not built into the ESP32, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform. + * - Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. @ref MOZZI_AUDIO_INPUT is not implemented + * - twi_nonblock is not ported + * - WIFI-activity not yet tested, but likely the same notes as for ESP8266 apply, i.e. @em any Wifi activity is likely to introdcue considerable nose. Consider turning off WIFI. + * - The implementation of audioTicks() may be slightly inaccurate on this platform. + * + * @section esp32_output Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PDM_VIA_I2S + * - MOZZI_OUTPUT_I2S_DAC + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref esp32_internal_dac . + * + * @section esp32_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * The internal DAC has 8 bit resolution, and outputs to GPIO pins 25 and 26 (non-configurable). For simplicity of code, both pins are always used. + * In a mono configuration, both pins output the same sample. + * + * TODO: We could really use this to hack in a 2 PIN mode! + * + * @note + * The number 25 refers to "GPIO 25" or sometimes labelled "D25". Confusingly, many boards come with an additional, totally different numbering scheme on top of that. + * Check a detailed pinout diagram, if in any doubt. + * + * Internally, the inbuilt DAC is connected via an I2S interface. Which interface number to use can be configured using: + * + * @code + * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0) + * @endcode + * + * @section esp32_i2s_dac MOZZI_OUTPUT_I2S_DAC + * This mode outputs to a PT8211 (or compatible) I2S DAC, which allows for very high quality (mono or stereo) output. Communication needs the BCK, WS, and DATA(out) pins + * of one I2S interface. Presumably, any pins qualify, and you can configure this using: + * @code + * #define MOZZI_I2S_PIN_BCK ... // (default: 26) + * #define MOZZI_I2S_PIN_WS ... // (default: 15) + * #define MOZZI_I2S_PIN_DATA ... // (default: 33) + * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0) + * @endcode + * + * See the note above (@ref esp_internal_dac) regarding pin numbering. Also, please always test the default pinout, should a custom setting fail! + * + * As a technical note, I2S support in the ESP32 SDK has been reworked since this was implemented in Mozzi, and Mozzi uses the "legacy" implementation "i2s.h". + * This should not be an issue, unless you want to connect additional I2S components, yourself. In which case contributions are certainly welcome! + * + * @section esp32_pdm_via_i2s MOZZI_OUTPUT_PDM_VIA_I2S + * This mode uses the same setup as @ref esp32_i2s_dac, but rather than using an external DAC, the communication signal itself is modulated in PDM + * (pulse density modulation) encoded form. Thus not extra hardware is needed, and the signal is output on the DATA pin (see above). The BCK and + * WS pins are also claimed, but should be left non-connected, and do not produce anything meaningful. This can only be used in mono mode. + * + * Output resolution may be adjusted by defining MOZZI_PDM_RESOLUTION , where the default value of 4 means that each audio sample is encoded into four 32 bit blocks + * of ones and zeros. Obviously, more is potentially better, but at the cost of considerable computation power. + * + * @section esp32_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + #if not IS_ESP32() #error This header should be included for ESP32 architecture, only #endif diff --git a/internal/config_checks_esp8266.h b/internal/config_checks_esp8266.h index 7cc06901f..b4ed95087 100644 --- a/internal/config_checks_esp8266.h +++ b/internal/config_checks_esp8266.h @@ -1,6 +1,62 @@ #ifndef CONFIG_CHECK_ESP8266_H #define CONFIG_CHECK_ESP8266_H +/** @ingroup hardware + * @page hardware_esp8266 Mozzi on ESP32-based boards. + * + * port by Thomas Friedrichsmeier + * + * @section esp8266_status Port status and notes + * - Since flash memory is not built into the ESP8266, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform. + * - Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. @ref MOZZI_AUDIO_INPUT is not available + * - twi_nonblock is not ported + * - Note that the ESP8266 pins can output less current than the other supported CPUs. The maximum is 12mA, with a recommendation to stay below 6mA. + * - WHEN CONNECTING A HEADPHONE, DIRECTLY, USE APPROPRIATE CURRENT LIMITING RESISTORS (>= 500Ohms). + * - _Any_ WiFi-activity can cause severe spikes in power consumption. This can cause audible "ticking" artifacts, long before any other symptoms. + * - If you do not require WiFi in your sketch, you should turn it off, _explicitly_, using @code WiFi.mode(WIFI_OFF) @endcode. + * - A juicy enough, well regulated power supply, and a stabilizing capacitor between VCC and Gnd can help a lot. + * - As the (PDM) output signal is digital, a single (fast!) transistor can be used to amplify it to an independent voltage level. + * - audioHook() calls `yield()` once for every audio sample generated. Thus, as long as your audio output buffer does not run empty, you should not need any additional `yield()`s inside `loop()`. + * + * @section esp8266_output Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PDM_VIA_I2S + * - MOZZI_OUTPUT_PDM_VIA_SERIAL + * - MOZZI_OUTPUT_I2S_DAC + * + * The default mode is @ref esp8266_pdm_via_serial . + * + * @note + * This port really does not currently come with a PWM mode! + * + * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_SERIAL + * Output is coded using pulse density modulation, and sent via GPIO2 (Serial1 TX). + * - This output mode uses timer1 for queuing audio sample, so that timer is not available for other uses. + * - Note that this mode has slightly lower effective analog output range than @ref esp8266_pdm_via_i2s, due to start/stop bits being added to the output stream. + * - Supports mono output, only, pins not configurable. + * + * The option @ref MOZZI_PDM_RESOLTUON (default value 2, corresponding to 64 ones and zeros per audio sample) can be used to adjust the output resolution. + * Obviously higher values demand more computation power. + * + * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_I2S + * Output is coded using pulse density modulation, and sent via the I2S pins. The I2S data out pin (GPIO3, which is also "RX") will have the output, + * but *all* I2S output pins (RX, GPIO2 and GPIO15) will be affected. Mozzi tries to set GPIO2 and GPIO15 to input mode, and *at the time of this writing*, this allows + * I2S output on RX even on boards such as the ESP01 (where GPIO15 is tied to Ground). However, it seems safest to assume that this mode may not be useable on boards where + * GPIO2 or GPIO15 are not available as output pins. + * + * Supports mono output, only, pins not configurable. + * + * Resolution may be controlled using MOZZI_PDM_RESOLUTION (see above; default value is 2). + * + * @section esp8266_i2s_dac MOZZI_OUTPUT_I2S_DAC + * Output is sent to an external DAC (such as a PT8211), digitally coded. This is the only mode that supports stereo (@ref MOZZI_AUDIO_CHANNELS). It also needs the least processing power. + * The pins cannot be configured (GPIO3/RX, GPIO2, and GPIO15). + * + * @section esp8266_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ #if not IS_ESP8266() #error This header should be included for ESP architecture, only diff --git a/internal/config_checks_mbed.h b/internal/config_checks_mbed.h index d212bb3c1..e92b33414 100644 --- a/internal/config_checks_mbed.h +++ b/internal/config_checks_mbed.h @@ -1,6 +1,57 @@ #ifndef CONFIG_CHECK_MBED_H #define CONFIG_CHECK_MBED_H +/** @ingroup hardware + * @page hardware_mbed Mozzi on MBED-based boards (Arduino Giga / Portenta). + * + * port by Thomas Friedrichsmeier & Thomas Combriat + * + * @section mbed_status Port status and notes + * Compiles and runs using Arduino's standard and Arduino_AdvancedAnalog libraries. This port is still **experimental**, testing reveals + * some instabilities for some configurations (in particular with @ref MOZZI_AUDIO_INPUT) that are under active investigations. + * + * This port is not complete yet, in particular: + * - Asynchroneous analog reads are not implemented (yet), `mozziAnalogRead()` relays to `analogRead()`. (Note that @ref MOZZI_AUDIO_INPUT @em is implemented!) + * - This port should support other MBED based Arduino boards like the Arduino Portenta, in *theory*, but the developer have only tested it on the Giga. Feedback welcome! + * + * @section mbed_output Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PDM_VIA_SERIAL + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref mbed_internal_dac . + * + * @section mbed_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * This uses the inbuild DAC on the board. The default is setting is appropriate for the Arduino Giga: 12 bits going to A13 (3.5mm jack connector's tip), + * and in stereo mode to pin A12 (3.5mm jack connector's first ring) additionally. + * + * For other boards is may be appropriate to customize: + * @code + * #define MOZZI_AUDIO_PIN_1 ... // mono / left channel; default: A13 + * #define MOZZI_AUDIO_PIN_2 ... // stereo only: right channel; default: A12 + * #define MOZZI_AUDIO_BITS ... // default is 12 + * @endcode + * + * @section mbed_pdm_via_serial MOZZI_PDM_VIA_SERIAL + * Returns a pulse-density modulated (mono only) signal on one of the hardware UARTs of the board (Serial ports). Default is using the SERIAL2, on pin D18. + * You can confiugre the pins to use, but it must be connected to a hardware UART. Output is written to the TX pin, only, but the RX pin needs to be + * claimed as well. Beware of confusing pinout labelling, for instance SERIAL2_TX iss labelled "TX1" on the Arduino Giga. The audio resolution can be enhanced + * using @ref MOZZI_PDM_RESOLUTION, which is described in more detail here: @esp32_pdm_via_i2s . + * + * Configuration options: + * @code + * #define MOZZI_SERIAL_PIN_TX ... // default: SERIAL2_TX + * #define MOZZI_SERIAL_PIN_RX ... // *must* specify the matching one, if customizing the above; default: SERIAL2_RX + * #define MOZZI_PDM_RESOLUTION ... // default value is 2, for 2*32 ones and zeros per audio sample + * @endcode + * + * @section mbed_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + + #if not IS_MBED() #error This header should be included for MBED architecture, only #endif diff --git a/internal/config_checks_renesas.h b/internal/config_checks_renesas.h index 7f3f20a59..fe8083c63 100644 --- a/internal/config_checks_renesas.h +++ b/internal/config_checks_renesas.h @@ -1,6 +1,39 @@ #ifndef CONFIG_CHECK_RENESAS_H #define CONFIG_CHECK_RENESAS_H +/** @ingroup hardware + * @page hardware_renesas Mozzi on Arduino Uno R4 - Renesas. + * + * port by Thomas Combriat + * + * @section renesas_status Port status and notes + * Compiles and runs using Arduino's standard library (Renesas 0.8.7 at the time of this writing). + * + * A few particularities: + * - Because this board has an on-board DAC (A0), but only one, STEREO is not implemented and Mozzi uses this pin. Usage of other pins using PWM for instance is not implemented yet. + * - getAudioInput() and mozziAnalogRead() return values in the Renesas' full ADC resolution of 0-16384 rather than AVR's 0-1023. *This might change in the near future for speed purposes.* + * + * @section rensesas_output Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref renesas_internal_dac. Further modes may be added in the future. + - Because this board has an on-board DAC (A0), but only one, STEREO is not implemented and Mozzi uses this pin. Usage of other pins using PWM for instance is not implemented yet. + - Two timers are claimed by Mozzi when using the on-board DAC, one when using `EXTERNAL_AUDIO_OUTPUT`. + - `mozziAnalogRead()` returns values in the Renesas' full ADC resolution of 0-16384 rather than AVR's 0-1023. *This might change in the near future for speed purposes.* + + * @section renesas_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * This uses the inbuild DAC on the board on pin A0. Mono output only, and the pin is not configurable. Audio resolution is also fixed at 12 bits (which is what the board supports). + * + * This mode claims two timers (but it is not hardcoded, which ones). + * + * @section renesas_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * MOZZI_OUTPUT_EXTERNAL_TIMED claimes one timer, MOZZI_OUTPUT_EXTERNAL_CUSTOM does not claim any timer. + * See @ref external_audio +*/ + #if not IS_RENESAS() #error This header should be included for RENESAS (Arduino Uno R4) architecture, only #endif diff --git a/internal/config_checks_rp2040.h b/internal/config_checks_rp2040.h index a6f056785..2a9a734e8 100644 --- a/internal/config_checks_rp2040.h +++ b/internal/config_checks_rp2040.h @@ -1,6 +1,62 @@ #ifndef CONFIG_CHECK_RP2040_H #define CONFIG_CHECK_RP2040_H +/** @ingroup hardware + * @page hardware_rp2040 Mozzi on RP2040 (Raspberry Pi Pico) + * + * port by Thomas Friedrichsmeier + * + * @section rp2040_status Port status and notes + * Compiles and runs using [this core](https://github.com/earlephilhower/arduino-pico). Can probably be ported to the Mbed core for RP2040, relatively easily, + * as it relies mostly on the RP2040 SDK API. Tested on a Pi Pico. + * + * - This is a recent addition, implementation details may still change (currently just PWM driven by a timer; this may be worth changing to a DMA driven output) + * - Wavetables and samples are not kept in progmem on this platform. While apparently speed (of the external flash) is not much of an issue, the data always seems to be copied into RAM, anyway. + * - Note that getAudioInput() and mozziAnalogRead() return values in the RP2040's full ADC resolution of 0-4095 rather than AVR's 0-1023. + * - twi_nonblock is not ported + * - Code uses only one CPU core + * + * @section rp2040_output Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_PDM + * - MOZZI_OUTPUT_I2S_DAC + * + * The default mode is @ref rp2040_pdm . + * + * @section rp2040_pdm MOZZI_OUTPUT_PDM + * Audio output is written to pin 0 (mono) or 0 and 1 (stereo), by default, with 11 bits of ouput resolution. + * One hardware timer interrupt and one DMA channel are claimed (number not hardcoded), a non-exclusive handler is installed on DMA_IRQ_0. + * + * Configuration options: + * @code + * #define MOZZI_AUDIO_PIN_1 ... // default is 0 + * #define MOZZI_AUDIO_BITS ... // output resolution (bits); default is 11 + * // additionally, for stereo: + * #define MOZZI_AUDIO_PIN_2 ... // default is 1; this must be on the same PWM slice as the first pin (i.e. neighboring) + * @endcode + * + * @section rp2040_i2s_dac MOZZI_OUTPUT_I2S_DAC + * Output to an external DAC, connected via I2S. This uses 16 bit (per audio channel), but can be changed to 8, 16, 24 (left aligned) and 32 resolution. + * Both plain I2S and LSBJ format (PT8211 needs this, for instance) are available. LSBJ format is used by default. The GPIO pins to use can be configured, + * - almost - freely (see below). Two DMA channels are claimed (numbers not hardcoded), non-exclusive handlers are installed on DMA_IRQ_0. + * + * Configuration options: + * @code + * #define MOZZI_AUDIO_BITS ... // available values are 8, 16 (default), 24 (LEFT ALIGN in 32 bits type!!) and 32 bits + * #define MOZZI_I2S_PIN_BCK ... // /BLCK) default is 20 + * //#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) ... // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21 + * #define MOZZI_I2S_PIN_DATA ... // (DOUT) default is 22 + * #define MOZZI_I2S_FORMAT ... // may be MOZZI_I2S_FORMAT_LSBJ (default) or MOZZI_I2S_FORMAT_PLAIN + * @endcode + * + * @note + * The MOZZI_I2S_FORMAT_LSBJ option may require a relatively recent git-hub checkout of the arduino-pico core. + * + * @section rp2040_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ #if not IS_RP2040() #error This header should be included for RP2040 architecture (Raspberry Pi Pico and others), only diff --git a/internal/config_checks_samd21.h b/internal/config_checks_samd21.h index 88a50c228..dc340fb2d 100644 --- a/internal/config_checks_samd21.h +++ b/internal/config_checks_samd21.h @@ -1,6 +1,36 @@ #ifndef CONFIG_CHECK_SAMD21_H #define CONFIG_CHECK_SAMD21_H +/** @ingroup hardware + * @page hardware_samd Mozzi on SAMD21 based boards (Arduino Circuitplayground M0 and others) + * + * port by Adrian Freed + * + * @section samd_status Port status and notes + * - @def MOZZI_ANALOG_READ and MOZZI_ANALOG_INPUT are not implemented (contributions welcome) + * - We don't have a lot of data, which boards this port has been tested on. Success or not, let us know, if you are using Mozzi on SAMD21 boards + * + * @section samd_output_modes Output modes + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * - MOZZI_OUTPUT_INTERNAL_DAC + * + * The default mode is @ref samd_internal_dac , meaning, only boards with an inbuilt DAC are covered by default + * (you could stil use one of the external output modes, however). + * + * @section samd_internal_dac MOZZI_OUTPUT_INTERNAL_DAC + * Output resolution is 10 bits by default, and goes to pin DAC0. Only mono output is supported. Within the hardware limits of your board, you can configure the following: + * + * @code + * #define MOZZI_AUDIO_PIN_1 ... // default is DAC0 + * #define MOZZI_AUDIO_BITS ... // default is 10 + * @endcode + * + * @section samd_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM + * See @ref external_audio +*/ + #if not IS_SAMD21() #error This header should be included for SAMD21 architecture (Arduino Circuitplayground M0 and others), only #endif diff --git a/internal/config_checks_teensy.h b/internal/config_checks_teensy.h index ea7143e5d..6f2e642a9 100644 --- a/internal/config_checks_teensy.h +++ b/internal/config_checks_teensy.h @@ -4,7 +4,7 @@ /** @ingroup hardware * @page hardware_teensy3 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards. * - * port by Thomas Combriat + * port by Tim Barrass * * @note * For Teensy 4.x see @ref hardware_teensy4 diff --git a/mozzi_config.h b/mozzi_config.h index 2319d5b8b..ead877179 100644 --- a/mozzi_config.h +++ b/mozzi_config.h @@ -1,6 +1,9 @@ /** TODO: Temporarily brought back to life for testing config rework. * - * The plan still is to have config in user space, instead. + * This file is not meant to stay, but removing it for good requirs the "single compilation unit". + * + * At the moment it can be used to quickly configure some options to non-default values, as shown in the commented exampales. + * Alternatively, one can include a config_examples_xyz.h file from here. */ #include "MozziConfigValues.h" @@ -9,5 +12,7 @@ //#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO //#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE -#include "internal/config_check_generic.h" +//#include "config/config_example_avr_legacy_standard.h" + +#include "internal/config_checks_generic.h" From 7d3d3d1f7b0b36d873b6550119cc21fb930f296b Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 19 Nov 2023 10:57:54 +0100 Subject: [PATCH 059/215] Add some configuration examples --- config/config_example_avr_hifi.h | 19 +++++++++++++++++++ .../config_example_avr_legacy_standard_mode.h | 15 +++++++++++++++ ...fig_example_avr_legacy_standardplus_mode.h | 18 ++++++++++++++++++ config/config_example_avr_stereo.h | 15 +++++++++++++++ config/config_example_external.h | 15 +++++++++++++++ .../mozzi_config_documentation.h | 0 6 files changed, 82 insertions(+) create mode 100644 config/config_example_avr_hifi.h create mode 100644 config/config_example_avr_legacy_standard_mode.h create mode 100644 config/config_example_avr_legacy_standardplus_mode.h create mode 100644 config/config_example_avr_stereo.h create mode 100644 config/config_example_external.h rename MozziConfigExample.h => config/mozzi_config_documentation.h (100%) diff --git a/config/config_example_avr_hifi.h b/config/config_example_avr_hifi.h new file mode 100644 index 000000000..1d02316c5 --- /dev/null +++ b/config/config_example_avr_hifi.h @@ -0,0 +1,19 @@ +/* Configuration example + +This example is targetted at the AVR platform (Arduino Uno & friends), only! + +Set configuration options according to the mode that was formerly known as "HIFI". +Do read up on the required hardware circuitry! */ + +#include "MozziConfigValues.h" // for named option values + +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +//#define MOZZI_AUDIO_RATE 32768 // the default, in this mode +//#define MOZZI_PWM_RATE 125000 // the default, in this mode +//#define MOZZI_AUDIO_BITS_PER_CHANNEL 2 // the default, in this mode + +// should you wish to customize the output pins: +//#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN +//#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin +//#define AUDIO_AUDIO_PIN_1_LOW TIMER1_B_PIN +//#define MOZZI_AUDIO_PIN_1_LOW_REGISTER OCR1B // must also specify the hardware register responsible for this pin diff --git a/config/config_example_avr_legacy_standard_mode.h b/config/config_example_avr_legacy_standard_mode.h new file mode 100644 index 000000000..87efbe3a6 --- /dev/null +++ b/config/config_example_avr_legacy_standard_mode.h @@ -0,0 +1,15 @@ +/* Configuration example + +This example is targetted at the AVR platform (Arduino Uno & friends), only! + +Set configuration options according to the mode that was formerly known as "STANDARD" (not STANDARD_PLUS). */ + +#include "MozziConfigValues.h" // for named option values + +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM +#define MOZZI_AUDIO_RATE 16384 +#define MOZZI_PWM_RATE 16384 + +// should you wish to customize the output pin: +//#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN +//#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin diff --git a/config/config_example_avr_legacy_standardplus_mode.h b/config/config_example_avr_legacy_standardplus_mode.h new file mode 100644 index 000000000..73b386fc1 --- /dev/null +++ b/config/config_example_avr_legacy_standardplus_mode.h @@ -0,0 +1,18 @@ +/* Configuration example + +This example is targetted at the AVR platform (Arduino Uno & friends), only! + +The configuration formerly known as STANDARD_PLUS is still the default on AVR, so you +do not need to configure anything! This file just lists the relevant settings involved: */ + +#include "MozziConfigValues.h" // for named option values + +// all of these are the defaults on AVR, anyway, thus commented +//#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM +//#define MOZZI_AUDIO_RATE 32768 +//#define MOZZI_PWM_RATE 16384 + + +// should you wish to customize the output pin: +//#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN +//#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin diff --git a/config/config_example_avr_stereo.h b/config/config_example_avr_stereo.h new file mode 100644 index 000000000..57d402d20 --- /dev/null +++ b/config/config_example_avr_stereo.h @@ -0,0 +1,15 @@ +/* Configuration example + +This example is targetted at the AVR platform (Arduino Uno & friends), only! + +This example shows setting up stereo mode on AVR. */ + +#include "MozziConfigValues.h" // for named option values + +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO + +// should you wish to customize the output pins: +//#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN +//#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin +//#define AUDIO_AUDIO_PIN_2 TIMER1_B_PIN +//#define MOZZI_AUDIO_PIN_2_REGISTER OCR1B // must also specify the hardware register responsible for this pin diff --git a/config/config_example_external.h b/config/config_example_external.h new file mode 100644 index 000000000..991ee9d86 --- /dev/null +++ b/config/config_example_external.h @@ -0,0 +1,15 @@ +/* Configuration example + +Configure Mozzi for "external" audio output. You will need to provide an audioOutput() function in your sketch. + +See TODO: link to relevant tutorial +*/ + +#include "MozziConfigValues.h" // for named option values + +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +// or use this: +//#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM + +//#define MOZZI_AUDIO_RATE 32768 // the default, in this mode +//#define AUDIO_BITS 16 // the default in this mode, but e.g. when connecting to a 24-bit DAC, you'd set 24, here. diff --git a/MozziConfigExample.h b/config/mozzi_config_documentation.h similarity index 100% rename from MozziConfigExample.h rename to config/mozzi_config_documentation.h From 34478cfae32df78f6e9cf2a37b7fec2cb2b7324b Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 19 Nov 2023 22:36:24 +0100 Subject: [PATCH 060/215] Documentation corrections and clarifcations --- AudioOutput.h | 70 +++++++++++-------- ...fig_example_avr_legacy_standardplus_mode.h | 4 +- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index 69bad2f38..b8b3190b2 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -1,6 +1,5 @@ -/** @file AudioOutput - * - * Platform independent audio output and adding support for new platforms or output methods. +/** @ingroup conre +/** @page mozzi_audio_output_architecture Basic architecture of audio generation, buffering, and output in Mozzi * * Mozzi provides support for audio ouput on a range of different boards and CPUs. This page is about the following related topics: * @@ -10,30 +9,35 @@ * * For all of these topics, it is helpful to have a basic understanding of the basic output steps in Mozzi: * - * 1. Inside the loop() function in your sketch you call audioHook(). This function is responsible for calling updateAudio(), whenever there is room in the output buffer, - * adding the generated sample to the output buffer, calling updateControl() at an appropriate rate, and a few other details that are not important for this discussion. + * 1. Inside the loop() function in your sketch you call audioHook(). + * 1a. If the audio output buffer is currently filled, this does nothing. + * 1b. Otherwise, this calls updateAudio(). The generated sample is then added to the audio output buffer. (Also, updateControl() will be called at an appropriate rate, + * and a few other details that are not important for this discussion.) * * 2. A platform-specific timer is triggered at audio rate (usually), takes a sample from the output buffer and sends it to audioOutput(). * * 3. The audioOutput() function - usually predefined inside Mozzi - takes care of sending the sample to the hardware. - * // TODO refer to @see external_audio for most of this, instead. * - * This basic output pipeline can be customized in several ways. First, defining EXTERNAL_AUDIO_OUTPUT to true in mozzi_config.h will allow you to define your own audioOutput() - * fuction. The library ships with some sample sketches for output to external DACs using this mechanism. + * These output steps are not always followed, however. Firstly, when using @ref external_audio output, the audioOutput() funtion is supplied by the user sketch, + * instead of Mozzi. @ref external_audio output. * - * In some cases, you will additionally want to bypass Mozzis output buffer, for example, if your board, or your external DAC already comes with an efficient built-in buffer. - * In this case, define BYPASS_MOZZI_OUTPUT_BUFFER to true. You will then have to provide a custom definition of canBufferAudioOutput(), returning true whenever your hardware - * is ready toaccept a new sample of output. This is called from inside audioHook(), and whenever there is room for a new sample, it is generated and sent to audioOutput(), - * immediately. In this case, should you need a timer running at AUDIO_RATE, you will have to set up one, yourself, if needed. + * Some ports will also want to bypass the Mozzi audio output buffer. For instance, an internal DAC may be addressable via an efficient DMA-connected + * buffer, already, and also have a built-in rate control. In this case, ports will internally set the define @ref BYPASS_MOZZI_OUTPUT_BUFFER to true. Such a port will + * have to provide a custom definition of canBufferAudioOutput(), returning true, whenever a new sample of output can be accepted. No timer at audio-rate is set up in this + * case. * - * In custom code, setting BYPASS_MOZZI_OUTPUT_BUFFER does not make much sense without EXTERNAL_AUDIO_OUTPUT also set to true. However, some platform ports (e.g. ESP32) actually - * use this combination, internally. + * Finally, the @ref external_audio output mode @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM is essentially a combination of the two. Here, the user sketch needs to provide + * both audioOutput() and canBufferAudioOutput(). The latter is again called from audioHook(), and whenever it returns true, a new sample is generated and passed to + * audioOutput(). * + * @section audio_shifting Platform specific audio resolution * Different output methods often support a different resolution of output samples. To provide best performance on slow boards, Mozzi expects your updateAudio() function to * return samples in exactly the width that is needed at the output stage. Thus, defining this naively, an updateAudio() function designed for 8 bit output will produce very * low volume output on a 16 bit DAC, while the other way around overflows will result in way too loud and heavily distored output. Fortunately, all that is needed to write * portable sketches is to specify how many bits your updateAudio() function provides. The (inline) functions in the AudioOutput namespace do just that. Using them makes sure * your audio output is shifted if, and as much as needed on all platforms. + * + * @see MonoOutput::fromNBit(), StereoOutput::fromNBit() */ #ifndef AUDIOOUTPUT @@ -80,7 +84,7 @@ #endif /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to two int values, but the struct provides - * useful API an top of that. For more detail @see MonoOutput . */ + * useful API an top of that. For more detail see @ref MonoOutput . */ struct StereoOutput { /** Construct an audio frame from raw values (zero-centered) */ StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r) : _l(l), _r(r) {}; @@ -94,16 +98,16 @@ struct StereoOutput { #endif AudioOutputStorage_t l() const { return _l; }; AudioOutputStorage_t r() const { return _r; }; - /** @see MonoOutput::clip(). Clips both channels. */ + /** See @ref MonoOutput::clip(). Clips both channels. */ StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; }; - /** @see MonoOutput::fromNBit(), stereo variant */ + /** See @ref MonoOutput::fromNBit(), stereo variant */ template static inline StereoOutput fromNBit(uint8_t bits, T l, T r) { return StereoOutput(SCALE_AUDIO(l, bits), SCALE_AUDIO(r, bits)); } - /** @see MonoOutput::from8Bit(), stereo variant */ + /** See @ref MonoOutput::from8Bit(), stereo variant */ static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); } - /** @see MonoOutput::from16Bit(), stereo variant */ + /** See @ref MonoOutput::from16Bit(), stereo variant */ static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); } - /** @see MonoOutput::fromAlmostNBit(), stereo variant */ + /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */ template static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); } private: AudioOutputStorage_t _l; @@ -121,7 +125,7 @@ template static inline StereoOutput fromNBit(uint8_t bits, T l, T r) * c) The struct provides accessors l() and r() that are source-compatible with StereoOutput, making it easy to e.g. implement support for an external DAC in both mono * and stereo. * d) Finally, an automatic conversion operator to int aka AudioOutput_t provides backward compatibility with old Mozzi sketches. Internally, the compiler will actually - * do away with this wholw struct, leaving just the same basic fast integer operations as in older Mozzi sketches. However, now, you don't have to rewrite those for + * do away with this whole struct, leaving just the same basic fast integer operations as in older Mozzi sketches. However, now, you don't have to rewrite those for * different configurations. */ struct MonoOutput { @@ -146,7 +150,7 @@ struct MonoOutput { * bits available. While this function takes care of the shifting, beware of potential overflow issues, if your intermediary results exceed the 16 bit range. Use proper * casts to int32_t or larger in that case (and the compiler will automatically pick the 32 bit overload in this case) */ template static inline MonoOutput fromNBit(uint8_t bits, T l) { return MonoOutput(SCALE_AUDIO(l, bits)); } - /** Construct an audio frame from a zero-centered value known to be in the 8 bit range. On AVR, STANDADR or STANDARD_PLUS mode, this is effectively the same as calling the + /** Construct an audio frame from a zero-centered value known to be in the 8 bit range. On AVR, if MOZZI_OUTPUT_PWM mode, this is effectively the same as calling the * constructor, directly (no scaling gets applied). On platforms/configs using more bits, an appropriate left-shift will be performed. */ static inline MonoOutput from8Bit(int16_t l) { return fromNBit(8, l); } /** Construct an audio frame a zero-centered value known to be in the 16 bit range. This is jsut a shortcut for fromNBit(16, ...) provided for convenience. */ @@ -154,10 +158,12 @@ struct MonoOutput { /** Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit range, e.g. at N=8 bits and a litte. On most platforms, this is * exactly the same as fromNBit(), shifting up or down to the platforms' available resolution. * - * However, on AVR, STANDARD(_PLUS) (where about 8.5 bits are usable), the value will be shifted to the (almost) 9 bit range, instead of to the 8 bit range. allowing to - * make use of that extra half bit of resolution. In many cases it is useful to follow up this call with clip(). + * However, on AVR, MOZZI_OUTPUT_PWM mode (where about 8.5 bits are usable), the value will be shifted to the (almost) 9 bit range, instead of to the 8 bit range. allowing to + * make use of that extra half bit of resolution. In many cases it is useful to follow up this call with clip(). E.g.: * - * @example fromAlmostNBit(10, oscilA.next() + oscilB.next() + oscilC.next()); + * @code + * return MonoOutput::fromAlmostNBit(10, oscilA.next() + oscilB.next() + oscilC.next()).clip(); + * @endcode */ template static inline MonoOutput fromAlmostNBit(A bits, B l) { return MonoOutput(SCALE_AUDIO_NEAR(l, bits)); } @@ -166,15 +172,17 @@ struct MonoOutput { }; -/** When setting EXTERNAL_AUDIO_OUTPUT to true, implement this function to take care of writing samples to the hardware. */ +/** When setting using one of the external output modes (@ref MOZZI_OUTPUT_EXTERNAL_TIMED or @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM) implement this function to take care of writing samples to the hardware. + * In all otther cases, it will be provided by the platform implementation. You should never call this function, directly, in your sketch. */ void audioOutput(const AudioOutput f); -#if BYPASS_MOZZI_OUTPUT_BUFFER -/** When setting BYPASS_MOZZI_OUTPUT_BUFFER to true, implement this function to return true, if and only if your hardware (or custom buffer) is ready to accept the next sample. */ +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) +/** For @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM implement this function to return true, if and only if your hardware (or custom buffer) is ready to accept the next sample. */ inline bool canBufferAudioOutput(); #endif /** Perform one step of (fast) pdm encoding, returning 8 "bits" (i.e. 8 ones and zeros). - * You will usually call this at least four or eight times for a single input sample. + * You will usually call this at least four or eight times, and possibly much more often + * for a single input sample. * * The return type is defined as uint32_t to avoid conversion steps. Actually, only the 8 lowest * bits of the return value are set. */ @@ -190,7 +198,9 @@ inline uint32_t pdmCode8(uint16_t sample) { // Note that sample only has 16 bits, while the // highest bit we consider for writing is bit 17. // Thus, if the highest bit is set, the next - // three bits cannot be. + // three bits cannot be. (highest possible values: + // nexttarget-lastwritten == 0b00001111111111111, + // sample == 0b01111111111111111) nexttarget += sample; nexttarget -= lastwritten; lastwritten = nexttarget & 0b11110000000000000; diff --git a/config/config_example_avr_legacy_standardplus_mode.h b/config/config_example_avr_legacy_standardplus_mode.h index 73b386fc1..22acf93a4 100644 --- a/config/config_example_avr_legacy_standardplus_mode.h +++ b/config/config_example_avr_legacy_standardplus_mode.h @@ -9,8 +9,8 @@ do not need to configure anything! This file just lists the relevant settings in // all of these are the defaults on AVR, anyway, thus commented //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM -//#define MOZZI_AUDIO_RATE 32768 -//#define MOZZI_PWM_RATE 16384 +//#define MOZZI_AUDIO_RATE 16384 +//#define MOZZI_PWM_RATE 32768 // should you wish to customize the output pin: From 40ee79fc3ada2d191d3ac1d520317a7cee59b780 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 19 Nov 2023 22:45:10 +0100 Subject: [PATCH 061/215] Clean up some outdated comments --- AudioOutput.h | 2 +- MozziGuts_impl_MBED.hpp | 1 - internal/config_checks_renesas.h | 5 +---- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index b8b3190b2..12f149e04 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -78,7 +78,7 @@ * in mozzi_config.h. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g. * both have functions l() and r(), to return "two" audio channels (which will be the same in case of mono). * - * You will not usually use or encounter this definition, unless using EXTERNAL_AUDIO_OUTPUT. + * You will not usually use or encounter this definition, unless using @ref external_audio output mode. */ #define AudioOutput MonoOutput #endif diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index f9784bad8..fb06f904f 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -145,7 +145,6 @@ inline void commitBuffer(Sample buffer[], AdvancedDAC &dac) { dac.write(dmabuf); } -/** NOTE: This is the function that actually write a sample to the output. In case of EXTERNAL_AUDIO_OUTPUT == true, it is provided by the library user, instead. */ inline void audioOutput(const AudioOutput f) { if (bufpos >= CHUNKSIZE) { commitBuffer(buf1, dac1); diff --git a/internal/config_checks_renesas.h b/internal/config_checks_renesas.h index fe8083c63..53e33a40c 100644 --- a/internal/config_checks_renesas.h +++ b/internal/config_checks_renesas.h @@ -20,10 +20,7 @@ * - MOZZI_OUTPUT_INTERNAL_DAC * * The default mode is @ref renesas_internal_dac. Further modes may be added in the future. - - Because this board has an on-board DAC (A0), but only one, STEREO is not implemented and Mozzi uses this pin. Usage of other pins using PWM for instance is not implemented yet. - - Two timers are claimed by Mozzi when using the on-board DAC, one when using `EXTERNAL_AUDIO_OUTPUT`. - - `mozziAnalogRead()` returns values in the Renesas' full ADC resolution of 0-16384 rather than AVR's 0-1023. *This might change in the near future for speed purposes.* - + * * @section renesas_internal_dac MOZZI_OUTPUT_INTERNAL_DAC * This uses the inbuild DAC on the board on pin A0. Mono output only, and the pin is not configurable. Audio resolution is also fixed at 12 bits (which is what the board supports). * From 59f83cd4966653a8b892ae7894daf478aacd647d Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 22 Nov 2023 20:57:31 +0100 Subject: [PATCH 062/215] Fixed RP2040 documentation and I2S, added config option for RP2040 --- MozziGuts_impl_RP2040.hpp | 4 ++-- config/config_example_rp2040_i2s_pt8211.h | 18 ++++++++++++++++++ config/config_example_rp2040_pwm.h | 16 ++++++++++++++++ internal/config_checks_rp2040.h | 4 ++-- 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 config/config_example_rp2040_i2s_pt8211.h create mode 100644 config/config_example_rp2040_pwm.h diff --git a/MozziGuts_impl_RP2040.hpp b/MozziGuts_impl_RP2040.hpp index 22fa58299..1b2b87623 100644 --- a/MozziGuts_impl_RP2040.hpp +++ b/MozziGuts_impl_RP2040.hpp @@ -257,9 +257,9 @@ static void startAudio() { } void stopMozzi() { -#if (RP2040_AUDIO_OUT_MODE == PWM_VIA_BARE_CHIP) || (EXTERNAL_AUDIO_OUTPUT == true) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) hardware_alarm_set_callback(audio_update_alarm_num, NULL); -#elif (RP2040_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S) +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) i2s.end(); #endif diff --git a/config/config_example_rp2040_i2s_pt8211.h b/config/config_example_rp2040_i2s_pt8211.h new file mode 100644 index 000000000..155d7ba98 --- /dev/null +++ b/config/config_example_rp2040_i2s_pt8211.h @@ -0,0 +1,18 @@ +/* Configuration example + +This example is targetted at the RP2040 (raspberry Pi pico) platform only! + +Configure the Raspberry Pico to output sound on a I2S DAC on LSBJ format (like the PT8211). */ + + +#include "MozziConfigValues.h" // for named option values + +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_I2S_DAC +#define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_LSBJ // PT8211 is on LSBJ format + +// all of these are the defaults on RP2040 outputting on I2S, anyway, thus commented +#define MOZZI_AUDIO_BITS 16 +#define MOZZI_I2S_PIN_BCK 20 +#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21 +#define MOZZI_I2S_PIN_DATA 22 + diff --git a/config/config_example_rp2040_pwm.h b/config/config_example_rp2040_pwm.h new file mode 100644 index 000000000..9f94b56e2 --- /dev/null +++ b/config/config_example_rp2040_pwm.h @@ -0,0 +1,16 @@ +/* Configuration example + +This example is targetted at the RP2040 (raspberry Pi pico) platform only! + +The configuration formerly known as STANDARD_PLUS is still the default on RP2040, so you +do not need to configure anything! This file just lists the relevant settings involved: */ + +#include "MozziConfigValues.h" // for named option values + +// all of these are the defaults on RP2040, anyway, thus commented +//#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM +//#define MOZZI_AUDIO_RATE 32768 + + +// should you wish to customize the output pin: +//#define AUDIO_AUDIO_PIN_1 0 diff --git a/internal/config_checks_rp2040.h b/internal/config_checks_rp2040.h index 2a9a734e8..493c808f2 100644 --- a/internal/config_checks_rp2040.h +++ b/internal/config_checks_rp2040.h @@ -39,7 +39,7 @@ * * @section rp2040_i2s_dac MOZZI_OUTPUT_I2S_DAC * Output to an external DAC, connected via I2S. This uses 16 bit (per audio channel), but can be changed to 8, 16, 24 (left aligned) and 32 resolution. - * Both plain I2S and LSBJ format (PT8211 needs this, for instance) are available. LSBJ format is used by default. The GPIO pins to use can be configured, + * Both plain I2S and LSBJ format (PT8211 needs this, for instance) are available. Plain format is used by default. The GPIO pins to use can be configured, * - almost - freely (see below). Two DMA channels are claimed (numbers not hardcoded), non-exclusive handlers are installed on DMA_IRQ_0. * * Configuration options: @@ -48,7 +48,7 @@ * #define MOZZI_I2S_PIN_BCK ... // /BLCK) default is 20 * //#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) ... // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21 * #define MOZZI_I2S_PIN_DATA ... // (DOUT) default is 22 - * #define MOZZI_I2S_FORMAT ... // may be MOZZI_I2S_FORMAT_LSBJ (default) or MOZZI_I2S_FORMAT_PLAIN + * #define MOZZI_I2S_FORMAT ... // may be MOZZI_I2S_FORMAT_LSBJ or MOZZI_I2S_FORMAT_PLAIN (default) * @endcode * * @note From a39e5dcd3584619bc9078560c314486326c88280 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 26 Nov 2023 18:26:56 +0100 Subject: [PATCH 063/215] Clarification and corrected MOZZI_AUDIO_BITS for external config --- config/config_example_external.h | 2 +- ...040_i2s_pt8211.h => config_example_rp2040_i2s_pt8211_mono.h} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename config/{config_example_rp2040_i2s_pt8211.h => config_example_rp2040_i2s_pt8211_mono.h} (84%) diff --git a/config/config_example_external.h b/config/config_example_external.h index 991ee9d86..2017f61bf 100644 --- a/config/config_example_external.h +++ b/config/config_example_external.h @@ -12,4 +12,4 @@ See TODO: link to relevant tutorial //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM //#define MOZZI_AUDIO_RATE 32768 // the default, in this mode -//#define AUDIO_BITS 16 // the default in this mode, but e.g. when connecting to a 24-bit DAC, you'd set 24, here. +//#define MOZZI_AUDIO_BITS 16 // the default in this mode, but e.g. when connecting to a 24-bit DAC, you'd set 24, here. diff --git a/config/config_example_rp2040_i2s_pt8211.h b/config/config_example_rp2040_i2s_pt8211_mono.h similarity index 84% rename from config/config_example_rp2040_i2s_pt8211.h rename to config/config_example_rp2040_i2s_pt8211_mono.h index 155d7ba98..ed1611ae7 100644 --- a/config/config_example_rp2040_i2s_pt8211.h +++ b/config/config_example_rp2040_i2s_pt8211_mono.h @@ -2,7 +2,7 @@ This example is targetted at the RP2040 (raspberry Pi pico) platform only! -Configure the Raspberry Pico to output sound on a I2S DAC on LSBJ format (like the PT8211). */ +Configure the Raspberry Pico to output sound in mono on a I2S DAC on LSBJ format (like the PT8211). */ #include "MozziConfigValues.h" // for named option values From 435855d541caec33a4f6acfd6464ccf82b277680 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 28 Nov 2023 20:29:12 +0100 Subject: [PATCH 064/215] Fix AudioExternal for giga --- MozziGuts_impl_MBED.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index fb06f904f..5f612cc14 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -119,7 +119,7 @@ inline void defaultAudioOutputCallback() { static void startAudio() { audio_output_timer.attach_us(&defaultAudioOutputCallback, US_PER_AUDIO_TICK); - startAudioInput(), + startAudioInput(); } void stopMozzi() { From d5976e812f365f77a5ae6322bccd0b68175869c0 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 29 Nov 2023 19:23:12 +0100 Subject: [PATCH 065/215] Fix of mozziAnalogRead for Renesas --- MozziGuts_impl_RENESAS_ADC.hpp | 87 +++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/MozziGuts_impl_RENESAS_ADC.hpp b/MozziGuts_impl_RENESAS_ADC.hpp index c9a01fb24..079486e67 100644 --- a/MozziGuts_impl_RENESAS_ADC.hpp +++ b/MozziGuts_impl_RENESAS_ADC.hpp @@ -5,12 +5,97 @@ It contains functions to interact with the ADC in order to implement async ADC r */ #include -#include +//#include #include +/** VERBATIM from Arduino's analog.cpp + */ +#define MAX_ADC_CHANNELS 29 +static uint16_t analog_values_by_channels[MAX_ADC_CHANNELS] = {0}; +static void ADC_irq_cbk(adc_callback_args_t * cb_data); +static ADC_Container adc(0,ADC_irq_cbk); +static ADC_Container adc1(1,ADC_irq_cbk); +static ADCIrqCbk_f scan_complete_cbk = nullptr; +static ADCIrqCbk_f scan_complete_b_cbk = nullptr; +static ADCIrqCbk_f window_compare_a_cbk = nullptr; +static ADCIrqCbk_f window_compare_b_cbk = nullptr; +static void readAllGroupA(ADC_Container *_adc) { + for(int i = 0; i < MAX_ADC_CHANNELS; i++) { + if(_adc->channel_cfg.scan_mask & (1 << i)) { + //is the channel active -> yes, read it + R_ADC_Read(&(_adc->ctrl), (adc_channel_t)i, analog_values_by_channels + i); + } + } +} + +static void readAllGroupB(ADC_Container *_adc) { + for(int i = 0; i < MAX_ADC_CHANNELS; i++) { + if(_adc->channel_cfg.scan_mask_group_b & (1 << i)) { + //is the channel active -> yes, read it + R_ADC_Read(&(_adc->ctrl), (adc_channel_t)i, analog_values_by_channels + i); + } + } +} + + +static void ADC_irq_cbk(adc_callback_args_t * cb_data) { + if(cb_data->event == ADC_EVENT_SCAN_COMPLETE) { + if(scan_complete_cbk != nullptr) { + if(cb_data->unit == 0) { + readAllGroupA(&adc); + } + else if(cb_data->unit == 1) { + readAllGroupA(&adc1); + } + scan_complete_cbk(cb_data->unit); + } + } + else if(cb_data->event == ADC_EVENT_SCAN_COMPLETE_GROUP_B) { + if(scan_complete_b_cbk != nullptr) { + if(cb_data->unit == 0) { + readAllGroupB(&adc); + } + else if(cb_data->unit == 1) { + readAllGroupB(&adc1); + } + scan_complete_b_cbk(cb_data->unit); + } + } + else if(cb_data->event == ADC_EVENT_WINDOW_COMPARE_A) { + if(window_compare_a_cbk != nullptr) { + window_compare_a_cbk(cb_data->unit); + } + } + else if(cb_data->event == ADC_EVENT_WINDOW_COMPARE_B) { + if(window_compare_b_cbk != nullptr) { + window_compare_b_cbk(cb_data->unit); + } + } +} + +/* -------------------------------------------------------------------------- */ +static ADC_Container *get_ADC_container_ptr(int32_t pin, uint16_t &cfg) { +/* -------------------------------------------------------------------------- */ + ADC_Container *rv = nullptr; + auto cfg_adc = getPinCfgs(pin, PIN_CFG_REQ_ADC); + if(cfg_adc[0] > 0 ) { + if(IS_ADC1(cfg_adc[0])) { + rv = &adc1; + } + else { + rv = &adc; + } + } + cfg = cfg_adc[0]; + return rv; + +} + +/* END of verbatim + */ //////////////////// ADC ////////////// void startScan(int pin) From 222cda90a6b927adb490e1308a66df3c6e1c3217 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 1 Jan 2024 22:16:37 +0100 Subject: [PATCH 066/215] Fix /* in comment --- AudioOutput.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioOutput.h b/AudioOutput.h index 12f149e04..0fc3b3f94 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -1,5 +1,5 @@ /** @ingroup conre -/** @page mozzi_audio_output_architecture Basic architecture of audio generation, buffering, and output in Mozzi + * @page mozzi_audio_output_architecture Basic architecture of audio generation, buffering, and output in Mozzi * * Mozzi provides support for audio ouput on a range of different boards and CPUs. This page is about the following related topics: * From aa32d0067ea25b562d9e3f2f77c06635ebb14293 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 1 Jan 2024 22:31:26 +0100 Subject: [PATCH 067/215] Fix mixup of PDM and PWM --- internal/config_checks_rp2040.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/config_checks_rp2040.h b/internal/config_checks_rp2040.h index 493c808f2..467f9948b 100644 --- a/internal/config_checks_rp2040.h +++ b/internal/config_checks_rp2040.h @@ -20,12 +20,12 @@ * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: * - MOZZI_OUTPUT_EXTERNAL_TIMED * - MOZZI_OUTPUT_EXTERNAL_CUSTOM - * - MOZZI_OUTPUT_PDM + * - MOZZI_OUTPUT_PWM * - MOZZI_OUTPUT_I2S_DAC * - * The default mode is @ref rp2040_pdm . + * The default mode is @ref rp2040_pwm . * - * @section rp2040_pdm MOZZI_OUTPUT_PDM + * @section rp2040_pdm MOZZI_OUTPUT_PWM * Audio output is written to pin 0 (mono) or 0 and 1 (stereo), by default, with 11 bits of ouput resolution. * One hardware timer interrupt and one DMA channel are claimed (number not hardcoded), a non-exclusive handler is installed on DMA_IRQ_0. * From da0b028b74c395caaec4e4afd68777b71817aa45 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 3 Jan 2024 15:40:26 +0100 Subject: [PATCH 068/215] Corrected important type for STM32 (Maple core) --- MozziGuts_impl_STM32.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MozziGuts_impl_STM32.hpp b/MozziGuts_impl_STM32.hpp index 35579b6be..3c5969ba0 100644 --- a/MozziGuts_impl_STM32.hpp +++ b/MozziGuts_impl_STM32.hpp @@ -63,7 +63,7 @@ void setupFastAnalogRead(int8_t speed) { //// BEGIN AUDIO OUTPUT code /////// -#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXERNAL_TIMED) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER); #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER); @@ -83,7 +83,7 @@ inline void audioOutput(const AudioOutput f) { #endif static void startAudio() { -#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXERNAL_TIMED) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) audio_update_timer.pause(); //audio_update_timer.setPeriod(1000000UL / AUDIO_RATE); // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors @@ -132,7 +132,7 @@ static void startAudio() { } void stopMozzi() { -#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXERNAL_TIMED) +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) audio_update_timer.pause(); #endif } From dc2428f3c2ea0d68e76932d2cb5b1445405e0f51 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 4 Jan 2024 11:28:11 +0100 Subject: [PATCH 069/215] Start reducing number of compilation units (trivial cases, first) --- extras/NEWS.txt | 6 +++++- mozzi_analog.cpp | 56 ------------------------------------------------ mozzi_analog.h | 32 ++++++++++++++++++++------- mozzi_utils.cpp | 36 ------------------------------- mozzi_utils.h | 35 ++++++++++++++++++++++++++++-- 5 files changed, 62 insertions(+), 103 deletions(-) delete mode 100644 mozzi_analog.cpp delete mode 100644 mozzi_utils.cpp diff --git a/extras/NEWS.txt b/extras/NEWS.txt index 9aec0b01b..6cc2ec4b5 100644 --- a/extras/NEWS.txt +++ b/extras/NEWS.txt @@ -3,7 +3,11 @@ Mozzi sound synthesis library for Arduino NEWS get the latest version from https://sensorium.github.io/Mozzi/ -not yet released (latest github version) +NOT YET RELEASED (github version): Mozzi 2.0 +- explicitly specify bit depth for "int" or "long" in several places, for better cross-platform consistency +- restructured configuration options for more consistency across platforms, and easier customization + +release v1.1.2 - new partial port of the Arduino Uno R4 - new partial port of the Arduino Giga by Thomas Friedrichsmeier & Thomas Combriat - new (partial) port to the STM32duino core by Thomas Friedrichsmeier diff --git a/mozzi_analog.cpp b/mozzi_analog.cpp deleted file mode 100644 index 72fd2ab82..000000000 --- a/mozzi_analog.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * mozzi_analog.cpp - * - * Copyright 2012 Tim Barrass. - * - * This file is part of Mozzi. - * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. - * - */ - - -#include "mozzi_analog.h" - -#include "hardware_defines.h" -#include "mozzi_config.h" - -/** NOTE: Since analog input code is heavily hardware dependent, and also heavily interweaved with AUDIO_INPUT, - * it was moved to MozziGuts.cpp / MozziGuts_impl_XYZ.hpp for better maintainability. - * - * TODO: The (dis|re)connect functions below remain for now, as I'm not sure what to do about them. They were only ever - * implemented for AVR. - */ - -void disconnectDigitalIn(uint8_t channel_num){ -#if IS_AVR() - DIDR0 |= 1<> 23) - 0x7f; -} - -Here's an alternate, trivial version: -uint8_t trailingZeros(uint16_t v) { - uint8_t ret = 0; - while ((v % 2) == 0) { - v = v >> 1; - ++ret; - } - return ret; -} */ - - - /** Convert BPM to milliseconds, which can be used to set the delay between beats for Metronome. - @param bpm beats per minute - */ - unsigned int BPMtoMillis(float bpm){ - float seconds_per_beat = 60.f/bpm; - return (unsigned int) (seconds_per_beat*1000); - } diff --git a/mozzi_utils.h b/mozzi_utils.h index 5ee8671c5..a21f4b03b 100644 --- a/mozzi_utils.h +++ b/mozzi_utils.h @@ -59,8 +59,39 @@ void setPin13Low() } +/** @ingroup util +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. +@param a power of 2, or any other number for that matter +@return the number of trailing zeros on the right hand end +*/ constexpr uint8_t trailingZerosConst(unsigned long v) { return ((v % 2) ? 0 : 1+trailingZerosConst(v >> 1)); } -//uint8_t trailingZeros(uint16_t v); -unsigned int BPMtoMillis(float bpm); +/* 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. + * 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, + * 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. +long trailingZeros(unsigned long v) { + // find the number of trailing zeros in v, from http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightFloatCast + // there are faster methods on the bit twiddling site, but this is short + float f = (float)(v & -v); // cast the least significant bit in v to a float + return (*(uint32_t *)&f >> 23) - 0x7f; +} + +Here's an alternate, trivial version: +uint8_t trailingZeros(uint16_t v) { + uint8_t ret = 0; + while ((v % 2) == 0) { + v = v >> 1; + ++ret; + } + return ret; +} */ + + +/** Convert BPM to milliseconds, which can be used to set the delay between beats for Metronome. +@param bpm beats per minute +*/ +constexpr uint16_t BPMtoMillis(float bpm){ + //float seconds_per_beat = 60.f/bpm; + return (uint16_t) (((float) 60.f/bpm)*1000); +} #endif /* UTILS_H_ */ From 2fa17a40489347eed23d5d67d91e588058fe3596 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 4 Jan 2024 12:45:38 +0100 Subject: [PATCH 070/215] Move auto random seeding to hardware specific implementation files (This is expected to increase flash size, marginally, but the effect will mostly go away once implementation and usage are once again in the same compilation unit.) --- MozziGuts_impl_AVR.hpp | 46 +++++++++++++++ MozziGuts_impl_ESP32.hpp | 8 +++ MozziGuts_impl_ESP8266.hpp | 11 ++++ MozziGuts_impl_MBED.hpp | 6 ++ MozziGuts_impl_RENESAS.hpp | 6 ++ MozziGuts_impl_RP2040.hpp | 6 ++ MozziGuts_impl_SAMD.hpp | 6 ++ MozziGuts_impl_STM32.hpp | 21 +++++++ MozziGuts_impl_STM32duino.hpp | 6 ++ MozziGuts_impl_TEENSY.hpp | 6 ++ MozziGuts_impl_template.hpp | 12 ++++ mozzi_rand.cpp | 107 ++++------------------------------ 12 files changed, 146 insertions(+), 95 deletions(-) diff --git a/MozziGuts_impl_AVR.hpp b/MozziGuts_impl_AVR.hpp index e877c87b0..635780e5f 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/MozziGuts_impl_AVR.hpp @@ -377,3 +377,49 @@ void stopMozzi() { // Timer1.isrCallback(); // } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +#if defined (__AVR_ATmega644P__) + +// a less fancy version for gizduino (__AVR_ATmega644P__) which doesn't know INTERNAL +static long longRandom() +{ + return ((long)analogRead(0)+63)*(analogRead(1)+97); // added offsets in case analogRead is 0 +} + +#else + +/* +longRandom(), used as a seed generator, comes from: +http://arduino.cc/forum/index.php/topic,38091.0.html +// AUTHOR: Rob Tillaart +// PURPOSE: Simple Random functions based upon unreliable internal temp sensor +// VERSION: 0.1 +// DATE: 2011-05-01 +// +// Released to the public domain, use at own risk +// +*/ +static long longRandom() +{ + //analogReference(INTERNAL); + unsigned long rv = 0; + for (uint8_t i=0; i< 32; i++) rv |= ((analogRead(8)+1171) & 1L) << i; // added 1171 in case analogRead is 0 + return rv; +} +#endif + +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { + ADCSRA &= ~ (1 << ADIE); // adc Disable Interrupt, re-enable at end + // this attempt at remembering analog_reference stops it working + // maybe needs a delay after changing analog reference in longRandom (Arduino reference suggests this) + // because the analog reads return 0 + //uint8_t analog_reference_orig = ADMUX&192; // analog_reference is high 2 bits of ADMUX, store this because longRandom sets it to internal + *x = longRandom(); + *y = longRandom(); + *z = longRandom(); + //analogReference(analog_reference_orig); // change back to original + ADCSRA |= (1 << ADIE); // adc re-Enable Interrupt +} + +//// END Random seeding //////// diff --git a/MozziGuts_impl_ESP32.hpp b/MozziGuts_impl_ESP32.hpp index b20c92772..2991bdc5c 100644 --- a/MozziGuts_impl_ESP32.hpp +++ b/MozziGuts_impl_ESP32.hpp @@ -161,4 +161,12 @@ void stopMozzi() { } //// END AUDIO OUTPUT code /////// +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { + *x = esp_random(); + *y = esp_random(); + *z = esp_random(); +} +//// END Random seeding //////// + #undef ESP_SAMPLE_SIZE // only used inside this file diff --git a/MozziGuts_impl_ESP8266.hpp b/MozziGuts_impl_ESP8266.hpp index 3d4f3c11d..f56441c44 100644 --- a/MozziGuts_impl_ESP8266.hpp +++ b/MozziGuts_impl_ESP8266.hpp @@ -136,3 +136,14 @@ void stopMozzi() { #endif //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +#include +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { + *x = RANDOM_REG32; + // TODO: The XORs may not be needed, but for lack of documentation (that I could find), let's assume RANDOM_REG32 + // itself might not get updated on every read. NOTE: x, y, and z are initialized to non-zero, before this. + *y = *y ^ RANDOM_REG32; + *z = *z ^ RANDOM_REG32; +} +//// END Random seeding //////// diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index 5f612cc14..96f4a1008 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -221,5 +221,11 @@ void stopMozzi() { #endif ////// END audio output code ////// +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +#warning Automatic random seedings is not implemented on this platform +} +//// END Random seeding //////// + #undef CHUNKSIZE #undef US_PER_AUDIO_TICK diff --git a/MozziGuts_impl_RENESAS.hpp b/MozziGuts_impl_RENESAS.hpp index ddc9edeaf..0fbaaecd1 100644 --- a/MozziGuts_impl_RENESAS.hpp +++ b/MozziGuts_impl_RENESAS.hpp @@ -168,3 +168,9 @@ void stopMozzi() { #endif } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +#warning Automatic random seedings is not implemented on this platform +} +//// END Random seeding //////// diff --git a/MozziGuts_impl_RP2040.hpp b/MozziGuts_impl_RP2040.hpp index 1b2b87623..79daf4995 100644 --- a/MozziGuts_impl_RP2040.hpp +++ b/MozziGuts_impl_RP2040.hpp @@ -266,5 +266,11 @@ void stopMozzi() { } ////// END audio output code ////// +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +#warning Automatic random seedings is not implemented on this platform +} +//// END Random seeding //////// + #undef MOZZI_RP2040_BUFFERS #undef MOZZI_RP2040_BUFFER_SIZE diff --git a/MozziGuts_impl_SAMD.hpp b/MozziGuts_impl_SAMD.hpp index b885a28fe..84adc833b 100644 --- a/MozziGuts_impl_SAMD.hpp +++ b/MozziGuts_impl_SAMD.hpp @@ -138,3 +138,9 @@ void stopMozzi() { interrupts(); } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +#warning Automatic random seedings is not implemented on this platform +} +//// END Random seeding //////// diff --git a/MozziGuts_impl_STM32.hpp b/MozziGuts_impl_STM32.hpp index 3c5969ba0..e57956544 100644 --- a/MozziGuts_impl_STM32.hpp +++ b/MozziGuts_impl_STM32.hpp @@ -138,3 +138,24 @@ void stopMozzi() { } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { + // Unfortunately the internal temp sensor on STM32s does _not_ appear to create a lot of noise. + // Ironically, the calls to calibrate help induce some random noise. You're still fairly likely to produce two equal + // random seeds in two subsequent runs, however. + adc.enableInternalReading(); + union { + float cf; + uint32_t ci; + } conv; + conv.cf = adc.readTemp(); + *x=*x^conv.ci; + adc.calibrate(); + conv.cf = adc.readTemp(); + *y=*y^conv.ci; + adc.calibrate(); + conv.cf = adc.readTemp(); + *z=*z^conv.ci; +} +//// END Random seeding //////// diff --git a/MozziGuts_impl_STM32duino.hpp b/MozziGuts_impl_STM32duino.hpp index b24f5a749..8a56e0dcb 100644 --- a/MozziGuts_impl_STM32duino.hpp +++ b/MozziGuts_impl_STM32duino.hpp @@ -171,3 +171,9 @@ void stopMozzi() { } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +#warning Automatic random seedings is not implemented on this platform +} +//// END Random seeding //////// diff --git a/MozziGuts_impl_TEENSY.hpp b/MozziGuts_impl_TEENSY.hpp index 04c18ac73..a8efc2199 100644 --- a/MozziGuts_impl_TEENSY.hpp +++ b/MozziGuts_impl_TEENSY.hpp @@ -112,3 +112,9 @@ void stopMozzi() { interrupts(); } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +#warning Automatic random seedings is not implemented on this platform +} +//// END Random seeding //////// diff --git a/MozziGuts_impl_template.hpp b/MozziGuts_impl_template.hpp index 154c1ee29..544b1b2e2 100644 --- a/MozziGuts_impl_template.hpp +++ b/MozziGuts_impl_template.hpp @@ -156,3 +156,15 @@ void stopMozzi() { // Add here code to pause whatever mechanism moves audio samples to the output } ////// END audio output code ////// + +//// BEGIN Random seeding //////// +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { + // Add here code to initialize the values pointed to by x, y, and z to some random values + // This doesn't need to be crypographically safe. If nothing better is available, e.g. try reading an internal temperature sensor + // in order to get some noise. It also doesn't have to be fast. + // It *should* however ensure that rand() sequences will differ across reboots, after randSeed() has been called. + // x, y, and z are already initialized to non-zero, when this function is called. + // It's ok to leave this unimplemented, initially. +#warning Automatic random seedings is not implemented on this platform +} +//// END Random seeding //////// diff --git a/mozzi_rand.cpp b/mozzi_rand.cpp index f37b61a48..531b0316a 100644 --- a/mozzi_rand.cpp +++ b/mozzi_rand.cpp @@ -1,16 +1,7 @@ #include "mozzi_rand.h" -#include "hardware_defines.h" - -#if IS_STM32MAPLE() -//#include -extern STM32ADC adc; -#elif IS_ESP8266() -#include -#endif - // moved these out of xorshift96() so xorshift96() can be reseeded manually -static unsigned long x=132456789, y=362436069, z=521288629; +static uint32_t x=132456789, y=362436069, z=521288629; // static unsigned long x= analogRead(A0)+123456789; // static unsigned long y= analogRead(A1)+362436069; // static unsigned long z= analogRead(A2)+521288629; @@ -25,8 +16,7 @@ Based on Marsaglia, George. (2003). Xorshift RNGs. http://www.jstatsoft.org/v08/ unsigned long xorshift96() { //period 2^96-1 - // static unsigned long x=123456789, y=362436069, z=521288629; - unsigned long t; + uint32_t t; x ^= x << 16; x ^= x >> 5; @@ -55,48 +45,8 @@ void randSeed(unsigned long seed) x=seed; } - -#if defined (__AVR_ATmega644P__) - -// a less fancy version for gizduino (__AVR_ATmega644P__) which doesn't know INTERNAL -static long longRandom() -{ - return ((long)analogRead(0)+63)*(analogRead(1)+97); // added offsets in case analogRead is 0 -} - -#elif defined (__AVR_ATmega2560__) -/* -longRandom(), used as a seed generator, comes from: -http://arduino.cc/forum/index.php/topic,38091.0.html -// AUTHOR: Rob Tillaart -// PURPOSE: Simple Random functions based upon unreliable internal temp sensor -// VERSION: 0.1 -// DATE: 2011-05-01 -// -// Released to the public domain, use at own risk -// -*/ -static long longRandom() -{ - //analogReference(INTERNAL2V56); - unsigned long rv = 0; - for (uint8_t i=0; i< 32; i++) rv |= ((analogRead(8)+2294) & 1L) << i; // added 2294 in case analogRead is 0 - return rv; -} - -#elif IS_AVR() - -static long longRandom() -{ - //analogReference(INTERNAL); - unsigned long rv = 0; - for (uint8_t i=0; i< 32; i++) rv |= ((analogRead(8)+1171) & 1L) << i; // added 1171 in case analogRead is 0 - return rv; -} - - -#endif - +// To be defined in hardware implementations +void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z); /** @ingroup random Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used @@ -106,51 +56,18 @@ randSeed() called without a parameter uses noise from reading the Arduino's internal temperature as the seed, a technique discussed at http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there by Rob Tillaart. -@note It's not perfect, as discussed in the forum thread. -It might only work with some processors: (from the thread) -"...ATmega328P in DIP, possibly others but the duemilanove and uno will do it at least." -So far, gizduino's __AVR_ATmega644P__ chip doesn't like it, so we use (long)analogRead(0)*analogRead(1) for that instead. -It works to some degree on STM32 chips, but the produced seed is not very random at all. Again, using an appropriate -analogRead() (preferably on one or two floating input pins) is much more effective. -@todo add Teensy 3 code + +@note Intialization of the random seed is done differently on different MCUs, + but is nowhere near perfect for most (and for some it is not even implemented at all). + Many implementations (e.g. on AVR, STM32) simply rely on reading a (hopefully noisy) + internal temperature sensor. + You will often get better results by calling analogRead() - @em not mozziAnalogRead(0), in this case! - + on one or two floating (non-connected) analog pins. */ void randSeed() { -#if IS_AVR() - ADCSRA &= ~ (1 << ADIE); // adc Disable Interrupt, re-enable at end - // this attempt at remembering analog_reference stops it working - // maybe needs a delay after changing analog reference in longRandom (Arduino reference suggests this) - // because the analog reads return 0 - //uint8_t analog_reference_orig = ADMUX&192; // analog_reference is high 2 bits of ADMUX, store this because longRandom sets it to internal - x=longRandom(); - y=longRandom(); - z=longRandom(); - //analogReference(analog_reference_orig); // change back to original - ADCSRA |= (1 << ADIE); // adc re-Enable Interrupt -#elif IS_STM32MAPLE() - // Unfortunately the internal temp sensor on STM32s does _not_ appear to create a lot of noise. - // Ironically, the calls to calibrate help induce some random noise. You're still fairly likely to produce two equal - // random seeds in two subsequent runs, however. - adc.enableInternalReading(); - float dummy = adc.readTemp(); - int* dummy_int = (int*) &dummy; - x=*dummy_int; - adc.calibrate(); - dummy = adc.readTemp(); - y=*dummy_int; - adc.calibrate(); - dummy = adc.readTemp(); - z=*dummy_int; -#elif IS_ESP8266() - x = RANDOM_REG32; - y = random (0xFFFFFFFF) ^ RANDOM_REG32; - z = random (0xFFFFFFFF) ^ RANDOM_REG32; -#else -#warning Automatic random seeding not implemented on this platform -#endif + autoRandomSeeds(&x, &y, &z); } - - /** @ingroup random Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number. @param seed a number to use as a seed. From 74d2814cd88056aef501e77a5c22525a3383f51b Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 4 Jan 2024 15:12:38 +0100 Subject: [PATCH 071/215] Move the remaining bits of mozzi_rand.cpp to other locations While at it, use explict precision types. --- MozziGuts.cpp | 6 +- MozziGuts_impl_AVR.hpp | 8 +- MozziGuts_impl_ESP32.hpp | 8 +- MozziGuts_impl_ESP8266.hpp | 8 +- MozziGuts_impl_MBED.hpp | 2 +- MozziGuts_impl_RENESAS.hpp | 2 +- MozziGuts_impl_RP2040.hpp | 2 +- MozziGuts_impl_SAMD.hpp | 2 +- MozziGuts_impl_STM32.hpp | 8 +- MozziGuts_impl_STM32duino.hpp | 2 +- MozziGuts_impl_TEENSY.hpp | 2 +- MozziGuts_impl_template.hpp | 4 +- internal/mozzi_rand_p.h | 29 ++++++ mozzi_rand.cpp | 181 ---------------------------------- mozzi_rand.h | 156 +++++++++++++++++++++++++---- 15 files changed, 196 insertions(+), 224 deletions(-) create mode 100644 internal/mozzi_rand_p.h delete mode 100644 mozzi_rand.cpp diff --git a/MozziGuts.cpp b/MozziGuts.cpp index 5fe2676ee..dae408bdd 100644 --- a/MozziGuts.cpp +++ b/MozziGuts.cpp @@ -14,7 +14,7 @@ #include "CircularBuffer.h" #include "MozziGuts.h" #include "mozzi_analog.h" -//#include "mozzi_utils.h" +#include "internal/mozzi_rand_p.h" #include "AudioOutput.h" // Forward declarations of functions to be provided by platform specific implementations @@ -274,6 +274,10 @@ void startMozzi(int control_rate_hz) { startAudio(); } +uint32_t MozziRandPrivate::x=132456789; +uint32_t MozziRandPrivate::y=362436069; +uint32_t MozziRandPrivate::z=521288629; + ////// END initialization /////// // reduce Macro leakage diff --git a/MozziGuts_impl_AVR.hpp b/MozziGuts_impl_AVR.hpp index 635780e5f..30e053ea7 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/MozziGuts_impl_AVR.hpp @@ -409,15 +409,15 @@ static long longRandom() } #endif -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +void MozziRandPrivate::autoSeed() { ADCSRA &= ~ (1 << ADIE); // adc Disable Interrupt, re-enable at end // this attempt at remembering analog_reference stops it working // maybe needs a delay after changing analog reference in longRandom (Arduino reference suggests this) // because the analog reads return 0 //uint8_t analog_reference_orig = ADMUX&192; // analog_reference is high 2 bits of ADMUX, store this because longRandom sets it to internal - *x = longRandom(); - *y = longRandom(); - *z = longRandom(); + x = longRandom(); + y = longRandom(); + z = longRandom(); //analogReference(analog_reference_orig); // change back to original ADCSRA |= (1 << ADIE); // adc re-Enable Interrupt } diff --git a/MozziGuts_impl_ESP32.hpp b/MozziGuts_impl_ESP32.hpp index 2991bdc5c..3a2196146 100644 --- a/MozziGuts_impl_ESP32.hpp +++ b/MozziGuts_impl_ESP32.hpp @@ -162,10 +162,10 @@ void stopMozzi() { //// END AUDIO OUTPUT code /////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { - *x = esp_random(); - *y = esp_random(); - *z = esp_random(); +void MozziRandPrivate::autoSeed() { + x = esp_random(); + y = esp_random(); + z = esp_random(); } //// END Random seeding //////// diff --git a/MozziGuts_impl_ESP8266.hpp b/MozziGuts_impl_ESP8266.hpp index f56441c44..10d321642 100644 --- a/MozziGuts_impl_ESP8266.hpp +++ b/MozziGuts_impl_ESP8266.hpp @@ -139,11 +139,11 @@ void stopMozzi() { //// BEGIN Random seeding //////// #include -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { - *x = RANDOM_REG32; +void MozziRandPrivate::autoSeed() { + x = RANDOM_REG32; // TODO: The XORs may not be needed, but for lack of documentation (that I could find), let's assume RANDOM_REG32 // itself might not get updated on every read. NOTE: x, y, and z are initialized to non-zero, before this. - *y = *y ^ RANDOM_REG32; - *z = *z ^ RANDOM_REG32; + y = y ^ RANDOM_REG32; + z = z ^ RANDOM_REG32; } //// END Random seeding //////// diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index 96f4a1008..8babb2972 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -222,7 +222,7 @@ void stopMozzi() { ////// END audio output code ////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_RENESAS.hpp b/MozziGuts_impl_RENESAS.hpp index 0fbaaecd1..71f4dc2c6 100644 --- a/MozziGuts_impl_RENESAS.hpp +++ b/MozziGuts_impl_RENESAS.hpp @@ -170,7 +170,7 @@ void stopMozzi() { //// END AUDIO OUTPUT code /////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_RP2040.hpp b/MozziGuts_impl_RP2040.hpp index 79daf4995..51556ad0f 100644 --- a/MozziGuts_impl_RP2040.hpp +++ b/MozziGuts_impl_RP2040.hpp @@ -267,7 +267,7 @@ void stopMozzi() { ////// END audio output code ////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_SAMD.hpp b/MozziGuts_impl_SAMD.hpp index 84adc833b..a975fae86 100644 --- a/MozziGuts_impl_SAMD.hpp +++ b/MozziGuts_impl_SAMD.hpp @@ -140,7 +140,7 @@ void stopMozzi() { //// END AUDIO OUTPUT code /////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_STM32.hpp b/MozziGuts_impl_STM32.hpp index e57956544..bc881d168 100644 --- a/MozziGuts_impl_STM32.hpp +++ b/MozziGuts_impl_STM32.hpp @@ -140,7 +140,7 @@ void stopMozzi() { //// END AUDIO OUTPUT code /////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +void MozziRandPrivate::autoSeed() { // Unfortunately the internal temp sensor on STM32s does _not_ appear to create a lot of noise. // Ironically, the calls to calibrate help induce some random noise. You're still fairly likely to produce two equal // random seeds in two subsequent runs, however. @@ -150,12 +150,12 @@ void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { uint32_t ci; } conv; conv.cf = adc.readTemp(); - *x=*x^conv.ci; + x=x^conv.ci; adc.calibrate(); conv.cf = adc.readTemp(); - *y=*y^conv.ci; + y=y^conv.ci; adc.calibrate(); conv.cf = adc.readTemp(); - *z=*z^conv.ci; + z=z^conv.ci; } //// END Random seeding //////// diff --git a/MozziGuts_impl_STM32duino.hpp b/MozziGuts_impl_STM32duino.hpp index 8a56e0dcb..88d0e4be4 100644 --- a/MozziGuts_impl_STM32duino.hpp +++ b/MozziGuts_impl_STM32duino.hpp @@ -173,7 +173,7 @@ void stopMozzi() { //// END AUDIO OUTPUT code /////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_TEENSY.hpp b/MozziGuts_impl_TEENSY.hpp index a8efc2199..81ce2cf6e 100644 --- a/MozziGuts_impl_TEENSY.hpp +++ b/MozziGuts_impl_TEENSY.hpp @@ -114,7 +114,7 @@ void stopMozzi() { //// END AUDIO OUTPUT code /////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { +void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_template.hpp b/MozziGuts_impl_template.hpp index 544b1b2e2..565cb39ba 100644 --- a/MozziGuts_impl_template.hpp +++ b/MozziGuts_impl_template.hpp @@ -158,8 +158,8 @@ void stopMozzi() { ////// END audio output code ////// //// BEGIN Random seeding //////// -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z) { - // Add here code to initialize the values pointed to by x, y, and z to some random values +void MozziRandPrivate::autoSeed() { + // Add here code to initialize the values of MozziRandPrivate::x, MozziRandPrivate::y, and MozziRandPrivate::z to some random values // This doesn't need to be crypographically safe. If nothing better is available, e.g. try reading an internal temperature sensor // in order to get some noise. It also doesn't have to be fast. // It *should* however ensure that rand() sequences will differ across reboots, after randSeed() has been called. diff --git a/internal/mozzi_rand_p.h b/internal/mozzi_rand_p.h new file mode 100644 index 000000000..a056ebe51 --- /dev/null +++ b/internal/mozzi_rand_p.h @@ -0,0 +1,29 @@ +#ifndef MOZZI_RAND_P_H +#define MOZZI_RAND_P_H + +class MozziRandPrivate { +friend void randSeed(); +friend void randSeed(uint32_t); +friend uint32_t xorshift96(); + static uint32_t xorshift96() { + //period 2^96-1 + uint32_t t; + + x ^= x << 16; + x ^= x >> 5; + x ^= x << 1; + + t = x; + x = y; + y = z; + z = t ^ x ^ y; + + return z; + } + static void autoSeed(); // defined in hardware specific MozziGuts_impl-files + static uint32_t x; + static uint32_t y; + static uint32_t z; +}; + +#endif diff --git a/mozzi_rand.cpp b/mozzi_rand.cpp deleted file mode 100644 index 531b0316a..000000000 --- a/mozzi_rand.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "mozzi_rand.h" - -// moved these out of xorshift96() so xorshift96() can be reseeded manually -static uint32_t x=132456789, y=362436069, z=521288629; -// static unsigned long x= analogRead(A0)+123456789; -// static unsigned long y= analogRead(A1)+362436069; -// static unsigned long z= analogRead(A2)+521288629; - -/** @ingroup random -Random number generator. A faster replacement for Arduino's random function, -which is too slow to use with Mozzi. -Based on Marsaglia, George. (2003). Xorshift RNGs. http://www.jstatsoft.org/v08/i14/xorshift.pdf -@return a random 32 bit integer. -@todo check timing of xorshift96(), rand() and other PRNG candidates. - */ - -unsigned long xorshift96() -{ //period 2^96-1 - uint32_t t; - - x ^= x << 16; - x ^= x >> 5; - x ^= x << 1; - - t = x; - x = y; - y = z; - z = t ^ x ^ y; - - return z; -} - - -/** @ingroup random -Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used -in Mozzi's rand() function. This can be useful if you want random sequences to -be different on each run of a sketch, by seeding with fairly random input, such -as analogRead() on an unconnected pin (as explained in the Arduino documentation -for randomSeed(). randSeed is the same as xorshift96Seed(), but easier to -remember. -@param seed a number to use as a seed. -*/ -void randSeed(unsigned long seed) -{ - x=seed; -} - -// To be defined in hardware implementations -void autoRandomSeeds(uint32_t *x, uint32_t *y, uint32_t *z); - -/** @ingroup random -Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used -in Mozzi's rand() function. This can be useful if you want random sequences to -be different on each run of a sketch, by seeding with a fairly random input. -randSeed() called without a parameter uses noise from reading the Arduino's -internal temperature as the seed, a technique discussed at -http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there -by Rob Tillaart. - -@note Intialization of the random seed is done differently on different MCUs, - but is nowhere near perfect for most (and for some it is not even implemented at all). - Many implementations (e.g. on AVR, STM32) simply rely on reading a (hopefully noisy) - internal temperature sensor. - You will often get better results by calling analogRead() - @em not mozziAnalogRead(0), in this case! - - on one or two floating (non-connected) analog pins. -*/ -void randSeed() { - autoRandomSeeds(&x, &y, &z); -} - -/** @ingroup random -Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number. -@param seed a number to use as a seed. -*/ -void xorshiftSeed(unsigned long seed) -{ - x=seed; -} - - - -/** @ingroup random -Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param minval the minimum signed byte value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. -@param maxval the maximum signed byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random signed byte between minval and maxval-1 inclusive. -*/ -int8_t rand(int8_t minval, int8_t maxval) -{ - return (int8_t) ((((int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval; -} - - -/** @ingroup random -Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param minval the minimum unsigned byte value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. -@param maxval the maximum unsigned byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random unsigned byte between minval and maxval-1 inclusive. -*/ -uint8_t rand(uint8_t minval, uint8_t maxval) -{ - return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval; -} - - -/** @ingroup random -Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param minval the minimum signed int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. -@param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random int between minval and maxval-1 inclusive. -*/ -int rand( int minval, int maxval) -{ - return (int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); -} - - -/** @ingroup random -Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param minval the minimum unsigned int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. -@param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random unsigned int between minval and maxval-1 inclusive. -*/ -unsigned int rand(unsigned int minval, unsigned int maxval) -{ - return (unsigned int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); -} - - -/** @ingroup random -Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param maxval the maximum signed byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random signed byte between 0 and maxval-1 inclusive. -*/ -int8_t rand(int8_t maxval) -{ - return (int8_t) ((((int) (lowByte(xorshift96()))) * maxval)>>8); -} - - -/** @ingroup random -Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param maxval the maximum unsigned byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random unsigned byte between 0 and maxval-1 inclusive. -*/ -uint8_t rand(uint8_t maxval) -{ - return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * maxval)>>8); -} - - -/** @ingroup random -Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random int between 0 and maxval-1 inclusive. -*/ -int rand(int maxval) -{ - return (int) (((xorshift96() & 0xFFFF) * maxval)>>16); -} - - -/** @ingroup random -Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random unsigned int between 0 and maxval-1 inclusive. -*/ -unsigned int rand(unsigned int maxval) -{ - return (unsigned int) (((xorshift96() & 0xFFFF) * maxval)>>16); -} - - -/** @ingroup random -Generates a random number in the range for midi notes. -@return a random value between 0 and 127 inclusive -*/ -uint8_t randMidiNote() -{ - return lowByte(xorshift96())>>1; -} diff --git a/mozzi_rand.h b/mozzi_rand.h index ac75db24f..4e96fb94f 100644 --- a/mozzi_rand.h +++ b/mozzi_rand.h @@ -1,31 +1,151 @@ #ifndef MOZZI_RAND_H_ #define MOZZI_RAND_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include +#include "internal/mozzi_rand_p.h" +/** @ingroup random +Random number generator. A faster replacement for Arduino's random function, +which is too slow to use with Mozzi. +Based on Marsaglia, George. (2003). Xorshift RNGs. http://www.jstatsoft.org/v08/i14/xorshift.pdf +@return a random 32 bit integer. +@todo check timing of xorshift96(), rand() and other PRNG candidates. + */ +inline uint32_t xorshift96() { return MozziRandPrivate::xorshift96(); }; -unsigned long xorshift96(); +/** @ingroup random +Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used +in Mozzi's rand() function. This can be useful if you want random sequences to +be different on each run of a sketch, by seeding with fairly random input, such +as analogRead() on an unconnected pin (as explained in the Arduino documentation +for randomSeed(). randSeed is the same as xorshift96Seed(), but easier to +remember. +@param seed a number to use as a seed. +*/ +inline void randSeed(uint32_t seed) { + MozziRandPrivate::x=seed; +} -void xorshiftSeed(unsigned long seed); -void randSeed(unsigned long seed); -void randSeed(); +/** @ingroup random +Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used +in Mozzi's rand() function. This can be useful if you want random sequences to +be different on each run of a sketch, by seeding with a fairly random input. +randSeed() called without a parameter uses noise from reading the Arduino's +internal temperature as the seed, a technique discussed at +http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there +by Rob Tillaart. -int8_t rand(int8_t minval, int8_t maxval); -int8_t rand(int8_t maxval); +@note Intialization of the random seed is done differently on different MCUs, + but is nowhere near perfect for most (and for some it is not even implemented at all). + Many implementations (e.g. on AVR, STM32) simply rely on reading a (hopefully noisy) + internal temperature sensor. + You will often get better results by calling analogRead() - @em not mozziAnalogRead(0), in this case! - + on one or two floating (non-connected) analog pins. +*/ +inline void randSeed() { MozziRandPrivate::autoSeed(); }; -uint8_t rand(uint8_t minval, uint8_t maxval); -uint8_t rand(uint8_t maxval); +/** @ingroup random +Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number. +@param seed a number to use as a seed. +// TODO: duplicate deprecate / remove +*/ +inline void xorshiftSeed(uint32_t seed) { randSeed(seed); }; -int rand(int minval, int maxval); -int rand(int maxval); +/** @ingroup random +Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. +@param minval the minimum signed byte value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. +@param maxval the maximum signed byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random signed byte between minval and maxval-1 inclusive. +*/ +inline int8_t rand(int8_t minval, int8_t maxval) +{ + return (int8_t) ((((int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval; +} -unsigned int rand(unsigned int minval, unsigned int maxval); -unsigned int rand(unsigned int maxval); +/** @ingroup random +Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. +@param maxval the maximum signed byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random signed byte between 0 and maxval-1 inclusive. +*/ +inline int8_t rand(int8_t maxval) +{ + return (int8_t) ((((int) (lowByte(xorshift96()))) * maxval)>>8); +} -uint8_t randMidiNote(); +/** @ingroup random +Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. +@param minval the minimum unsigned byte value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. +@param maxval the maximum unsigned byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random unsigned byte between minval and maxval-1 inclusive. +*/ +inline uint8_t rand(uint8_t minval, uint8_t maxval) +{ + return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval; +} + +/** @ingroup random +Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. +@param maxval the maximum unsigned byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random unsigned byte between 0 and maxval-1 inclusive. +*/ +inline uint8_t rand(uint8_t maxval) +{ + return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * maxval)>>8); +} + +/** @ingroup random +Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. +@param minval the minimum signed int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. +@param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random int between minval and maxval-1 inclusive. +*/ +inline int16_t rand(int16_t minval, int16_t maxval) +{ + return (int16_t) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); +} + + +/** @ingroup random +Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. +@param minval the minimum unsigned int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. +@param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random unsigned int between minval and maxval-1 inclusive. +*/ +inline uint16_t rand(uint16_t minval, uint16_t maxval) +{ + return (uint16_t) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); +} + + +/** @ingroup random +Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. +@param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random int between 0 and maxval-1 inclusive. +*/ +inline int16_t rand(int16_t maxval) +{ + return (int16_t) (((xorshift96() & 0xFFFF) * maxval)>>16); +} + + +/** @ingroup random +Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. +@param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random unsigned int between 0 and maxval-1 inclusive. +*/ +inline uint16_t rand(uint16_t maxval) +{ + return (uint16_t) (((xorshift96() & 0xFFFF) * maxval)>>16); +} + + +/** @ingroup random +Generates a random number in the range for midi notes. +@return a random value between 0 and 127 inclusive +*/ +inline uint8_t randMidiNote() +{ + return lowByte(xorshift96())>>1; +} #endif /* MOZZI_RAND_H_ */ From 1856897cc5514b167b5e07b3f07b5688bad9e1b1 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 4 Jan 2024 15:37:26 +0100 Subject: [PATCH 072/215] Restore the plain "int" overloads to rand(). When int is not an alias to intXY_t, compilers may be too stubborn to understand, which overload to use. Conversely, having both an int16_t and and int overload is not possible on AVR (where the two _are_ an alias). --- mozzi_rand.h | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/mozzi_rand.h b/mozzi_rand.h index 4e96fb94f..b293c5b46 100644 --- a/mozzi_rand.h +++ b/mozzi_rand.h @@ -98,47 +98,49 @@ Ranged random number generator, faster than Arduino's built-in random function, @param minval the minimum signed int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. @param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. @return a random int between minval and maxval-1 inclusive. + +@note The returned value is always in the 16 bit range, even on platforms where int is wider. If you need 32 bits, call xorshift96(), directly. */ -inline int16_t rand(int16_t minval, int16_t maxval) +inline int rand(int minval, int maxval) { - return (int16_t) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); + return (int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); } - /** @ingroup random Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param minval the minimum unsigned int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. -@param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random unsigned int between minval and maxval-1 inclusive. +@param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random int between 0 and maxval-1 inclusive. + +@note The returned value is always in the 16 bit range, even on platforms where int is wider. If you need 32 bits, call xorshift96(), directly. */ -inline uint16_t rand(uint16_t minval, uint16_t maxval) +inline int rand(int maxval) { - return (uint16_t) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); + return (int) (((xorshift96() & 0xFFFF) * maxval)>>16); } - /** @ingroup random Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. -@param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. -@return a random int between 0 and maxval-1 inclusive. +@param minval the minimum unsigned int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function. +@param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. +@return a random unsigned int between minval and maxval-1 inclusive. */ -inline int16_t rand(int16_t maxval) +inline unsigned int rand(unsigned int minval, unsigned int maxval) { - return (int16_t) (((xorshift96() & 0xFFFF) * maxval)>>16); + return (unsigned int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); } - /** @ingroup random Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. @param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function. @return a random unsigned int between 0 and maxval-1 inclusive. + +@note The returned value is always in the 16 bit range, even on platforms where int is wider. If you need 32 bits, call xorshift96(), directly. */ -inline uint16_t rand(uint16_t maxval) +inline unsigned int rand(unsigned int maxval) { - return (uint16_t) (((xorshift96() & 0xFFFF) * maxval)>>16); + return (unsigned int) (((xorshift96() & 0xFFFF) * maxval)>>16); } - /** @ingroup random Generates a random number in the range for midi notes. @return a random value between 0 and 127 inclusive From 51ae09a918a81009a38d47996a79cc179dc77bd3 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 4 Jan 2024 22:24:41 +0100 Subject: [PATCH 073/215] MozziGuts implementation is now included from MozziGuts.h (most important step for single compilation unit) This required introduction of a private namespace, so that internals do not leak out and clash with user code. That, in turn, meant changes all over the place. --- MozziGuts.h | 14 ++---- MozziGuts.cpp => MozziGuts.hpp | 23 +++++++++- MozziGuts_impl_AVR.hpp | 45 ++++++++++++++----- MozziGuts_impl_ESP32.hpp | 11 ++++- MozziGuts_impl_ESP8266.hpp | 13 +++++- MozziGuts_impl_MBED.hpp | 12 +++++ MozziGuts_impl_RENESAS.hpp | 9 ++++ MozziGuts_impl_RENESAS_ADC.hpp | 3 ++ MozziGuts_impl_RENESAS_analog.hpp | 5 ++- MozziGuts_impl_RP2040.hpp | 15 ++++++- MozziGuts_impl_SAMD.hpp | 11 ++++- MozziGuts_impl_STM32.hpp | 7 +++ MozziGuts_impl_STM32duino.hpp | 5 +++ MozziGuts_impl_STM32duino_analog.hpp | 3 ++ MozziGuts_impl_TEENSY.hpp | 13 +++++- MozziGuts_impl_template.hpp | 15 ++++++- Readme_Mozzi_2_0.md | 4 +- .../Skeleton_Multi/Skeleton_Multi_Unit2.cpp | 6 ++- internal/mozzi_rand_p.h | 13 ++++-- mozzi_analog.h | 42 ++--------------- mozzi_rand.h | 8 ++-- 21 files changed, 195 insertions(+), 82 deletions(-) rename MozziGuts.cpp => MozziGuts.hpp (89%) diff --git a/MozziGuts.h b/MozziGuts.h index 0056c51ca..83ca6c35c 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -12,13 +12,7 @@ #ifndef MOZZIGUTS_H_ #define MOZZIGUTS_H_ -//#define F_CPU 8000000 // testing - -#if ARDUINO >= 100 #include "Arduino.h" -#else - #include "WProgram.h" -#endif #include "hardware_defines.h" #include "mozzi_config.h" @@ -33,10 +27,6 @@ #include "internal/config_checks_generic.h" -#if (STEREO_HACK == true) -extern int audio_out_1, audio_out_2; -#endif - #include "AudioOutput.h" // TODO Mozzi 2.0: These typedef probably obsolete? @@ -183,4 +173,8 @@ is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when */ unsigned long mozziMicros(); +#ifndef MOZZI_HEADER_ONLY +#include "MozziGuts.hpp" +#endif + #endif /* MOZZIGUTS_H_ */ diff --git a/MozziGuts.cpp b/MozziGuts.hpp similarity index 89% rename from MozziGuts.cpp rename to MozziGuts.hpp index dae408bdd..550e534d6 100644 --- a/MozziGuts.cpp +++ b/MozziGuts.hpp @@ -17,6 +17,8 @@ #include "internal/mozzi_rand_p.h" #include "AudioOutput.h" +namespace MozziPrivate { + // Forward declarations of functions to be provided by platform specific implementations #if (!BYPASS_MOZZI_OUTPUT_BUFFER) static void CACHED_FUNCTION_ATTR defaultAudioOutput(); @@ -26,6 +28,7 @@ static void advanceADCStep(); // to be provided by platfor static void startSecondADCReadOnCurrentChannel(); // to be provided by platform implementation static uint8_t adc_count = 0; // needed below #endif +} // Include the appropriate implementation #if IS_AVR() @@ -63,6 +66,7 @@ static uint8_t adc_count = 0; // needed below # endif #endif +namespace MozziPrivate { ////// BEGIN Output buffering ///// #if BYPASS_MOZZI_OUTPUT_BUFFER == true uint64_t samples_written_to_buffer = 0; @@ -266,7 +270,7 @@ unsigned long mozziMicros() { return audioTicks() * MICROS_PER_AUDIO_TICK; } ////// BEGIN initialization /////// void startMozzi(int control_rate_hz) { #if !MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) - setupMozziADC(); // you can use setupFastAnalogRead() with FASTER_ADC or FASTEST_ADC + MozziPrivate::setupMozziADC(FAST_ADC); // you can use setupFastAnalogRead() with FASTER_ADC or FASTEST_ADC // in setup() if desired (not for Teensy 3.* ) #endif // delay(200); // so AutoRange doesn't read 0 to start with @@ -279,6 +283,7 @@ uint32_t MozziRandPrivate::y=362436069; uint32_t MozziRandPrivate::z=521288629; ////// END initialization /////// +} // reduce Macro leakage #undef LOOP_YIELD @@ -286,3 +291,19 @@ uint32_t MozziRandPrivate::z=521288629; #undef AUDIO_HOOK_HOOK #undef AUDIOTICK_ADJUSTMENT #undef MOZZI__LEGACY_AUDIO_INPUT_IMPL + +// "export" publically accessible functions defined in this file +unsigned long mozziMicros() { return MozziPrivate::mozziMicros(); }; +unsigned long audioTicks() { return MozziPrivate::audioTicks(); }; +void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); }; +void stopMozzi() { MozziPrivate::stopMozzi(); }; +int mozziAnalogRead(uint8_t pin) { return MozziPrivate::mozziAnalogRead(pin); }; +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) +AudioOutputStorage_t getAudioInput() { return MozziPrivate::getAudioInput(); }; +#endif +#if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) +void setupMozziADC(int8_t speed) { MozziPrivate::setupMozziADC(speed); }; +void setupFastAnalogRead(int8_t speed) { MozziPrivate::setupFastAnalogRead(speed); }; +uint8_t adcPinToChannelNum(uint8_t pin) { return MozziPrivate::adcPinToChannelNum(pin); }; +#endif +void audioHook() { MozziPrivate::audioHook(); }; diff --git a/MozziGuts_impl_AVR.hpp b/MozziGuts_impl_AVR.hpp index 30e053ea7..3053cb559 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/MozziGuts_impl_AVR.hpp @@ -10,8 +10,8 @@ * */ -#include "FrequencyTimer2.h" -#include "TimerOne.h" +#include "utility/FrequencyTimer2.h" +#include "utility/TimerOne.h" #if (F_CPU != 16000000) #warning \ @@ -22,6 +22,12 @@ #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) extern uint8_t analog_reference; +ISR(ADC_vect, ISR_BLOCK) +{ + MozziPrivate::advanceADCStep(); +} + +namespace MozziPrivate { #define getADCReading() ADC /* officially (ADCL | (ADCH << 8)) but the compiler works it out */ #define channelNumToIndex(channel) channel uint8_t adcPinToChannelNum(uint8_t pin) { @@ -29,7 +35,15 @@ uint8_t adcPinToChannelNum(uint8_t pin) { if (pin >= 54) pin -= 54; // allow for channel or pin numbers #elif defined(__AVR_ATmega32U4__) if (pin >= 18) pin -= 18; // allow for channel or pin numbers - pin = analogPinToChannel(pin); // moved from extra #if which was below in Arduino code, and redefined in mozzi_analog.h, with notes +# if defined(CORE_TEENSY) // special handling for Teensy2, which does not (did not?) have an analogPinToChannel() define (see https://github.com/sensorium/Mozzi/issues/10) + static const uint8_t PROGMEM adc_mapping[] = { + // 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8 + 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8, 10, 11, 12, 13, 7, 6, 5, 4, 1, 0, 8 + }; + pin = pgm_read_byte(adc_mapping + (P)); +# else + pin = analogPinToChannel(pin); +# endif #elif defined(__AVR_ATmega1284__) if (pin >= 24) pin -= 24; // allow for channel or pin numbers #else @@ -74,11 +88,6 @@ void adcEnableInterrupt(){ } */ -ISR(ADC_vect, ISR_BLOCK) -{ - advanceADCStep(); -} - void setupMozziADC(int8_t speed) { ADCSRA |= (1 << ADIE); // adc Enable Interrupt adcDisconnectAllDigitalIns(); @@ -100,13 +109,14 @@ void setupFastAnalogRead(int8_t speed) { ADCSRA &= ~(1 << ADPS0); } } +} #endif ////// END analog input code //////// - +namespace MozziPrivate { //// BEGIN AUDIO OUTPUT code /////// /* ATmega328 technical manual, Section 12.7.4: @@ -181,9 +191,13 @@ static void startAudio() { // Timer1.attachInterrupt()) } +} // namespace MozziPrivate + ISR(TIMER1_OVF_vect, ISR_BLOCK) { defaultAudioOutput(); } + +namespace MozziPrivate { #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) inline void audioOutput(const AudioOutput f) { @@ -221,9 +235,10 @@ static void startAudio() { // Timer1.attachInterrupt()) } +} // namespace MozziPrivate + /* Interrupt service routine moves sound data from the output buffer to the Arduino output register, running at AUDIO_RATE. */ - ISR(TIMER1_OVF_vect, ISR_BLOCK) { # if (MOZZI_AUDIO_RATE < MOZZI_PWM_RATE) // only update every second ISR, if lower audio rate static_assert(2l*MOZZI_AUDIO_RATE == MOZZI_PWM_RATE, "audio rate must the same, or exactly half of the pwm rate!"); @@ -232,9 +247,10 @@ ISR(TIMER1_OVF_vect, ISR_BLOCK) { if (alternate) return; # endif - defaultAudioOutput(); + MozziPrivate::defaultAudioOutput(); } +namespace MozziPrivate { #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) inline void audioOutput(const AudioOutput f) { // read about dual pwm at @@ -314,6 +330,8 @@ static void setupTimer2() { FrequencyTimer2::enable(); } +} // namespace MozziPrivate + #if defined(TIMER2_COMPA_vect) ISR(TIMER2_COMPA_vect) #elif defined(TIMER2_COMP_vect) @@ -326,11 +344,13 @@ ISR(TIMER4_COMPA_vect) void dummy_function(void) #endif { - defaultAudioOutput(); + MozziPrivate::defaultAudioOutput(); } // end of HIFI +namespace MozziPrivate { + #endif //----------------------------------------------------------------------------------------------------------------- @@ -423,3 +443,4 @@ void MozziRandPrivate::autoSeed() { } //// END Random seeding //////// +} diff --git a/MozziGuts_impl_ESP32.hpp b/MozziGuts_impl_ESP32.hpp index 3a2196146..32d8535c2 100644 --- a/MozziGuts_impl_ESP32.hpp +++ b/MozziGuts_impl_ESP32.hpp @@ -14,6 +14,7 @@ # error "Wrong implementation included for this platform" #endif +namespace MozziPrivate { ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) #error not yet implemented @@ -36,11 +37,11 @@ void setupFastAnalogRead(int8_t speed) { ////// END analog input code //////// - - //// BEGIN AUDIO OUTPUT code /////// #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) +} // namespace MozziPrivate # include // for I2S-based output modes, including - technically - internal DAC +namespace MozziPrivate { const i2s_port_t i2s_num = MOZZI_I2S_PORT; // On ESP32 we cannot test wether the DMA buffer has room. Instead, we have to use a one-sample mini buffer. In each iteration we @@ -93,7 +94,11 @@ inline void audioOutput(const AudioOutput f) { #endif #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) + +} // namespace MozziPrivate # include +namespace MozziPrivate { + void CACHED_FUNCTION_ATTR timer0_audio_output_isr(void *) { TIMERG0.int_clr_timers.t0 = 1; TIMERG0.hw_timer[0].config.alarm_en = 1; @@ -170,3 +175,5 @@ void MozziRandPrivate::autoSeed() { //// END Random seeding //////// #undef ESP_SAMPLE_SIZE // only used inside this file + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_ESP8266.hpp b/MozziGuts_impl_ESP8266.hpp index 10d321642..da95b723f 100644 --- a/MozziGuts_impl_ESP8266.hpp +++ b/MozziGuts_impl_ESP8266.hpp @@ -14,6 +14,8 @@ # error "Wrong implementation included for this platform" #endif +namespace MozziPrivate { + ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) #error not yet implemented @@ -34,19 +36,21 @@ void setupFastAnalogRead(int8_t speed) { #endif ////// END analog input code //////// - - //// BEGIN AUDIO OUTPUT code /////// #define LOOP_YIELD yield(); +} // namespace MozziPrivate #include #include +namespace MozziPrivate { uint16_t output_buffer_size = 0; #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC) // i.e. not external # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) +} // namespace MozziPrivate # include +namespace MozziPrivate { inline bool canBufferAudioOutput() { return (i2s_available() >= MOZZI_PDM_RESOLUTION); } @@ -56,7 +60,9 @@ inline void audioOutput(const AudioOutput f) { } } # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) +} // namespace MozziPrivate # include +namespace MozziPrivate { inline bool canBufferAudioOutput() { return (i2s_available() >= MOZZI_PDM_RESOLUTION); } @@ -138,7 +144,9 @@ void stopMozzi() { //// END AUDIO OUTPUT code /////// //// BEGIN Random seeding //////// +} //namespace MozziPrivate #include +namespace MozziPrivate { void MozziRandPrivate::autoSeed() { x = RANDOM_REG32; // TODO: The XORs may not be needed, but for lack of documentation (that I could find), let's assume RANDOM_REG32 @@ -147,3 +155,4 @@ void MozziRandPrivate::autoSeed() { z = z ^ RANDOM_REG32; } //// END Random seeding //////// +} // namespace MozziPrivate diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index 8babb2972..81ce30ad8 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -16,12 +16,16 @@ #define CHUNKSIZE 64 +namespace MozziPrivate { + ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_STANDARD) #define MOZZI__LEGACY_AUDIO_INPUT_IMPL 0 +} // namespace MozziPrivate #include +namespace MozziPrivate { AdvancedADC adc(MOZZI_AUDIO_INPUT_PIN); Sample inbuf[CHUNKSIZE]; @@ -107,7 +111,9 @@ void setupMozziADC(int8_t speed) { #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) #define US_PER_AUDIO_TICK (1000000L / MOZZI_AUDIO_RATE) +} // namespace MozziPrivate #include +namespace MozziPrivate { mbed::Ticker audio_output_timer; volatile bool audio_output_requested = false; @@ -128,7 +134,9 @@ void stopMozzi() { #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) +} // namespace MozziPrivate #include +namespace MozziPrivate { AdvancedDAC dac1(MOZZI_AUDIO_PIN_1); Sample buf1[CHUNKSIZE]; @@ -192,7 +200,9 @@ void stopMozzi() { #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL) +} // namespace MozziPrivate #include +namespace MozziPrivate { mbed::BufferedSerial serial_out1(digitalPinToPinName(MOZZI_SERIAL_PIN_TX), digitalPinToPinName(MOZZI_SERIAL_PIN_RX)); uint8_t buf[MOZZI_PDM_RESOLUTION*4]; @@ -227,5 +237,7 @@ void MozziRandPrivate::autoSeed() { } //// END Random seeding //////// +} // namespace MozziPrivate + #undef CHUNKSIZE #undef US_PER_AUDIO_TICK diff --git a/MozziGuts_impl_RENESAS.hpp b/MozziGuts_impl_RENESAS.hpp index 71f4dc2c6..0b80241d9 100644 --- a/MozziGuts_impl_RENESAS.hpp +++ b/MozziGuts_impl_RENESAS.hpp @@ -16,6 +16,7 @@ #include +namespace MozziPrivate { ////// BEGIN analog input code //////// @@ -31,8 +32,12 @@ void adc_callback(adc_callback_args_t *p_args) { advanceADCStep(); } +} // namespace MozziPrivate + #include "MozziGuts_impl_RENESAS_ADC.hpp" +namespace MozziPrivate { + #define getADCReading() readADC(r4_pin) uint8_t adcPinToChannelNum(uint8_t pin) { @@ -83,7 +88,9 @@ FspTimer timer; #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) CircularBuffer output_buffer; +} // namespace MozziPrivate #include "MozziGuts_impl_RENESAS_analog.hpp" +namespace MozziPrivate { #endif @@ -174,3 +181,5 @@ void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_RENESAS_ADC.hpp b/MozziGuts_impl_RENESAS_ADC.hpp index 079486e67..9b7afa97e 100644 --- a/MozziGuts_impl_RENESAS_ADC.hpp +++ b/MozziGuts_impl_RENESAS_ADC.hpp @@ -8,6 +8,7 @@ It contains functions to interact with the ADC in order to implement async ADC r //#include #include +namespace MozziPrivate { /** VERBATIM from Arduino's analog.cpp */ @@ -119,3 +120,5 @@ uint16_t readADC(int pin) R_ADC_Read(&(_adc->ctrl), (adc_channel_t)GET_CHANNEL(cfg_adc), &result); return result; } + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_RENESAS_analog.hpp b/MozziGuts_impl_RENESAS_analog.hpp index 2496cbfe8..80caffdd6 100644 --- a/MozziGuts_impl_RENESAS_analog.hpp +++ b/MozziGuts_impl_RENESAS_analog.hpp @@ -4,11 +4,13 @@ for Renesas board from Arduino. It contains functions to create and start the on-board DAC (and associate timer). */ -FspTimer timer_dac; #include #include #include +namespace MozziPrivate { + +FspTimer timer_dac; volatile uint32_t pin; uint8_t dac_bits; @@ -86,3 +88,4 @@ void dac_init() { } } +} diff --git a/MozziGuts_impl_RP2040.hpp b/MozziGuts_impl_RP2040.hpp index 51556ad0f..3a2cf6df4 100644 --- a/MozziGuts_impl_RP2040.hpp +++ b/MozziGuts_impl_RP2040.hpp @@ -17,6 +17,8 @@ #include +namespace MozziPrivate { + ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) @@ -28,8 +30,12 @@ * We'll abuse that to connect a callback to the DMA channel, instead. */ +} // namespace MozziPrivate + #include +namespace MozziPrivate { + #define getADCReading() rp2040_adc_result #define channelNumToIndex(channel) channel @@ -69,7 +75,7 @@ void rp2040_adc_queue_handler(); static uint16_t rp2040_adc_result = 0; int rp2040_adc_dma_chan; void setupMozziADC(int8_t speed) { - for (int i = 0; i < NUM_ANALOG_INPUTS; ++i) { + for (int i = 0; i < (int) NUM_ANALOG_INPUTS; ++i) { adc_gpio_init(i); } @@ -116,6 +122,7 @@ void rp2040_adc_queue_handler() { dma_channel_set_trans_count(rp2040_adc_dma_chan, 1, true); // set up for another read advanceADCStep(); } + #endif // MOZZI_ANALOG_READ ////// END analog input code //////// @@ -137,7 +144,9 @@ inline void audioOutput(const AudioOutput f) { } # endif // MOZZI_OUTPUT_PWM +} // namespace MozziPrivate #include +namespace MozziPrivate { /** Implementation notes: * - For the time being this port uses a very crude approach to audio output: PWM updated by a hardware timer running at AUDIO_RATE * - Hardware timer isn't fixed, but rather we claim the first unclaimed one @@ -159,7 +168,9 @@ void audioOutputCallback(uint) { } #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) +} // namespace MozziPrivate #include +namespace MozziPrivate { I2S i2s(OUTPUT); inline bool canBufferAudioOutput() { @@ -272,5 +283,7 @@ void MozziRandPrivate::autoSeed() { } //// END Random seeding //////// +} // namespace MozziPrivate + #undef MOZZI_RP2040_BUFFERS #undef MOZZI_RP2040_BUFFER_SIZE diff --git a/MozziGuts_impl_SAMD.hpp b/MozziGuts_impl_SAMD.hpp index a975fae86..b801d77b4 100644 --- a/MozziGuts_impl_SAMD.hpp +++ b/MozziGuts_impl_SAMD.hpp @@ -14,6 +14,8 @@ # error "Wrong implementation included for this platform" #endif +namespace MozziPrivate { + ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, NOZZI_ANALOG_READ_STANDARD) #error not yet implemented @@ -93,18 +95,23 @@ static void tcConfigure(uint32_t sampleRate) { ; } +} // namespace MozziPrivate + void TC5_Handler(void) __attribute__((weak, alias("samd21AudioOutput"))); #ifdef __cplusplus extern "C" { #endif void samd21AudioOutput() { - defaultAudioOutput(); + MozziPrivate::defaultAudioOutput(); TC5->COUNT16.INTFLAG.bit.MC0 = 1; } #ifdef __cplusplus } #endif + +namespace MozziPrivate { + #endif // MOZZI_AUDIO_MODE #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) @@ -144,3 +151,5 @@ void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_STM32.hpp b/MozziGuts_impl_STM32.hpp index bc881d168..2542016f8 100644 --- a/MozziGuts_impl_STM32.hpp +++ b/MozziGuts_impl_STM32.hpp @@ -12,10 +12,15 @@ #include "HardwareTimer.h" +namespace MozziPrivate { + ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) +} // namespace MozziPrivate //#include // Disabled, here. See hardware_defines.h +namespace MozziPrivate { + STM32ADC adc(ADC1); uint8_t stm32_current_adc_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform #define getADCReading() adc.getData() @@ -159,3 +164,5 @@ void MozziRandPrivate::autoSeed() { z=z^conv.ci; } //// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_STM32duino.hpp b/MozziGuts_impl_STM32duino.hpp index 88d0e4be4..471921b85 100644 --- a/MozziGuts_impl_STM32duino.hpp +++ b/MozziGuts_impl_STM32duino.hpp @@ -12,6 +12,7 @@ #include "HardwareTimer.h" +namespace MozziPrivate { ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) @@ -36,7 +37,9 @@ int16_t previously_sampled_pin = -1; bool conversion_running = false; ADC_HandleTypeDef AdcHandle = {}; +} // namespace MozziPrivate #include "MozziGuts_impl_STM32duino_analog.hpp" +namespace MozziPrivate { void adcStartConversion(int8_t pin) { if (pin != previously_sampled_pin) { @@ -177,3 +180,5 @@ void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_STM32duino_analog.hpp b/MozziGuts_impl_STM32duino_analog.hpp index c1a852b2a..f6c986582 100644 --- a/MozziGuts_impl_STM32duino_analog.hpp +++ b/MozziGuts_impl_STM32duino_analog.hpp @@ -1,3 +1,4 @@ +namespace MozziPrivate { // NOTE: The contents of this file are copied mostly verbatim from Arduino_Core_STM32, (c) STMicroelectronics, BSD 3-clause license. static PinName g_current_pin = NC; @@ -310,3 +311,5 @@ bool adc_setup_read(PinName pin, uint32_t resolution) { return HAL_OK; } + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_TEENSY.hpp b/MozziGuts_impl_TEENSY.hpp index 81ce2cf6e..70373fb07 100644 --- a/MozziGuts_impl_TEENSY.hpp +++ b/MozziGuts_impl_TEENSY.hpp @@ -19,10 +19,13 @@ "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino and 48MHz on Teensy 3! Results may vary with other speeds." #endif +namespace MozziPrivate { ////// BEGIN analog input code //////// #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) // required from http://github.com/pedvide/ADC for Teensy 3.* +} //namespace MozziPrivate #include +namespace MozziPrivate { ADC *adc; // adc object uint8_t teensy_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform @@ -42,14 +45,16 @@ void setupFastAnalogRead(int8_t speed) { #endif } +} // namespace MozziPrivate void adc0_isr(void) { - advanceADCStep(); + MozziPrivate::advanceADCStep(); } +namespace MozziPrivate { void setupMozziADC(int8_t speed) { adc = new ADC(); - adc->adc0->enableInterrupts(adc0_isr); + adc->adc0->enableInterrupts(adc0_isr); // TODO: is this even correct? Does the function take a parameter? And is adc0_isr a predefined name, or are we free to move this to MozziPrivate? #ifdef ADC_DUAL_ADCS adc->adc1->enableInterrupts(adc0_isr); #endif @@ -75,7 +80,9 @@ static void startSecondADCReadOnCurrentChannel() { //// BEGIN AUDIO OUTPUT code /////// #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED) +} // namespace MozziPrivate #include "IntervalTimer.h" +namespace MozziPrivate { IntervalTimer timer1; #endif @@ -118,3 +125,5 @@ void MozziRandPrivate::autoSeed() { #warning Automatic random seedings is not implemented on this platform } //// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_template.hpp b/MozziGuts_impl_template.hpp index 565cb39ba..b997e3cd3 100644 --- a/MozziGuts_impl_template.hpp +++ b/MozziGuts_impl_template.hpp @@ -37,6 +37,17 @@ #endif // Add platform specific includes and declarations, here +//#include + +// In order to allow simple yet efficient user configuration, the entire contents of this file are compiled in the same translation unit +// as (the main file of) the user sketch. To avoid name clashes, we encapsulate everyghing in a namespace. +// For the most part, this namescape can just extend from the start of the file to the end (as shown, here), and you will not have to +// worry about it. However, there may be a few situations, where you have to "leave" the MozziPrivate namespace. This includes: +// - When you include a further (hardware-dependent library). Consider gathering all includes at the top of this file, instead. +// - When you provide definitions for special names, importantly for ISR-functions. If these would be placed in the namespace, the linker would not +// recognize them as the definition of the intended ISR-vector. See MozziGuts_impl_AVR.hpp for examples. + +namespace MozziPrivate { ////// BEGIN analog input code //////// @@ -165,6 +176,8 @@ void MozziRandPrivate::autoSeed() { // It *should* however ensure that rand() sequences will differ across reboots, after randSeed() has been called. // x, y, and z are already initialized to non-zero, when this function is called. // It's ok to leave this unimplemented, initially. -#warning Automatic random seedings is not implemented on this platform +#warning Automatic random seeding is not implemented on this platform } //// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index a4907f90a..1ae244089 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -31,8 +31,8 @@ general: Other removed stuff: - pauseMozzi() - was still declared but not defined -> not usable, anyway - unpauseMozzi() - was still declared but not defined -> not usable, anyway - - + - Teensy3/4: channel2sc1a -> thought to be unused, removed + - Teensy2: adc_mapping -> hidden away; use adcPinToChannelNum(), as on all other platforms, instead Documentation bits that still need to find a new home (many other bits were moved around, many, many duplicates merged into a common place, and seom obsoleted bits discarded): diff --git a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp index a661c8e32..00d33a879 100644 --- a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp @@ -1,4 +1,8 @@ -#include // This file, too, will have to include the Mozzi headers. +// This file, too, will have to include the Mozzi headers, but in order to avoid "multiple definition" errors, +// all secondary .cpp files in the sketch must set MOZZI_HEADER_ONLY before including any Mozzi headers. +// TODO: Maybe that is not even the final word, and this will be required in the end, but it seems a useful intermediate step +#define MOZZI_HEADER_ONLY +#include AudioOutput_t updateAudio() { return MonoOutput::from8Bit(0); // just a dummy diff --git a/internal/mozzi_rand_p.h b/internal/mozzi_rand_p.h index a056ebe51..02674bd36 100644 --- a/internal/mozzi_rand_p.h +++ b/internal/mozzi_rand_p.h @@ -1,10 +1,16 @@ #ifndef MOZZI_RAND_P_H #define MOZZI_RAND_P_H +namespace MozziPrivate { + class MozziRandPrivate { friend void randSeed(); friend void randSeed(uint32_t); friend uint32_t xorshift96(); + static uint32_t x; + static uint32_t y; + static uint32_t z; +public: static uint32_t xorshift96() { //period 2^96-1 uint32_t t; @@ -21,9 +27,10 @@ friend uint32_t xorshift96(); return z; } static void autoSeed(); // defined in hardware specific MozziGuts_impl-files - static uint32_t x; - static uint32_t y; - static uint32_t z; }; +inline void randSeed(uint32_t seed) { MozziRandPrivate::x = seed; }; + +} + #endif diff --git a/mozzi_analog.h b/mozzi_analog.h index df051776c..d0080c3d6 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -24,44 +24,6 @@ #warning "Using AUDIO_INPUT_PIN defined in mozzi_config.h for audio input." #endif -// hack for Teensy 2 (ATmega32U4), which has "adc_mapping" instead of "analog_pin_to_channel_PGM" -#if defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) -//pasted from hardware/arduino/variants/leonardo/pins_arduino.h, doesn't work as of mozzi 0.01.2a -// __AVR_ATmega32U4__ has an unusual mapping of pins to channels -//extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; -//#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) ) - -// look at Arduino.app/Contents/Resources/Java/hardware/teensy/cores/teensy/pins_teensy.c - analogRead -// adc_mapping is already declared in pins_teensy.c, but it's static there so we can't access it -static const uint8_t PROGMEM adc_mapping[] = { -// 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8 - 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8, 10, 11, 12, 13, 7, 6, 5, 4, 1, 0, 8 -}; -#define analogPinToChannel(P) ( pgm_read_byte( adc_mapping + (P) ) ) -#endif - - -// include this although already in teensy 3 analog.c, because it is static there -#if defined(__MK20DX128__) -static const uint8_t channel2sc1a[] = { - 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, - 0, 19, 3, 21, 26, 22, 23 -}; -#elif defined(__MK20DX256__) -static const uint8_t channel2sc1a[] = { - 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, - 0, 19, 3, 19+128, 26, 18+128, 23, - 5+192, 5+128, 4+128, 6+128, 7+128, 4+192 -// A15 26 E1 ADC1_SE5a 5+64 -// A16 27 C9 ADC1_SE5b 5 -// A17 28 C8 ADC1_SE4b 4 -// A18 29 C10 ADC1_SE6b 6 -// A19 30 C11 ADC1_SE7b 7 -// A20 31 E0 ADC1_SE4a 4+64 -}; -#endif - - // for setupFastAnalogRead() enum ANALOG_READ_SPEED {FAST_ADC,FASTER_ADC,FASTEST_ADC}; @@ -124,6 +86,8 @@ Digital Input Disable bits. inline void disconnectDigitalIn(uint8_t channel_num) { #if IS_AVR() DIDR0 |= 1< Date: Fri, 5 Jan 2024 11:09:30 +0100 Subject: [PATCH 074/215] Add - yet unused - macros for deprecation --- MozziGuts.hpp | 7 +++++-- MozziGuts_impl_MBED.hpp | 2 +- MozziGuts_impl_RENESAS.hpp | 2 +- MozziGuts_impl_RP2040.hpp | 2 +- MozziGuts_impl_SAMD.hpp | 2 +- MozziGuts_impl_STM32duino.hpp | 2 +- MozziGuts_impl_TEENSY.hpp | 2 +- internal/mozzi_macros.h | 32 ++++++++++++++++++++++++++++---- 8 files changed, 39 insertions(+), 12 deletions(-) diff --git a/MozziGuts.hpp b/MozziGuts.hpp index 550e534d6..852922bcb 100644 --- a/MozziGuts.hpp +++ b/MozziGuts.hpp @@ -292,8 +292,11 @@ uint32_t MozziRandPrivate::z=521288629; #undef AUDIOTICK_ADJUSTMENT #undef MOZZI__LEGACY_AUDIO_INPUT_IMPL -// "export" publically accessible functions defined in this file -unsigned long mozziMicros() { return MozziPrivate::mozziMicros(); }; +// "export" publicly accessible functions defined in this file +// NOTE: unfortunately, we cannot just write using MozziPrivate::mozziMicros(), and that will conflict with, rather than define mozziMicros() +// we might want to rethink how this is done. What matters is that these functions are user accessible, though, while most of what we +// now keep in MozziPrivate is hidden away. +//unsigned long mozziMicros() { return MozziPrivate::mozziMicros(); }; unsigned long audioTicks() { return MozziPrivate::audioTicks(); }; void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); }; void stopMozzi() { MozziPrivate::stopMozzi(); }; diff --git a/MozziGuts_impl_MBED.hpp b/MozziGuts_impl_MBED.hpp index 81ce30ad8..6f7d064e3 100644 --- a/MozziGuts_impl_MBED.hpp +++ b/MozziGuts_impl_MBED.hpp @@ -233,7 +233,7 @@ void stopMozzi() { //// BEGIN Random seeding //////// void MozziRandPrivate::autoSeed() { -#warning Automatic random seedings is not implemented on this platform +#warning Automatic random seeding is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_RENESAS.hpp b/MozziGuts_impl_RENESAS.hpp index 0b80241d9..4ad924c50 100644 --- a/MozziGuts_impl_RENESAS.hpp +++ b/MozziGuts_impl_RENESAS.hpp @@ -178,7 +178,7 @@ void stopMozzi() { //// BEGIN Random seeding //////// void MozziRandPrivate::autoSeed() { -#warning Automatic random seedings is not implemented on this platform +#warning Automatic random seeding is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_RP2040.hpp b/MozziGuts_impl_RP2040.hpp index 3a2cf6df4..94a9d52e4 100644 --- a/MozziGuts_impl_RP2040.hpp +++ b/MozziGuts_impl_RP2040.hpp @@ -279,7 +279,7 @@ void stopMozzi() { //// BEGIN Random seeding //////// void MozziRandPrivate::autoSeed() { -#warning Automatic random seedings is not implemented on this platform +#warning Automatic random seeding is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_SAMD.hpp b/MozziGuts_impl_SAMD.hpp index b801d77b4..37bfdb658 100644 --- a/MozziGuts_impl_SAMD.hpp +++ b/MozziGuts_impl_SAMD.hpp @@ -148,7 +148,7 @@ void stopMozzi() { //// BEGIN Random seeding //////// void MozziRandPrivate::autoSeed() { -#warning Automatic random seedings is not implemented on this platform +#warning Automatic random seeding is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_STM32duino.hpp b/MozziGuts_impl_STM32duino.hpp index 471921b85..90452ae21 100644 --- a/MozziGuts_impl_STM32duino.hpp +++ b/MozziGuts_impl_STM32duino.hpp @@ -177,7 +177,7 @@ void stopMozzi() { //// BEGIN Random seeding //////// void MozziRandPrivate::autoSeed() { -#warning Automatic random seedings is not implemented on this platform +#warning Automatic random seeding is not implemented on this platform } //// END Random seeding //////// diff --git a/MozziGuts_impl_TEENSY.hpp b/MozziGuts_impl_TEENSY.hpp index 70373fb07..ddb8daf25 100644 --- a/MozziGuts_impl_TEENSY.hpp +++ b/MozziGuts_impl_TEENSY.hpp @@ -122,7 +122,7 @@ void stopMozzi() { //// BEGIN Random seeding //////// void MozziRandPrivate::autoSeed() { -#warning Automatic random seedings is not implemented on this platform +#warning Automatic random seeding is not implemented on this platform } //// END Random seeding //////// diff --git a/internal/mozzi_macros.h b/internal/mozzi_macros.h index cbd021d97..51c2af075 100644 --- a/internal/mozzi_macros.h +++ b/internal/mozzi_macros.h @@ -27,12 +27,15 @@ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE)) -/** Compile time check to complain if the given argument is not a power of two */ +/** @file mozzi_internal_macros + * Compile time check to complain if the given argument is not a power of two */ #define MOZZI_CHECK_POW2(X) static_assert((X & (X - 1)) == 0, #X " must be a power of two"); #define MOZZI__IS(X, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, ...) \ ((X == A0) || (X == A1) || (X == A2) || (X == A3) || (X == A4) || (X == A5) || (X == A6) || (X == A7) || (X == A8) || (X == A9) || (X == B0) || (X == B1) || (X == B2) || (X == B3) || (X == B4) || (X == B5) || (X == B6) || (X == B7) || (X == B8) || (X == B9)) -/** Short-hand to check if given first value is any of the following values (up to 20). + +/** @file mozzi_internal_macros + * Short-hand to check if given first value is any of the following values (up to 20). * * (Orgignally, this macro was intended to also produce an error, should any of the values be non-defined (such as because it's a typo), but alas, the preprocessor would * let me have that). @@ -51,7 +54,8 @@ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, \ MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE, MOZZI__INVALID_CONFIG_VALUE)) -/** Short-hand for a compile time complaint, if the given define does not have the expected value. +/** @file mozzi_internal_macros + * Short-hand for a compile time complaint, if the given define does not have the expected value. * * Use this to check - and clarify - complex nested logic inside #fidefs. * @@ -66,7 +70,27 @@ */ #define MOZZI_ASSERT_EQUAL(X, Y) static_assert(X == Y, "Internal error in preprocessor logic: " #X " != " #Y "."); -/** See MOZZI_ASSERT_EQUAL, but reversed */ +/** @file mozzi_internal_macros + * See MOZZI_ASSERT_EQUAL, but reversed */ #define MOZZI_ASSERT_NOTEQUAL(X, Y) static_assert(X != Y, "Internal error in preprocessor logic: " #X " == " #Y "."); + +#if __cplusplus >= 201402L +/** @file mozzi_internal_macros + * Document that a function has been deprecated, and when, if possible giving the user an explanatory message */ +#define MOZZI_DEPRECATED(WHEN, WHY) [[deprecated(WHY)]] +#elif defined(__GNUC__) && __has_cpp_attribute(deprecated) +#define MOZZI_DEPRECATED(WHEN, WHY) [[deprecated(WHY)]] +#elif defined(__GNUC__) || defined(__clang__) +#define MOZZI_DEPRECATED(WHEN, WHY) __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define MOZZI_DEPRECATED(WHEN, WHY) __declspec(deprecated) +#else +#define MOZZI_DEPRECATED(WHEN, WHY) +#endif + +/** @file mozzi_internal_macros + * Document that a function is not implemented on this platform */ +#define MOZZI_UNIMPLEMENTED() MOZZI_DEPRECATED("n/a", "This feature is not implemented on this platform.") + #endif From c9fcfd85482a02c0c4e6f9b187ef148142ecb22e Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 13:27:37 +0100 Subject: [PATCH 075/215] Move private headers to "internal", document that. --- Mozzi.h | 28 +++++++++++++++++++ MozziGuts.h | 15 +++++++--- MozziHeadersOnly.h | 28 +++++++++++++++++++ Readme_Mozzi_2_0.md | 7 ++++- .../Skeleton_Multi/Skeleton_Multi.ino | 2 +- .../Skeleton_Multi/Skeleton_Multi_Unit2.cpp | 8 ++---- MozziGuts.hpp => internal/MozziGuts.hpp | 0 .../MozziGuts_impl_AVR.hpp | 0 .../MozziGuts_impl_ESP32.hpp | 0 .../MozziGuts_impl_ESP8266.hpp | 0 .../MozziGuts_impl_MBED.hpp | 0 .../MozziGuts_impl_RENESAS.hpp | 0 .../MozziGuts_impl_RENESAS_ADC.hpp | 0 .../MozziGuts_impl_RENESAS_analog.hpp | 0 .../MozziGuts_impl_RP2040.hpp | 0 .../MozziGuts_impl_SAMD.hpp | 0 .../MozziGuts_impl_STM32.hpp | 0 .../MozziGuts_impl_STM32duino.hpp | 0 .../MozziGuts_impl_STM32duino_analog.hpp | 0 .../MozziGuts_impl_TEENSY.hpp | 0 .../MozziGuts_impl_template.hpp | 0 internal/config_checks_generic.h | 1 + teensyPinMap.h => internal/teensyPinMap.h | 0 mozzi_analog.h | 10 +------ 24 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 Mozzi.h create mode 100644 MozziHeadersOnly.h rename MozziGuts.hpp => internal/MozziGuts.hpp (100%) rename MozziGuts_impl_AVR.hpp => internal/MozziGuts_impl_AVR.hpp (100%) rename MozziGuts_impl_ESP32.hpp => internal/MozziGuts_impl_ESP32.hpp (100%) rename MozziGuts_impl_ESP8266.hpp => internal/MozziGuts_impl_ESP8266.hpp (100%) rename MozziGuts_impl_MBED.hpp => internal/MozziGuts_impl_MBED.hpp (100%) rename MozziGuts_impl_RENESAS.hpp => internal/MozziGuts_impl_RENESAS.hpp (100%) rename MozziGuts_impl_RENESAS_ADC.hpp => internal/MozziGuts_impl_RENESAS_ADC.hpp (100%) rename MozziGuts_impl_RENESAS_analog.hpp => internal/MozziGuts_impl_RENESAS_analog.hpp (100%) rename MozziGuts_impl_RP2040.hpp => internal/MozziGuts_impl_RP2040.hpp (100%) rename MozziGuts_impl_SAMD.hpp => internal/MozziGuts_impl_SAMD.hpp (100%) rename MozziGuts_impl_STM32.hpp => internal/MozziGuts_impl_STM32.hpp (100%) rename MozziGuts_impl_STM32duino.hpp => internal/MozziGuts_impl_STM32duino.hpp (100%) rename MozziGuts_impl_STM32duino_analog.hpp => internal/MozziGuts_impl_STM32duino_analog.hpp (100%) rename MozziGuts_impl_TEENSY.hpp => internal/MozziGuts_impl_TEENSY.hpp (100%) rename MozziGuts_impl_template.hpp => internal/MozziGuts_impl_template.hpp (100%) rename teensyPinMap.h => internal/teensyPinMap.h (100%) diff --git a/Mozzi.h b/Mozzi.h new file mode 100644 index 000000000..6dca6b0ed --- /dev/null +++ b/Mozzi.h @@ -0,0 +1,28 @@ +/* + * Mozzi.h + * + * Copyright 2023, Thomas Combriat and the Mozzi team + * + * This file is part of Mozzi. + * + * Mozzi is licensed under a Creative Commons + * Attribution-NonCommercial-ShareAlike 4.0 International License. + * + */ + +/** @ingroup core + * @file Mozzi.h + * + * This is the main include file in Mozzi. Almost all sketches using Mozzi will want to include this file @em exactly once. + * + * Should your sketch require \ref core Mozzi functions in more than one translation unit (i.e. you have more than one .cpp-file + * in your sketch itself), only *one* of these shall include this file, while any others shall include \ref MozziHeadersOnly instead. + * (Failing to heed this advice will lead to "duplicate definition" errors.) + */ + +#ifndef MOZZI_H_ +#define MOZZI_H_ + +#include "MozziGuts.h" + +#endif diff --git a/MozziGuts.h b/MozziGuts.h index 83ca6c35c..4919f4482 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -12,7 +12,14 @@ #ifndef MOZZIGUTS_H_ #define MOZZIGUTS_H_ - #include "Arduino.h" +#include "Arduino.h" + +#include "MozziConfigValues.h" + +#if !(defined(MOZZI_H_) || defined(MOZZI_HEADERS_ONLY_H_)) +#warning Direct inclusion of MozziGuts.h is deprecated. Use Mozzi.h, instead, and read about porting to Mozzi 2.0 +#define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_1_1 +#endif #include "hardware_defines.h" #include "mozzi_config.h" @@ -82,7 +89,7 @@ forked version of Mozzi on github, so sound production can continue while reading sensors. As it is, stopMozzi restores all the Timers used by Mozzi to their previous -settings. Another scenario which could be easily hacked in MozziGuts.cpp could +settings. Another scenario which could be easily hacked in MozziGuts.hpp could involve individually saving and restoring particular Timer registers depending on which one(s) are required for other tasks. @@ -173,8 +180,8 @@ is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when */ unsigned long mozziMicros(); -#ifndef MOZZI_HEADER_ONLY -#include "MozziGuts.hpp" +#ifndef _MOZZI_HEADER_ONLY +#include "internal/MozziGuts.hpp" #endif #endif /* MOZZIGUTS_H_ */ diff --git a/MozziHeadersOnly.h b/MozziHeadersOnly.h new file mode 100644 index 000000000..6bd0f7b22 --- /dev/null +++ b/MozziHeadersOnly.h @@ -0,0 +1,28 @@ +/* + * Mozzi.h + * + * Copyright 2023, Thomas Combriat and the Mozzi team + * + * This file is part of Mozzi. + * + * Mozzi is licensed under a Creative Commons + * Attribution-NonCommercial-ShareAlike 4.0 International License. + * + */ + +/** @ingroup core + * @file MozziHeadersOnly.h + * + * This file provides declarations of the \ref core Mozzi functions, but no implementation. Use this only, if you have more than one + * translation unit in your project (i.e. you have more than one .cpp-file in your sketch itself). Otherwise include \ref Mozzi.h, instead. + * + * (Failure to head this advice will lead to "symbol XY undefined" errors.). + */ + +#ifndef MOZZI_HEADERS_ONLY_H_ +#define MOZZI_HEADERS_ONLY_H_ + +#define _MOZZI_HEADER_ONLY +#include "MozziGuts.h" + +#endif diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index 1ae244089..ef3a0f1c5 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -28,11 +28,16 @@ all new general: - Added many config sanity checks. Some may be too strict, if so please mention - Other removed stuff: +Other removed stuff: - pauseMozzi() - was still declared but not defined -> not usable, anyway - unpauseMozzi() - was still declared but not defined -> not usable, anyway - Teensy3/4: channel2sc1a -> thought to be unused, removed - Teensy2: adc_mapping -> hidden away; use adcPinToChannelNum(), as on all other platforms, instead + - removed inclusion of "WProgram.h". If using Arduino versions < 1.0, you need to update, seriously ;-) + +Moved headers: + - Header files not meant for user inclusion have been moved to "internal" + - New sketches should include "Mozzi.h", rather than "MozziGuts.h", thereby documenting, they have been written for Mozzi 2.0+ Documentation bits that still need to find a new home (many other bits were moved around, many, many duplicates merged into a common place, and seom obsoleted bits discarded): diff --git a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino index 2c9cc85a2..3763d22b7 100644 --- a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino @@ -4,7 +4,7 @@ * Unless you have good reason to do this, it is recommended to base your sketch on the * single-file "Skeleton" example, instead. */ -#include // at the top of your sketch +#include // at the top of your sketch void setup() { startMozzi(64); diff --git a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp index 00d33a879..4687b88b7 100644 --- a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp @@ -1,8 +1,6 @@ -// This file, too, will have to include the Mozzi headers, but in order to avoid "multiple definition" errors, -// all secondary .cpp files in the sketch must set MOZZI_HEADER_ONLY before including any Mozzi headers. -// TODO: Maybe that is not even the final word, and this will be required in the end, but it seems a useful intermediate step -#define MOZZI_HEADER_ONLY -#include +#include // should be included only once in the whole program. Sketches needing + // core Mozzi functions in more than one .cpp file, shall include MozziHeadersOnly.h + // in all but one. AudioOutput_t updateAudio() { return MonoOutput::from8Bit(0); // just a dummy diff --git a/MozziGuts.hpp b/internal/MozziGuts.hpp similarity index 100% rename from MozziGuts.hpp rename to internal/MozziGuts.hpp diff --git a/MozziGuts_impl_AVR.hpp b/internal/MozziGuts_impl_AVR.hpp similarity index 100% rename from MozziGuts_impl_AVR.hpp rename to internal/MozziGuts_impl_AVR.hpp diff --git a/MozziGuts_impl_ESP32.hpp b/internal/MozziGuts_impl_ESP32.hpp similarity index 100% rename from MozziGuts_impl_ESP32.hpp rename to internal/MozziGuts_impl_ESP32.hpp diff --git a/MozziGuts_impl_ESP8266.hpp b/internal/MozziGuts_impl_ESP8266.hpp similarity index 100% rename from MozziGuts_impl_ESP8266.hpp rename to internal/MozziGuts_impl_ESP8266.hpp diff --git a/MozziGuts_impl_MBED.hpp b/internal/MozziGuts_impl_MBED.hpp similarity index 100% rename from MozziGuts_impl_MBED.hpp rename to internal/MozziGuts_impl_MBED.hpp diff --git a/MozziGuts_impl_RENESAS.hpp b/internal/MozziGuts_impl_RENESAS.hpp similarity index 100% rename from MozziGuts_impl_RENESAS.hpp rename to internal/MozziGuts_impl_RENESAS.hpp diff --git a/MozziGuts_impl_RENESAS_ADC.hpp b/internal/MozziGuts_impl_RENESAS_ADC.hpp similarity index 100% rename from MozziGuts_impl_RENESAS_ADC.hpp rename to internal/MozziGuts_impl_RENESAS_ADC.hpp diff --git a/MozziGuts_impl_RENESAS_analog.hpp b/internal/MozziGuts_impl_RENESAS_analog.hpp similarity index 100% rename from MozziGuts_impl_RENESAS_analog.hpp rename to internal/MozziGuts_impl_RENESAS_analog.hpp diff --git a/MozziGuts_impl_RP2040.hpp b/internal/MozziGuts_impl_RP2040.hpp similarity index 100% rename from MozziGuts_impl_RP2040.hpp rename to internal/MozziGuts_impl_RP2040.hpp diff --git a/MozziGuts_impl_SAMD.hpp b/internal/MozziGuts_impl_SAMD.hpp similarity index 100% rename from MozziGuts_impl_SAMD.hpp rename to internal/MozziGuts_impl_SAMD.hpp diff --git a/MozziGuts_impl_STM32.hpp b/internal/MozziGuts_impl_STM32.hpp similarity index 100% rename from MozziGuts_impl_STM32.hpp rename to internal/MozziGuts_impl_STM32.hpp diff --git a/MozziGuts_impl_STM32duino.hpp b/internal/MozziGuts_impl_STM32duino.hpp similarity index 100% rename from MozziGuts_impl_STM32duino.hpp rename to internal/MozziGuts_impl_STM32duino.hpp diff --git a/MozziGuts_impl_STM32duino_analog.hpp b/internal/MozziGuts_impl_STM32duino_analog.hpp similarity index 100% rename from MozziGuts_impl_STM32duino_analog.hpp rename to internal/MozziGuts_impl_STM32duino_analog.hpp diff --git a/MozziGuts_impl_TEENSY.hpp b/internal/MozziGuts_impl_TEENSY.hpp similarity index 100% rename from MozziGuts_impl_TEENSY.hpp rename to internal/MozziGuts_impl_TEENSY.hpp diff --git a/MozziGuts_impl_template.hpp b/internal/MozziGuts_impl_template.hpp similarity index 100% rename from MozziGuts_impl_template.hpp rename to internal/MozziGuts_impl_template.hpp diff --git a/internal/config_checks_generic.h b/internal/config_checks_generic.h index df29fe621..380b596ff 100644 --- a/internal/config_checks_generic.h +++ b/internal/config_checks_generic.h @@ -44,6 +44,7 @@ #endif #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && !defined(MOZZI_AUDIO_INPUT_PIN) +#warning Using audio input, but no audio input pin defined, explicitly. Defaulting to pin 0. #define MOZZI_AUDIO_INPUT_PIN 0 #endif diff --git a/teensyPinMap.h b/internal/teensyPinMap.h similarity index 100% rename from teensyPinMap.h rename to internal/teensyPinMap.h diff --git a/mozzi_analog.h b/mozzi_analog.h index d0080c3d6..57eb221c6 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -12,18 +12,10 @@ #ifndef MOZZI_ANALOG_H_ #define MOZZI_ANALOG_H_ - #if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include "Arduino.h" #include "hardware_defines.h" -#if (USE_AUDIO_INPUT==true) -#warning "Using AUDIO_INPUT_PIN defined in mozzi_config.h for audio input." -#endif - // for setupFastAnalogRead() enum ANALOG_READ_SPEED {FAST_ADC,FASTER_ADC,FASTEST_ADC}; From ee4efe31e043c8a922adf0f372f1a69a837997e1 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 13:41:24 +0100 Subject: [PATCH 076/215] Include Mozzi.h/MozziHeadersOnly.h instead of MozziGuts.h, everywhere --- Oscil.h | 8 ++------ Sample.h | 2 +- WavePacket.h | 14 +++++++------- config/mozzi_config_documentation.h | 2 +- examples/01.Basics/Control_Gain/Control_Gain.ino | 2 +- examples/01.Basics/Sinewave/Sinewave.ino | 2 +- examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino | 2 +- examples/01.Basics/Skeleton/Skeleton.ino | 2 +- .../Table_Resolution/Table_Resolution.ino | 2 +- examples/01.Basics/Vibrato/Vibrato.ino | 2 +- .../Control_Echo_Theremin.ino | 2 +- .../Control_Oscil_Wash/Control_Oscil_Wash.ino | 2 +- .../02.Control/Control_Tremelo/Control_Tremelo.ino | 2 +- examples/02.Control/EventDelay/EventDelay.ino | 2 +- examples/02.Control/Line_Gliss/Line_Gliss.ino | 2 +- .../Line_Gliss_Double_32k_HIFI.ino | 2 +- .../Metronome_SampleHuffman.ino | 2 +- examples/02.Control/Stop_Start/Stop_Start.ino | 2 +- .../Knob_LightLevel_FMsynth.ino | 2 +- .../Knob_LightLevel_x2_FMsynth.ino | 2 +- .../Light_Temperature_Detuned.ino | 2 +- .../Light_Temperature_Multi_Oscil.ino | 2 +- .../03.Sensors/Piezo_Frequency/Piezo_Frequency.ino | 2 +- .../Piezo_SampleScrubber/Piezo_SampleScrubber.ino | 2 +- .../Piezo_SampleTrigger/Piezo_SampleTrigger.ino | 2 +- .../Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino | 2 +- examples/03.Sensors/RCpoll/RCpoll.ino | 2 +- .../Sinewave_Pinchange_Interrupt.ino | 2 +- examples/03.Sensors/Volume_Knob/Volume_Knob.ino | 2 +- .../Volume_Knob_LightLevel_Frequency.ino | 2 +- .../04.Audio_Input/Audio_Input/Audio_Input.ino | 2 +- .../Audio_Input_with_Knob_Filter.ino | 2 +- .../Audio_and_Control_Input.ino | 2 +- examples/05.Control_Filters/DCfilter/DCfilter.ino | 2 +- .../Line_vs_Smooth/Line_vs_Smooth.ino | 2 +- .../MIDI_portamento/MIDI_portamento.ino | 2 +- .../RollingAverage/RollingAverage.ino | 2 +- examples/05.Control_Filters/Smooth/Smooth.ino | 2 +- .../Smooth_Frequency/Smooth_Frequency.ino | 2 +- .../Thermistor_OverSample.ino | 2 +- examples/06.Synthesis/AMsynth/AMsynth.ino | 2 +- .../06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino | 2 +- .../Brown_Noise_Realtime/Brown_Noise_Realtime.ino | 2 +- .../Detuned_Beats_Wash/Detuned_Beats_Wash.ino | 2 +- .../Difference_Tone/Difference_Tone.ino | 2 +- examples/06.Synthesis/FMsynth/FMsynth.ino | 2 +- .../FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino | 2 +- .../NonAlias_MetaOscil/NonAlias_MetaOscil.ino | 2 +- examples/06.Synthesis/PDresonant/PDresonant.ino | 2 +- examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino | 2 +- examples/06.Synthesis/WaveFolder/WaveFolder.ino | 2 +- .../WavePacket_Double/WavePacket_Double.ino | 2 +- .../WavePacket_Sample/WavePacket_Sample.ino | 1 + .../WavePacket_Single/WavePacket_Single.ino | 1 + examples/06.Synthesis/Waveshaper/Waveshaper.ino | 2 +- .../ADSR_Audio_Rate_Envelope.ino | 2 +- .../ADSR_Audio_Rate_Envelope_Long.ino | 2 +- .../ADSR_Audio_Rate_Envelope_x2.ino | 2 +- .../ADSR_Control_Rate_Envelope.ino | 2 +- .../07.Envelopes/Ead_Envelope/Ead_Envelope.ino | 2 +- .../Phasemod_Envelope/Phasemod_Envelope.ino | 2 +- examples/08.Samples/Sample/Sample.ino | 2 +- .../SampleHuffman_Umpah/SampleHuffman_Umpah.ino | 2 +- .../Sample_Loop_Points/Sample_Loop_Points.ino | 2 +- examples/08.Samples/Sample_Scrub/Sample_Scrub.ino | 2 +- examples/08.Samples/Samples/Samples.ino | 2 +- .../Samples_Tables_Arrays.ino | 2 +- .../08.Samples/Wavetable_Swap/Wavetable_Swap.ino | 2 +- examples/09.Delays/AudioDelay/AudioDelay.ino | 2 +- .../AudioDelayFeedback/AudioDelayFeedback.ino | 2 +- .../AudioDelayFeedbackAllpass.ino | 2 +- .../AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino | 2 +- .../AudioDelayFeedback_HIFI.ino | 2 +- .../09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino | 2 +- .../ReverbTank_STANDARD/ReverbTank_STANDARD.ino | 2 +- .../LowPassFilterX2/LowPassFilterX2.ino | 2 +- .../MultiResonantFilter/MultiResonantFilter.ino | 2 +- .../ResonantFilter/ResonantFilter.ino | 2 +- .../ResonantFilter16/ResonantFilter16.ino | 2 +- .../StateVariableFilter/StateVariableFilter.ino | 2 +- .../StateVariableFilter_HIFI.ino | 2 +- .../Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino | 2 +- .../Sinewave_PWM_leds_HIFI.ino | 2 +- .../Teensy_USB_MIDI_Input.ino | 2 +- .../TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino | 2 +- .../12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino | 2 +- .../Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino | 2 +- examples/12.Misc/Stereo_Hack/Stereo_Hack.ino | 2 +- .../12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino | 2 +- .../FMsynth_MCP4921_mono_12bits.ino | 2 +- .../MCP4922_mono_24bits/MCP4922_mono_24bits.ino | 2 +- .../PT8211_stereo_16bits/PT8211_stereo_16bits.ino | 2 +- .../PT8211_stereo_16bits_STM32_SPI2.ino | 2 +- .../Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino | 2 +- .../Sinewave_R2R_DAC_74HC595.ino | 2 +- .../Stereo_Pan_MCP4922_stereo_12bits.ino | 2 +- hardware_defines.h | 6 +----- internal/MozziGuts.hpp | 1 - library.properties | 4 ++-- 99 files changed, 106 insertions(+), 113 deletions(-) diff --git a/Oscil.h b/Oscil.h index d5b302daf..945f4a0e1 100644 --- a/Oscil.h +++ b/Oscil.h @@ -14,12 +14,8 @@ #ifndef OSCIL_H_ #define OSCIL_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif -#include "MozziGuts.h" +#include "Arduino.h" +#include "MozziHeadersOnly.h" #include "mozzi_fixmath.h" #include "mozzi_pgmspace.h" diff --git a/Sample.h b/Sample.h index 74a2f2eab..9c79c1084 100644 --- a/Sample.h +++ b/Sample.h @@ -12,7 +12,7 @@ #ifndef SAMPLE_H_ #define SAMPLE_H_ -#include "MozziGuts.h" +#include "MozziHeadersOnly.h" #include "mozzi_fixmath.h" #include "mozzi_pgmspace.h" diff --git a/WavePacket.h b/WavePacket.h index 4fed43da5..2b5f13033 100644 --- a/WavePacket.h +++ b/WavePacket.h @@ -13,13 +13,13 @@ #ifndef WAVEPACKET_H #define WAVEPACKET_H -#include -#include -#include -#include -#include -#include -#include +#include "MozziHeadersOnly.h" +#include "Oscil.h" +#include "tables/cos8192_int8.h" +#include "mozzi_fixmath.h" +#include "Phasor.h" +#include "Line.h" +#include "meta.h" enum algorithms {SINGLE,DOUBLE}; diff --git a/config/mozzi_config_documentation.h b/config/mozzi_config_documentation.h index b9c0eb538..26e4ee625 100644 --- a/config/mozzi_config_documentation.h +++ b/config/mozzi_config_documentation.h @@ -99,7 +99,7 @@ * @note * For compatibility reasons, the option AUDIO_RATE is automatically set to the same value as this option, and you will find some uses of that in old (pre Mozzi 2.0) code examples. * It is advised to use only MOZZI_AUDIO_RATE in new code, however. - * TODO: Only do the above, if MozziGuts.h, rather than Mozzi.h was included? + * TODO: Only do the above, for MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_2_0? */ diff --git a/examples/01.Basics/Control_Gain/Control_Gain.ino b/examples/01.Basics/Control_Gain/Control_Gain.ino index 2316d2600..b7e32298b 100644 --- a/examples/01.Basics/Control_Gain/Control_Gain.ino +++ b/examples/01.Basics/Control_Gain/Control_Gain.ino @@ -17,7 +17,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator diff --git a/examples/01.Basics/Sinewave/Sinewave.ino b/examples/01.Basics/Sinewave/Sinewave.ino index 27b2d4a80..9314fa6c7 100644 --- a/examples/01.Basics/Sinewave/Sinewave.ino +++ b/examples/01.Basics/Sinewave/Sinewave.ino @@ -16,7 +16,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator diff --git a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino index 2dd1b8301..c80cd3c76 100644 --- a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino +++ b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino @@ -41,7 +41,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator diff --git a/examples/01.Basics/Skeleton/Skeleton.ino b/examples/01.Basics/Skeleton/Skeleton.ino index 1bbc7fc23..cbc5a3d6e 100644 --- a/examples/01.Basics/Skeleton/Skeleton.ino +++ b/examples/01.Basics/Skeleton/Skeleton.ino @@ -1,4 +1,4 @@ -#include // at the top of your sketch +#include // at the top of your sketch #define CONTROL_RATE 64 void setup() { diff --git a/examples/01.Basics/Table_Resolution/Table_Resolution.ino b/examples/01.Basics/Table_Resolution/Table_Resolution.ino index 7a5852b61..c9f286b33 100644 --- a/examples/01.Basics/Table_Resolution/Table_Resolution.ino +++ b/examples/01.Basics/Table_Resolution/Table_Resolution.ino @@ -14,7 +14,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/01.Basics/Vibrato/Vibrato.ino b/examples/01.Basics/Vibrato/Vibrato.ino index 62a838be9..a232275f8 100644 --- a/examples/01.Basics/Vibrato/Vibrato.ino +++ b/examples/01.Basics/Vibrato/Vibrato.ino @@ -16,7 +16,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include // for mtof diff --git a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino index cf1f1ee13..a0069f23d 100644 --- a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino +++ b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino @@ -25,7 +25,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator #include diff --git a/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino b/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino index aef17e329..01482a2e2 100644 --- a/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino +++ b/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino @@ -21,7 +21,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino index 73d47211c..40ea37af5 100644 --- a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino +++ b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino @@ -21,7 +21,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/02.Control/EventDelay/EventDelay.ino b/examples/02.Control/EventDelay/EventDelay.ino index 05a8a6a07..a81661ac3 100644 --- a/examples/02.Control/EventDelay/EventDelay.ino +++ b/examples/02.Control/EventDelay/EventDelay.ino @@ -20,7 +20,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator #include diff --git a/examples/02.Control/Line_Gliss/Line_Gliss.ino b/examples/02.Control/Line_Gliss/Line_Gliss.ino index 33b4551c4..7c68ea7fb 100644 --- a/examples/02.Control/Line_Gliss/Line_Gliss.ino +++ b/examples/02.Control/Line_Gliss/Line_Gliss.ino @@ -25,7 +25,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // for smooth transitions #include // oscillator template #include // saw table for oscillator diff --git a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino index 8ba18f9c7..70d92bcec 100644 --- a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino +++ b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino @@ -57,7 +57,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // for smooth transitions #include // oscillator template #include // saw table for oscillator diff --git a/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino b/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino index a63cad2e5..8be25c49c 100644 --- a/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino +++ b/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino @@ -16,7 +16,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/02.Control/Stop_Start/Stop_Start.ino b/examples/02.Control/Stop_Start/Stop_Start.ino index 1c1937ce6..086338d2e 100644 --- a/examples/02.Control/Stop_Start/Stop_Start.ino +++ b/examples/02.Control/Stop_Start/Stop_Start.ino @@ -21,7 +21,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include // sine table for oscillator diff --git a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino index 55a15d229..39b2ba042 100644 --- a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino @@ -33,7 +33,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator #include // table for Oscils to play #include // maps unpredictable inputs to a range diff --git a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino index 294b9e70a..2686d8b13 100644 --- a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino @@ -36,7 +36,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator #include // table for Oscils to play #include diff --git a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino index 0d321f871..0bb8d8677 100644 --- a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino +++ b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino @@ -30,7 +30,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino index ab0543274..5f28a48a1 100644 --- a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino +++ b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino @@ -29,7 +29,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino index 9ac767c52..47cdacbf5 100644 --- a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino +++ b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino @@ -26,7 +26,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator #include // table for Oscils to play #include diff --git a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino index 4e3fba4ca..fcbdf69ed 100644 --- a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino +++ b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino @@ -28,7 +28,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // Sample template #include "blahblah4b_int8.h" #include diff --git a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino index 96a26bdf6..d5e2b99cc 100644 --- a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino +++ b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino @@ -32,7 +32,7 @@ CC by-nc-sa */ -#include +#include #include // Sample template #include // a converted audio sample included in the Mozzi download diff --git a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino index 8663bef1e..ed2e24288 100644 --- a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino +++ b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino @@ -32,7 +32,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // Sample template #include // a converted audio sample included in the Mozzi download diff --git a/examples/03.Sensors/RCpoll/RCpoll.ino b/examples/03.Sensors/RCpoll/RCpoll.ino index 0bb38942b..0cc0e54cd 100644 --- a/examples/03.Sensors/RCpoll/RCpoll.ino +++ b/examples/03.Sensors/RCpoll/RCpoll.ino @@ -38,7 +38,7 @@ sPin ---\/\/\/-----. */ -#include +#include #include #include // sine table for oscillator #include diff --git a/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino b/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino index 33c9a40b8..9bec01a16 100644 --- a/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino +++ b/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino @@ -27,7 +27,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator #include diff --git a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino index 4db03e90b..c87c01560 100644 --- a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino +++ b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino @@ -31,7 +31,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator diff --git a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino index 47f4c9da6..6b1565b6f 100644 --- a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino +++ b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino @@ -36,7 +36,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator diff --git a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino index 0abfdfbcd..301eb4b61 100644 --- a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino +++ b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino @@ -18,7 +18,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include void setup(){ startMozzi(); diff --git a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino index 585ac01b0..21957048d 100644 --- a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino +++ b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino @@ -23,7 +23,7 @@ */ -#include +#include #include #define KNOB_PIN 1 diff --git a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino index 3f15f5f62..51392a138 100644 --- a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino +++ b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino @@ -29,7 +29,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include void setup() { diff --git a/examples/05.Control_Filters/DCfilter/DCfilter.ino b/examples/05.Control_Filters/DCfilter/DCfilter.ino index 1b6337cc1..b1df39c9a 100644 --- a/examples/05.Control_Filters/DCfilter/DCfilter.ino +++ b/examples/05.Control_Filters/DCfilter/DCfilter.ino @@ -17,7 +17,7 @@ */ -#include +#include #include int sensorPin = A0; diff --git a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino index 0d5229f8a..aa6e14e92 100644 --- a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino +++ b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino @@ -25,7 +25,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include // sine table for oscillator #include diff --git a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino index 11a4d08a3..1cecc9fc5 100644 --- a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino +++ b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino @@ -22,7 +22,7 @@ */ #include -#include +#include #include // oscillator template #include // for envelope #include // sine table for oscillator diff --git a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino index 060c35f07..73b107306 100644 --- a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino +++ b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino @@ -19,7 +19,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator #include diff --git a/examples/05.Control_Filters/Smooth/Smooth.ino b/examples/05.Control_Filters/Smooth/Smooth.ino index 1c805fb98..9a8083754 100644 --- a/examples/05.Control_Filters/Smooth/Smooth.ino +++ b/examples/05.Control_Filters/Smooth/Smooth.ino @@ -18,7 +18,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator #include diff --git a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino index c4c98c725..9c964caec 100644 --- a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino +++ b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino @@ -16,7 +16,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator #include diff --git a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino index fabdf37b4..0459fb0f9 100644 --- a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino +++ b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino @@ -29,7 +29,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include // oscillator template #include #include // SINe table for oscillator diff --git a/examples/06.Synthesis/AMsynth/AMsynth.ino b/examples/06.Synthesis/AMsynth/AMsynth.ino index 66d08e053..8cd90761b 100644 --- a/examples/06.Synthesis/AMsynth/AMsynth.ino +++ b/examples/06.Synthesis/AMsynth/AMsynth.ino @@ -20,7 +20,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino index 2b70710a9..52302497f 100644 --- a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino +++ b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino @@ -46,7 +46,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino b/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino index 490b3716b..d1ad9e398 100644 --- a/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino +++ b/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino @@ -18,7 +18,7 @@ Tim Barrass 20118, CC by-nc-sa. */ -#include +#include #include #include // oscillator template #include // sine table for oscillator diff --git a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino index 4c076a005..05eb161d1 100644 --- a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino +++ b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino @@ -29,7 +29,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino index c7b8d41a6..46d2efbc4 100644 --- a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino +++ b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino @@ -17,7 +17,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/06.Synthesis/FMsynth/FMsynth.ino b/examples/06.Synthesis/FMsynth/FMsynth.ino index b450fb552..b21c40ebf 100644 --- a/examples/06.Synthesis/FMsynth/FMsynth.ino +++ b/examples/06.Synthesis/FMsynth/FMsynth.ino @@ -22,7 +22,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino index 7b6c4b65b..90e0bab18 100644 --- a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino +++ b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino @@ -49,7 +49,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino index eeaf53d6e..6e4ff3fa2 100644 --- a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino +++ b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino @@ -35,7 +35,7 @@ Tim Barrass 2012, Combriat T. 2021, CC by-nc-sa. */ -#include +#include #include // oscillator template #include diff --git a/examples/06.Synthesis/PDresonant/PDresonant.ino b/examples/06.Synthesis/PDresonant/PDresonant.ino index 05452a34f..856dd7262 100644 --- a/examples/06.Synthesis/PDresonant/PDresonant.ino +++ b/examples/06.Synthesis/PDresonant/PDresonant.ino @@ -28,7 +28,7 @@ //#include may be needed on some systems/versions -#include +#include // for fake midi #include diff --git a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino index dd9c07370..eafe06028 100644 --- a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino +++ b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino @@ -21,7 +21,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include Phasor aPhasor1; diff --git a/examples/06.Synthesis/WaveFolder/WaveFolder.ino b/examples/06.Synthesis/WaveFolder/WaveFolder.ino index c4ca20993..54bff7aa2 100644 --- a/examples/06.Synthesis/WaveFolder/WaveFolder.ino +++ b/examples/06.Synthesis/WaveFolder/WaveFolder.ino @@ -17,7 +17,7 @@ */ -#include +#include #include // oscillator template #include // sine table for oscillator #include // saw table for oscillator diff --git a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino index 7558a4c1a..1c8d0be93 100644 --- a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino +++ b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino @@ -29,7 +29,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino index 323c50d17..116e69593 100644 --- a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino +++ b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino @@ -32,6 +32,7 @@ Tim Barrass 2013, CC by-nc-sa. */ +#include #include #include #include diff --git a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino index 60c0b80ca..ad8eed2d1 100644 --- a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino +++ b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino @@ -29,6 +29,7 @@ Tim Barrass 2013, CC by-nc-sa. */ +#include #include #include #include diff --git a/examples/06.Synthesis/Waveshaper/Waveshaper.ino b/examples/06.Synthesis/Waveshaper/Waveshaper.ino index f2fe31236..8a1d62e39 100644 --- a/examples/06.Synthesis/Waveshaper/Waveshaper.ino +++ b/examples/06.Synthesis/Waveshaper/Waveshaper.ino @@ -17,7 +17,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino index 839a70b8a..3755951e7 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino @@ -19,7 +19,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino index 518f852ef..515a94ce7 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino @@ -22,7 +22,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino index 112fecfcf..299c1c7df 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino @@ -17,7 +17,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino index 30f27aab3..64679efb3 100644 --- a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino @@ -11,7 +11,7 @@ Tim Barrass 2013-14, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino index 72a7b6c25..a75c2bf75 100644 --- a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino +++ b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino @@ -13,7 +13,7 @@ Tim Barrass 2012, CC by-nc-sa */ -#include +#include #include // oscillator template #include // recorded audio wavetable #include // exponential attack decay diff --git a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino index 3dd6f9cf2..975e75980 100644 --- a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino +++ b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino @@ -14,7 +14,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/08.Samples/Sample/Sample.ino b/examples/08.Samples/Sample/Sample.ino index cc89bd066..b5723eaea 100644 --- a/examples/08.Samples/Sample/Sample.ino +++ b/examples/08.Samples/Sample/Sample.ino @@ -17,7 +17,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // Sample template #include #include diff --git a/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino b/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino index de8d4ab93..9958e7584 100644 --- a/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino +++ b/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino @@ -41,7 +41,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include "umpah_huff.h" diff --git a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino index 4c674ea23..599b6b555 100644 --- a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino +++ b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino @@ -20,7 +20,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // Sample template #include // table for Sample #include diff --git a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino index d8e02f575..caf07de1c 100644 --- a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino +++ b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino @@ -15,7 +15,7 @@ CC by-nc-sa */ -#include +#include #include // Sample template #include #include diff --git a/examples/08.Samples/Samples/Samples.ino b/examples/08.Samples/Samples/Samples.ino index 00854ccec..4a2cb4a76 100644 --- a/examples/08.Samples/Samples/Samples.ino +++ b/examples/08.Samples/Samples/Samples.ino @@ -18,7 +18,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include // Sample template #include // wavetable data #include // wavetable data diff --git a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino index 2d2e4e4ab..4a0d84983 100644 --- a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino +++ b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino @@ -22,7 +22,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include // for rand() diff --git a/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino b/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino index bf44075b9..8711475ff 100644 --- a/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino +++ b/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino @@ -7,7 +7,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include diff --git a/examples/09.Delays/AudioDelay/AudioDelay.ino b/examples/09.Delays/AudioDelay/AudioDelay.ino index e651eb60a..99ef70189 100644 --- a/examples/09.Delays/AudioDelay/AudioDelay.ino +++ b/examples/09.Delays/AudioDelay/AudioDelay.ino @@ -16,7 +16,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include // wavetable #include // wavetable diff --git a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino index 250922569..fe91c592d 100644 --- a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino +++ b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino @@ -16,7 +16,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ -#include +#include #include #include // wavetable #include // wavetable diff --git a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino index 431e4a3f1..9178af5c3 100644 --- a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino +++ b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino @@ -18,7 +18,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ -#include +#include #include #include #include // exponential attack decay diff --git a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino index aed092e1b..09b68ffae 100644 --- a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino +++ b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino @@ -17,7 +17,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ -#include +#include #include #include // wavetable for audio #include // wavetable for delay sweep diff --git a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino index d41276f72..ee048d561 100644 --- a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino +++ b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino @@ -47,7 +47,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ -#include +#include #include #include // wavetable #include // wavetable diff --git a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino index e264c6671..c9fa316b1 100644 --- a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino +++ b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino @@ -22,7 +22,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino index 20e73e694..e7eaf651e 100644 --- a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino +++ b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino @@ -22,7 +22,7 @@ Tim Barrass 2013, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino index cab4e77e3..a16d122a2 100644 --- a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino +++ b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino @@ -16,7 +16,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include // recorded audio wavetable #include // for filter modulation diff --git a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino index 06fb110df..a01e1afd1 100644 --- a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino +++ b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino @@ -23,7 +23,7 @@ Thomas Combriat 2023, CC by-nc-sa. */ -#include +#include #include #include // recorded audio wavetable #include // for filter modulation diff --git a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino index 77b775c0e..5e4c63054 100644 --- a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino +++ b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino @@ -20,7 +20,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include // recorded audio wavetable #include // for filter modulation diff --git a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino index 19a7f048a..50980fe4c 100644 --- a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino +++ b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino @@ -22,7 +22,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include // recorded audio wavetable #include // for filter modulation diff --git a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino index 8db1a6d57..3edd09133 100644 --- a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino +++ b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino @@ -16,7 +16,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include // for filter modulation diff --git a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino index cb23712b4..fc6afb006 100644 --- a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino +++ b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino @@ -43,7 +43,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include diff --git a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino index 24513f1a4..c563e00e5 100644 --- a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino +++ b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino @@ -20,7 +20,7 @@ */ #include -#include +#include #include // oscillator template #include // sine table for oscillator #include diff --git a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino index 208341260..746192fe1 100644 --- a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino +++ b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino @@ -57,7 +57,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator diff --git a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino index 216a7ae5d..c5ce5cf5e 100644 --- a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino +++ b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino @@ -22,7 +22,7 @@ */ #include -#include +#include #include // oscillator template #include // sine table for oscillator #include diff --git a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino index aedd5935a..1236c6c34 100644 --- a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino +++ b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino @@ -20,7 +20,7 @@ This example code is in the public domain. */ -#include +#include #include // oscillator template #include // exponential attack decay #include // sine table for oscillator diff --git a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino index ed1b0c41e..3c3954618 100644 --- a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino +++ b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino @@ -33,7 +33,7 @@ Tim Barrass 2018, CC by-nc-sa. */ -#include +#include #include // Sample template #include // table for Sample #include diff --git a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino index eefecd0ff..51334ddb3 100644 --- a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino +++ b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino @@ -30,7 +30,7 @@ Tim Barrass 2018, CC by-nc-sa. */ -#include +#include #include #include #include "triangle512_uint8.h" diff --git a/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino b/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino index 1bcc71484..2db36b1db 100644 --- a/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino +++ b/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino @@ -12,7 +12,7 @@ * This example code is in the public domain. */ -#include +#include #include // for controlling panning position #include // oscil for audio sig #include // table for oscillator diff --git a/examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino b/examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino index b6943face..0808f6c29 100644 --- a/examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino +++ b/examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino @@ -15,7 +15,7 @@ This example code is in the public domain. */ -#include +#include #include // oscil for audio sig #include // table for audio oscillator #include // sine table for pan oscillator diff --git a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino index 252d322ed..d3ffabb37 100644 --- a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino +++ b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino @@ -29,7 +29,7 @@ T. Combriat 2020, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino index 463515201..96c505a79 100644 --- a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino +++ b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino @@ -50,7 +50,7 @@ T. Combriat 2020, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino index 996d94101..258c74f41 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino @@ -30,7 +30,7 @@ T. Combriat 2020, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino index 3658191a0..e9b8eb751 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino @@ -30,7 +30,7 @@ T. Combriat 2020, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino index 3979db190..dfa5635a7 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino @@ -42,7 +42,7 @@ T. Combriat 2020, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino index b450d253d..3b2e95d93 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino @@ -47,7 +47,7 @@ T. Combriat 2020, CC by-nc-sa. */ -#include +#include #include // oscillator template #include // sine table for oscillator #include // needed for the shift register diff --git a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino index 2182c3bfd..3beb39f78 100644 --- a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino +++ b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino @@ -32,7 +32,7 @@ T. Combriat 2020, CC by-nc-sa. */ -#include +#include #include #include // table for Oscils to play #include diff --git a/hardware_defines.h b/hardware_defines.h index b93fc34e3..1cd708c0d 100644 --- a/hardware_defines.h +++ b/hardware_defines.h @@ -1,11 +1,7 @@ #ifndef HARDWARE_DEFINES_H_ #define HARDWARE_DEFINES_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include "Arduino.h" /* Macros to tell apart the supported platforms. The advantages of using these are, rather than the underlying defines - Easier to read and write diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 852922bcb..4ce3c0f8f 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -12,7 +12,6 @@ #include #include "CircularBuffer.h" -#include "MozziGuts.h" #include "mozzi_analog.h" #include "internal/mozzi_rand_p.h" #include "AudioOutput.h" diff --git a/library.properties b/library.properties index 053ce5357..4cbb8480c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Mozzi -version=1.1.2 +version=1.9.9 author=Tim Barrass and contributors as documented in source, and at https://github.com/sensorium/Mozzi/graphs/contributors maintainer=Tim Barrass sentence=Sound synthesis library for Arduino @@ -8,4 +8,4 @@ category=Signal Input/Output url=https://sensorium.github.io/Mozzi/ architectures=* dot_a_linkage=false -includes=MozziGuts.h +includes=Mozzi.h From 832cf3ad1f62b2a1b178fc26e84cac02baee25e6 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 14:02:52 +0100 Subject: [PATCH 077/215] Remove TimerZero-utility-lib, which is no longer used since quite some time (but continued to occupy flash) --- Readme_Mozzi_2_0.md | 14 ++--- utility/TimerZero.cpp | 140 ------------------------------------------ utility/TimerZero.h | 54 ---------------- 3 files changed, 5 insertions(+), 203 deletions(-) delete mode 100644 utility/TimerZero.cpp delete mode 100644 utility/TimerZero.h diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index ef3a0f1c5..2a2834cff 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -33,16 +33,12 @@ Other removed stuff: - unpauseMozzi() - was still declared but not defined -> not usable, anyway - Teensy3/4: channel2sc1a -> thought to be unused, removed - Teensy2: adc_mapping -> hidden away; use adcPinToChannelNum(), as on all other platforms, instead - - removed inclusion of "WProgram.h". If using Arduino versions < 1.0, you need to update, seriously ;-) + - removed several inclusions of "WProgram.h". If using Arduino versions < 1.0, you need to update, seriously ;-) (TODO many, many, instances of this are still around) + - Since Mozzi (AVR-port) no longer uses Timer 0 since a long time, the corresponding library (utility/TimerZero.h) has now been removed, too. + The Arduino functions delay(), millis(), micros() and delayMicroseconds() should now be usable in theory. That said, + you should avoid these functions, as they are slow (or even blocking). For measuring time, refer + to mozziMircos(). For delaying events, you can use Mozzi's EventDelay() unit instead (not to be confused with AudioDelay()). Moved headers: - Header files not meant for user inclusion have been moved to "internal" - New sketches should include "Mozzi.h", rather than "MozziGuts.h", thereby documenting, they have been written for Mozzi 2.0+ - -Documentation bits that still need to find a new home (many other bits were moved around, many, many duplicates merged into a common place, and seom obsoleted bits discarded): - -Contrary to earlier versions of Mozzi, this version does not take over Timer 0, and thus Arduino -functions delay(), millis(), micros() and delayMicroseconds() remain usable in theory. That said, -you should avoid these functions, as they are slow (or even blocking). For measuring time, refer -to mozziMircos(). For delaying events, you can use Mozzi's EventDelay() unit instead -(not to be confused with AudioDelay()). diff --git a/utility/TimerZero.cpp b/utility/TimerZero.cpp deleted file mode 100644 index 9cccc6db3..000000000 --- a/utility/TimerZero.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * TimerZero.cpp - * - * Copyright 2012 Tim Barrass - * - * This file is part of TimerZero, a library for Arduino. - * - * TimerZero is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * TimerZero is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with TimerZero. If not, see . - * - */ - -// Based on TimerTwo, -// downloaded from https://bitbucket.org/johnmccombs, 4/2/2012 -// -// TB2012 added Arduino.h include -// TB2012 replaced Timer 2 prescale factors with ones for Timer 0 -// TB2012 replaced all Timer 2 register names with ones for timer 0 -// TB2012 search/replaced TimerTwo with TimerZero -// TB2012 changed preScale array to suit Timer0 - -// Added by TB2014 for Mozzi library, to hide code from Teensy 3.1 -#if defined (__AVR__) - -#include -#include -#include -#include - -// allowed prescale factors -/* -#define PS1 (1 << CS20) -#define PS8 (1 << CS21) -#define PS32 (1 << CS21) | (1 << CS20) -#define PS64 (1 << CS22) -#define PS128 (1 << CS22) | (1 << CS20) -#define PS256 (1 << CS22) | (1 << CS21) -#define PS1024 (1 << CS22) | (1 << CS21) | (1 << CS20) -*/ -#define PS1 (1 << CS00) -#define PS8 (1 << CS01) -#define PS64 (1 << CS01) | (1 << CS00) -#define PS256 (1 << CS02) -#define PS1024 (1 << CS02) | (1 << CS00) - -// table by prescale = 2^n where n is the table index -static const unsigned char __attribute__((section(".progmem.data"))) preScale[] = - { - PS1, 0, 0, PS8, 0, 0, PS64, 0, PS256, 0, PS1024 - }; - -bool TimerZero::reset_; -void (*TimerZero::f_)(); -unsigned TimerZero::period_; -//------------------------------------------------------------------------------ -// initialize timer 0 -unsigned char TimerZero::init(unsigned usec, void (*f)(), bool reset) -{ - f_ = f; - reset_ = reset; - // assume F_CPU is a multiple of 1000000 - // number of clock ticks to delay usec microseconds - unsigned long ticks = usec * (F_CPU/1000000); - // determine prescale factor and TOP/OCR2A value - // use minimum prescale factor - unsigned char ps, i; - for (i = 0; i < sizeof(preScale); i++) - { - ps = pgm_read_byte(&preScale[i]); - if (ps && (ticks >> i) <= 256) - break; - } - //return error if usec is too large - if (i == sizeof(preScale)) - return false; - period_ = ((long)(ticks >> i) * (1 << i))/ (F_CPU /1000000); - // Serial.println(i, DEC); - // disable timer 0 interrupts - TIMSK0 = 0; - // use system clock (clkI/O) - //ASSR &= ~(1 << AS2); - // Clear Timer on Compare Match (CTC) mode - TCCR0A = (1 << WGM01); - - // only need prescale bits in TCCR0B - TCCR0B = ps; - - // set TOP so timer period is (ticks >> i) - OCR0A = (ticks >> i) - 1; - return true; -} -//------------------------------------------------------------------------------ -// Start timer zero interrupts -void TimerZero::start() -{ - TIMSK0 |= (1 << OCIE0A); -} -//------------------------------------------------------------------------------ -// Stop timer 2 interrupts -void TimerZero::stop() -{ - TIMSK0 = 0; -} -//------------------------------------------------------------------------------ -// ISR for timer 0 Compare A interrupt -// TB2012 added ISR_NOBLOCK so it can be interrupted by Timer 1 (audio) -ISR(TIMER0_COMPA_vect, ISR_NOBLOCK) -{ - // disable timer 0 interrupts - TIMSK0 = 0; - // call user function - (*TimerZero::f_)(); - // in case f_ enabled interrupts - cli(); - // clear counter if reset_ is true - if (TimerZero::reset_) - { - // reset counter - TCNT0 = 0; - // clear possible pending interrupt - TIFR0 |= (1 << OCF0A); - } - // enable timer 2 COMPA interrupt - TIMSK0 |= (1 << OCIE0A); -} - -#endif - - - diff --git a/utility/TimerZero.h b/utility/TimerZero.h deleted file mode 100644 index dff630f5f..000000000 --- a/utility/TimerZero.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * TimerZero.h - * - * Copyright 2012 Tim Barrass, adapted from TimerTwo by John McCombs (date?). - * - * This file is part of TimerZero, a library for Arduino. - * - * TimerZero is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * TimerZero is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with TimerZero. If not, see . - * - */ - -// Based on TimerTwo, -// downloaded from https://bitbucket.org/johnmccombs, 4/2/2012 -// -// TB2012 search/replaced TimerTwo with TimerZero - -#ifndef TimerZero_h -#define TimerZero_h - -namespace TimerZero -{ -extern unsigned period_; -// timer reset flag -extern bool reset_; -// user function -extern void (*f_)(); -// call f every usec microseconds if reset == false -// call f after delay of usec microseconds from call return if reset == true -// max delay is 256*1024 clock cycles or 16,384 microseconds for a 16 MHz CPU -unsigned char init(unsigned usec, void (*f)(), bool reset = false); -// period in usec -inline unsigned period() -{ - return period_; -} -// start calls -void start(); -// stop calls -void stop(); -} - -#endif // TimerZero - From 5e61065af3ec500a3f5c942d6cf292d889b37a86 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 15:14:17 +0100 Subject: [PATCH 078/215] Bye bye mozzi_config.h, hello inline configuration! Adjusted two of the stereo examples for starters --- AudioOutput.h | 8 +++---- MozziGuts.h | 5 +---- .../Stereo_Hack.ino => Stereo/Stereo.ino} | 13 ++++++++--- .../Stereo_Pan.ino} | 13 ++++++++--- extras/devscripts/mozzi_release_step1.sh | 22 ------------------- extras/devscripts/mozzi_release_step2.sh | 18 --------------- internal/teensyPinMap.h | 4 ---- mozzi_config.h | 18 --------------- 8 files changed, 25 insertions(+), 76 deletions(-) rename examples/12.Misc/{Stereo_Hack/Stereo_Hack.ino => Stereo/Stereo.ino} (71%) rename examples/12.Misc/{Stereo_Hack_Pan/Stereo_Hack_Pan.ino => Stereo_Pan/Stereo_Pan.ino} (79%) delete mode 100644 mozzi_config.h diff --git a/AudioOutput.h b/AudioOutput.h index 0fc3b3f94..47040b665 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -40,10 +40,8 @@ * @see MonoOutput::fromNBit(), StereoOutput::fromNBit() */ -#ifndef AUDIOOUTPUT -#define AUDIOOUTPUT - -#include "mozzi_config.h" +#ifndef AUDIOOUTPUT_H +#define AUDIOOUTPUT_H /** The type used to store a single channel of a single frame, internally. For compatibility with earlier versions of Mozzi this is defined as int. * If you do not care about keeping old sketches working, you may be able to save some RAM by using int16_t, instead (on boards where int is larger @@ -172,9 +170,11 @@ struct MonoOutput { }; +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) /** When setting using one of the external output modes (@ref MOZZI_OUTPUT_EXTERNAL_TIMED or @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM) implement this function to take care of writing samples to the hardware. * In all otther cases, it will be provided by the platform implementation. You should never call this function, directly, in your sketch. */ void audioOutput(const AudioOutput f); +#endif #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) /** For @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM implement this function to return true, if and only if your hardware (or custom buffer) is ready to accept the next sample. */ inline bool canBufferAudioOutput(); diff --git a/MozziGuts.h b/MozziGuts.h index 4919f4482..7629abe66 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -22,18 +22,15 @@ #endif #include "hardware_defines.h" -#include "mozzi_config.h" #if IS_TEENSY3() || IS_TEENSY4() // required from http://github.com/pedvide/ADC for Teensy 3.* #include #endif -#include "mozzi_analog.h" - - #include "internal/config_checks_generic.h" +#include "mozzi_analog.h" #include "AudioOutput.h" // TODO Mozzi 2.0: These typedef probably obsolete? diff --git a/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino b/examples/12.Misc/Stereo/Stereo.ino similarity index 71% rename from examples/12.Misc/Stereo_Hack/Stereo_Hack.ino rename to examples/12.Misc/Stereo/Stereo.ino index 2db36b1db..257b4c0ba 100644 --- a/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino +++ b/examples/12.Misc/Stereo/Stereo.ino @@ -1,9 +1,11 @@ -/* Example crudely panning noise to test stereo output hack, +/* Example crudely panning noise to test stereo output, * using Mozzi sonification library. * - * Tests stereo output. This requires #define AUDIO_CHANNELS STEREO in mozzi_config.h + * Tests stereo output. * - * Circuit: Audio outputs on digital pins 9 and 10. + * NOTE: Stereo output is not supported on all platforms / configurations! + * + * Circuit: Audio outputs on digital pins 9 and 10 (on classic Arduino). * * Mozzi help/discussion/announcements: * https://groups.google.com/forum/#!forum/mozzi-users @@ -12,6 +14,11 @@ * This example code is in the public domain. */ +// Configure Mozzi for Stereo output. This must be done before #include +// MozziConfigValues.h provides named defines for available config options. +#include +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO + #include #include // for controlling panning position #include // oscil for audio sig diff --git a/examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino similarity index 79% rename from examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino rename to examples/12.Misc/Stereo_Pan/Stereo_Pan.ino index 0808f6c29..4f1e14ee5 100644 --- a/examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino +++ b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino @@ -1,9 +1,11 @@ /* Example of constant power panning to test stereo output hack, using Mozzi sonification library. - Tests stereo output. This requires #define AUDIO_CHANNELS STEREO in mozzi_config.h + Tests stereo output. - Circuit: Audio outputs on digital pins 9 and 10. + NOTE: Stereo output is not supported on all platforms / configurations! + + Circuit: Audio outputs on digital pins 9 and 10 (on classic Arduino). Mozzi documentation/API https://sensorium.github.io/Mozzi/doc/html/index.html @@ -15,6 +17,11 @@ This example code is in the public domain. */ +// Configure Mozzi for Stereo output. This must be done before #include +// MozziConfigValues.h provides named defines for available config options. +#include +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO + #include #include // oscil for audio sig #include // table for audio oscillator @@ -57,4 +64,4 @@ AudioOutput_t updateAudio() { void loop() { audioHook(); // required here -} \ No newline at end of file +} diff --git a/extras/devscripts/mozzi_release_step1.sh b/extras/devscripts/mozzi_release_step1.sh index adf063a09..1e0b6ca9a 100644 --- a/extras/devscripts/mozzi_release_step1.sh +++ b/extras/devscripts/mozzi_release_step1.sh @@ -16,31 +16,9 @@ cp -a ~/Mozzi/examples ~/Documents/Arduino/mozzi_compile/ #cd mozzi_compile/examples cd ~/Documents/Arduino/mozzi_compile/examples/ -# change mozzi config to STANDARD_PLUS, make sure STANDARD is commented -sed -i.bak 's/^#define AUDIO_MODE STANDARD/\/\/#define AUDIO_MODE STANDARD/' ~/Mozzi/mozzi_config.h -# make sure STANDARD_PLUS is uncommented, ^ matches start of line -sed -i.bak 's/\/\/#define AUDIO_MODE STANDARD_PLUS/#define AUDIO_MODE STANDARD_PLUS/' ~/Mozzi/mozzi_config.h - -# make sure STANDARD is commented, ^ matches start of line -#sed -i.bak 's/^#define AUDIO_MODE STANDARD/\/\/#define AUDIO_MODE STANDARD/' ~/Mozzi/mozzi_config.h -# change mozzi config to STANDARD_PLUS, make sure STANDARD_PLUS is uncommented -#sed -i.bak 's/\/\/#define AUDIO_MODE STANDARD_PLUS/#define AUDIO_MODE STANDARD_PLUS/' ~/Mozzi/mozzi_config.h - -# make sure HIFI is commented, ^ matches start of line -sed -i.bak 's/^#define AUDIO_MODE HIFI/\/\/#define AUDIO_MODE HIFI/' ~/Mozzi/mozzi_config.h - - #compile and record STANDARD examples ~/bin/mozzi_compile_examples.sh -#change mozzi config to HIFI -# make sure HIFI is uncommented -sed -i.bak 's/\/\/#define AUDIO_MODE HIFI/#define AUDIO_MODE HIFI/' ~/Mozzi/mozzi_config.h -# make sure STANDARD is commented, ^ matches start of line -sed -i.bak 's/^#define AUDIO_MODE STANDARD/\/\/#define AUDIO_MODE STANDARD/' ~/Mozzi/mozzi_config.h -# make sure STANDARD_PLUS is commented, ^ matches start of line -sed -i.bak 's/^#define AUDIO_MODE STANDARD_PLUS/\/\/#define AUDIO_MODE STANDARD_PLUS/' ~/Mozzi/mozzi_config.h - #compile and record HIFI examples ~/bin/mozzi_compile_examples_hifi.sh diff --git a/extras/devscripts/mozzi_release_step2.sh b/extras/devscripts/mozzi_release_step2.sh index b9196031e..d971587e7 100644 --- a/extras/devscripts/mozzi_release_step2.sh +++ b/extras/devscripts/mozzi_release_step2.sh @@ -4,24 +4,6 @@ NOW=$(date +"%Y-%m-%d-%H:%M") -#ensure STANDARD config again -# uncomment STANDARD -#sed -i.bak 's/\/\/#define AUDIO_MODE STANDARD/#define AUDIO_MODE STANDARD/' ~/Mozzi/mozzi_config.h -# comment HIFI, ^ matches start of line -#sed -i.bak 's/^#define AUDIO_MODE HIFI/\/\/#define AUDIO_MODE HIFI/' ~/Mozzi/mozzi_config.h - -# make sure STANDARD is commented, ^ matches start of line -sed -i.bak 's/^#define AUDIO_MODE STANDARD/\/\/#define AUDIO_MODE STANDARD/' ~/Mozzi/mozzi_config.h -# change mozzi config to STANDARD_PLUS, make sure STANDARD_PLUS is uncommented -sed -i.bak 's/\/\/#define AUDIO_MODE STANDARD_PLUS/#define AUDIO_MODE STANDARD_PLUS/' ~/Mozzi/mozzi_config.h -# make sure HIFI is commented, ^ matches start of line -sed -i.bak 's/^#define AUDIO_MODE HIFI/\/\/#define AUDIO_MODE HIFI/' ~/Mozzi/mozzi_config.h - - -# make sure audio input is off -sed -i.bak 's/#define USE_AUDIO_INPUT true/#define USE_AUDIO_INPUT false/' ~/Mozzi/mozzi_config.h - - #delete wav files find ~/Documents/Arduino/mozzi_compile/examples -name "*.wav" -print -delete diff --git a/internal/teensyPinMap.h b/internal/teensyPinMap.h index 6904e124a..1f028115e 100644 --- a/internal/teensyPinMap.h +++ b/internal/teensyPinMap.h @@ -13,10 +13,6 @@ #define TEENSYPINMAP_H -#include "mozzi_config.h" - - - inline uint8_t teensyPinMap(uint8_t pin) { if (pin < 24) return pin-14; // common to all teensys diff --git a/mozzi_config.h b/mozzi_config.h deleted file mode 100644 index ead877179..000000000 --- a/mozzi_config.h +++ /dev/null @@ -1,18 +0,0 @@ -/** TODO: Temporarily brought back to life for testing config rework. - * - * This file is not meant to stay, but removing it for good requirs the "single compilation unit". - * - * At the moment it can be used to quickly configure some options to non-default values, as shown in the commented exampales. - * Alternatively, one can include a config_examples_xyz.h file from here. - */ - -#include "MozziConfigValues.h" - -//#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM -//#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO -//#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE - -//#include "config/config_example_avr_legacy_standard.h" - -#include "internal/config_checks_generic.h" - From 6b4c2c9cdf90ff9024cf539afe6135cbac81faf7 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 18:32:48 +0100 Subject: [PATCH 079/215] Trick doxygen into showing more of the existing documentation. Doxygen still ignores quite a bit of existing stuff. Importantly, apparently, we need to @defgroup all groups before using them, and define all documented preprocessor tokens (documenting them, alone, is not enough). --- AudioOutput.h | 8 +- IntegerType.h | 2 + MozziGuts.h | 1 + config/mozzi_config_documentation.h | 55 +++++- extras/doxygen-style/Doxyfile | 10 +- extras/doxygen-style/DoxygenLayout.xml | 226 +++++++++++++++++++++++++ internal/config_checks_avr.h | 6 +- 7 files changed, 292 insertions(+), 16 deletions(-) create mode 100644 extras/doxygen-style/DoxygenLayout.xml diff --git a/AudioOutput.h b/AudioOutput.h index 0fc3b3f94..668d2f69d 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -1,4 +1,8 @@ -/** @ingroup conre +/** @defgroup audio_output Audio Output and Buffering + * + * @details Documentation on basic Mozzi architecture and output modes */ + +/** @ingroup audio_output * @page mozzi_audio_output_architecture Basic architecture of audio generation, buffering, and output in Mozzi * * Mozzi provides support for audio ouput on a range of different boards and CPUs. This page is about the following related topics: @@ -26,7 +30,7 @@ * have to provide a custom definition of canBufferAudioOutput(), returning true, whenever a new sample of output can be accepted. No timer at audio-rate is set up in this * case. * - * Finally, the @ref external_audio output mode @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM is essentially a combination of the two. Here, the user sketch needs to provide + * Finally, the @ref external_audio output mode (@ref MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM) is essentially a combination of the two. Here, the user sketch needs to provide * both audioOutput() and canBufferAudioOutput(). The latter is again called from audioHook(), and whenever it returns true, a new sample is generated and passed to * audioOutput(). * diff --git a/IntegerType.h b/IntegerType.h index 053c62443..b8af4d341 100644 --- a/IntegerType.h +++ b/IntegerType.h @@ -1,6 +1,8 @@ #ifndef INTTYPE_H_ #define INTTYPE_H_ +#include + template struct IntegerType { // at an odd value, such as 3 bytes? Add one more byte (up to at most 8 bytes).. typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::unsigned_type unsigned_type; diff --git a/MozziGuts.h b/MozziGuts.h index 0056c51ca..cc42c32fa 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -57,6 +57,7 @@ typedef signed long int32_t; // Other supported arches add typedefs, here, unless already defined for that platform needed #endif +/*! @defgroup core Mozzi Core Functions /** @ingroup core Sets up the timers for audio and control rate processes, storing the timer diff --git a/config/mozzi_config_documentation.h b/config/mozzi_config_documentation.h index b9c0eb538..18407df75 100644 --- a/config/mozzi_config_documentation.h +++ b/config/mozzi_config_documentation.h @@ -1,8 +1,14 @@ +#ifdef FOR_DOXYGEN_ONLY +/** @file */ + /*! @defgroup config Mozzi Configuration options - * @section Mozzi Configuration - * * @brief Mozzi Configuration * + * @section config_general Configuring Mozzi + * + * Mozzi configuration options include details such as audio rate, number of audio channels (mono or stereo), output generation method and many others, + * where details on the available options differ between the different platforms (see @ref hardware), and may include additional options beyond those listed, here. + * * @note * It is generally safe to leave the Mozzi Configuration unchanged, and that's very much recommended _until_ you have a very specific need to customize something. * Contrary to past versions of Mozzi, all configuration options have a (usually sensible) default value, so you do not have to configure _anything_, unless you @@ -12,7 +18,23 @@ * to save Flash, RAM, and CPU use at runtime. This section lists various global options, but in addition, most ports allow additional hardware dependent * configuration options. See @ref hardware. * - * Several configuration examples are provided in the "config" folder of the Mozzi sources. You may want to look at these, first. + * Several configuration examples are provided in the "config" folder of the Mozzi sources. You may want to look at these, first. The general approach is as follows: + * + * @code + * #include // include this first, for named option values + * #define MOZZI_AUDIO_CHANNELS MOZZI_STEREO // set to stereo mode + * + * #include // *after* all configuration options, include the main Mozzi headers + * @endcode + * + * Alternatively, if a suitable configuration example exists, use: + * @code + * #include // again, do this, before including the main headers + * @endcode + * + * @note + * Should you include Mozzi headers in more than one compilation unit (i.e. more than one .cpp file) inside the same sketch, you *must* use identical + * configuration options at the top of each file! * * TODO: Fix and complete Doxygen coverage */ @@ -32,6 +54,7 @@ * @note * MOZZI_COMPATIBILITY_V1_1 does not guarantee, that *everything* from Mozzi 1.1 will continue to work, just that we're doing a reasonable effort. */ +#define MOZZI_COMPATIBILITY_LEVEL FOR_DOXYGEN_ONLY /** @ingroup config * @def MOZZI_AUDIO_MODE @@ -62,7 +85,7 @@ * * TODO: Adding an R2R-DAC option would be cool, http://blog.makezine.com/2008/05/29/makeit-protodac-shield-fo/ , some discussion on Mozzi-users. */ - +#define MOZZI_AUDIO_MODE FOR_DOXYGEN_ONLY /** @ingroup config * @def MOZZI_AUDIO_CHANNELS @@ -79,6 +102,7 @@ * @note At the time of this writing, only MOZZI_MONO and MOZZI_STEREO are supported. The value of * MOZZI_MONO is 1 and the value of MOZZI_STEREO is 2, so future extensions are also expected * to set this to the number of available channels, and it's ok to use numerical comparison. */ +#define MOZZI_AUDIO_CHANNELS FOR_DOXYGEN_ONLY /** @ingroup config @@ -101,7 +125,7 @@ * It is advised to use only MOZZI_AUDIO_RATE in new code, however. * TODO: Only do the above, if MozziGuts.h, rather than Mozzi.h was included? */ - +#define MOZZI_AUDIO_RATE FOR_DOXYGEN_ONLY /** @ingroup config @@ -120,6 +144,7 @@ * * TODO: If a definition of CONTROL_RATE is detected, apply that with a warning. */ +#define MOZZI_CONTROL_RATE FOR_DOXYGEN_ONLY /** @ingroup config @@ -140,6 +165,7 @@ * - MOZZI_ANALOG_READ_STANDARD * Analog read implementation enabled (currently there is only the "standard" method, but future versions might allow additional choice, here). */ +#define MOZZI_ANALOG_READ FOR_DOXYGEN_ONLY /** @ingroup config @@ -158,6 +184,7 @@ * * Further reading and config: @ref getAudioInput() @ref MOZZI_AUDIO_INPUT_PIN */ +#define MOZZI_AUDIO_INPUT FOR_DOXYGEN_ONLY /** @ingroup config @@ -166,6 +193,8 @@ * This sets which analog input channel to use for audio input, if you have enabled MOZZI_AUDIO_INPUT, above. * Not all pins may be available for this, be sure to check the documentation for your platform. */ +#define MOZZI_AUDIO_INPUT_PIN FOR_DOXYGEN_ONLY + /** @ingroup config * @def MOZZI_PWM_RATE @@ -179,6 +208,8 @@ * In other words, increasing this improves the signal quality at less cost than doubling the audio rate itself. However, increasing this too far will limit the dynamic resolution of the samples that can be * written to the output pin(s): 2 ^ (output bits) * MOZZI_PWM_RATE cannot be higher than the CPU frequency! */ +#define MOZZI_PWM_RATE FOR_DOXYGEN_ONLY + /** @ingroup config * @def MOZZI_AUDIO_BITS_PER_CHANNEL @@ -188,6 +219,8 @@ * * See @ref hardware_avr for a more detailed description. */ +#define MOZZI_AUDIO_BITS_PER_CHANNEL FOR_DOXYGEN_ONLY + /** @ingroup config * @def MOZZI_AUDIO_PIN_1 @@ -213,6 +246,7 @@ * * @see config/known_16bit_timers.h * */ +#define MOZZI_AUDIO_PIN_1 FOR_DOXYGEN_ONLY /***************************************** ADVANCED SETTTINGS -- External audio output ****************************************** @@ -221,10 +255,11 @@ * ********************************************************************************************************************************/ -/** @ingroup hardware - * @page external_audio External audio output +/** @ingroup audio_output * - * Only for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM. Most (all?) platforms support + * @page external_audio External audio output + * @details + * Only for @ref MOZZI_AUDIO_MODE set to MOZZI_OUTPUT_EXTERNAL_TIMED or MOZZI_OUTPUT_EXTERNAL_CUSTOM. Most (all?) platforms support * output using an "external" function. When using this option, you will need to provide a suitable definition for audioOutput() in * your own sketch, yourself. Some understanding of the general Mozzi audio output architecture may be recommendable, when using this * mode: See @ref AudioOutput . @@ -241,6 +276,8 @@ * * One additional configuration setting is MOZZI_AUDIO_BITS, which defaults to 16 bits for this mode, but might be set higher, if your * hardware supports it. + * + * @see config */ @@ -255,4 +292,6 @@ * At the time of this writng single audio samples are stored as "int", unconditionally. This limits MOZZI_AUDIO_BITS to a maximum of 16 bits on * some 8 bit boards! */ +#define MOZZI_AUDIO_BITS FOR_DOXYGEN_ONLY +#endif diff --git a/extras/doxygen-style/Doxyfile b/extras/doxygen-style/Doxyfile index af8960c83..b276ad07b 100644 --- a/extras/doxygen-style/Doxyfile +++ b/extras/doxygen-style/Doxyfile @@ -660,7 +660,7 @@ ENABLED_SECTIONS = # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. -MAX_INITIALIZER_LINES = 30 +MAX_INITIALIZER_LINES = 0 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the @@ -704,7 +704,7 @@ FILE_VERSION_FILTER = # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. -LAYOUT_FILE = +LAYOUT_FILE = DoxygenLayout.xml # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib @@ -2076,7 +2076,7 @@ ENABLE_PREPROCESSING = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and @@ -2084,7 +2084,7 @@ MACRO_EXPANSION = NO # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. @@ -2116,7 +2116,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = FOR_DOXYGEN_ONLY # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/extras/doxygen-style/DoxygenLayout.xml b/extras/doxygen-style/DoxygenLayout.xml new file mode 100644 index 000000000..a922eddc3 --- /dev/null +++ b/extras/doxygen-style/DoxygenLayout.xml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index 70163c880..18454f219 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -1,4 +1,8 @@ -/** For Mozzi-internal use: Apply hardware specific config defaults and config checks: AVR */ +/* For Mozzi-internal use: Apply hardware specific config defaults and config checks: AVR */ + +/** @defgroup hardware + * + * @details This page details hardware specific notes, and availabe configuration options for the various platforms. */ /** @ingroup hardware * @page hardware_avr Mozzi on classic Arduino, Teensy 2.x, Arduino Mega, and other 8 bit "AVR"/ATMEGA architecture boards From f0bdae2e3d369b89ce8cd13e39548aca6b58f35f Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 19:05:09 +0100 Subject: [PATCH 080/215] Bring back the groups that doxygen (1.9?) has dropped --- AutoMap.h | 3 +++ IntegerType.h | 3 +++ config/mozzi_config_documentation.h | 6 ++++-- meta.h | 2 ++ mozzi_analog.h | 2 ++ mozzi_fixmath.h | 4 +++- 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/AutoMap.h b/AutoMap.h index ff9aef13f..9e2bec1c3 100644 --- a/AutoMap.h +++ b/AutoMap.h @@ -21,6 +21,9 @@ #include "AutoRange.h" +/** @defgroup sensortools Automatic range adjustment +*/ + /** @ingroup sensortools Automatically map an input value to an output range without knowing the precise range of inputs beforehand. */ diff --git a/IntegerType.h b/IntegerType.h index b8af4d341..47c944a0f 100644 --- a/IntegerType.h +++ b/IntegerType.h @@ -3,6 +3,9 @@ #include +/** @ingroup util +Provides appropriate integer types that can bit the given number of bytes on this platform (at most 64). +*/ template struct IntegerType { // at an odd value, such as 3 bytes? Add one more byte (up to at most 8 bytes).. typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::unsigned_type unsigned_type; diff --git a/config/mozzi_config_documentation.h b/config/mozzi_config_documentation.h index 20686508f..523e1508b 100644 --- a/config/mozzi_config_documentation.h +++ b/config/mozzi_config_documentation.h @@ -1,8 +1,10 @@ #ifdef FOR_DOXYGEN_ONLY /** @file */ -/*! @defgroup config Mozzi Configuration options - * @brief Mozzi Configuration +/*! @defgroup config Mozzi Configuration options */ + +/** @ingroup config + * @page config_main Mozzi Configuration * * @section config_general Configuring Mozzi * diff --git a/meta.h b/meta.h index 85f99cc5b..0682bb6a6 100644 --- a/meta.h +++ b/meta.h @@ -6,6 +6,8 @@ Template meta-programming extras. #ifndef META_H_ #define META_H_ +/** @defgroup util Assorted meta-programming utils +*/ /** @ingroup util Enables you to instantiate a template based on an integer value. diff --git a/mozzi_analog.h b/mozzi_analog.h index 57eb221c6..943dbb798 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -19,6 +19,8 @@ // for setupFastAnalogRead() enum ANALOG_READ_SPEED {FAST_ADC,FASTER_ADC,FASTEST_ADC}; +/** @defgroup analog Functions for taking (non-blocking) analog readings. */ + /** @ingroup analog This is automatically called in startMozzi. diff --git a/mozzi_fixmath.h b/mozzi_fixmath.h index 69c1d7a85..b2f1574ed 100644 --- a/mozzi_fixmath.h +++ b/mozzi_fixmath.h @@ -18,7 +18,9 @@ #include "WProgram.h" #endif -/**@ingroup fixmath +/** @defgroup fixmath Fast integer based fixed-point arithmetic */ + +/** @ingroup fixmath @{ */ // types From c9d7c2b4763f4c8bb73cb112e703d4b44564b0db Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 20:29:11 +0100 Subject: [PATCH 081/215] Convert external audio examples to in-line config --- .../FMsynth_MCP4921_mono_12bits.ino | 8 ++++++-- .../MCP4922_mono_24bits.ino | 11 ++++++----- .../PT8211_stereo_16bits.ino | 19 +++++++------------ .../PT8211_stereo_16bits_STM32_SPI2.ino | 11 ++++------- .../Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino | 19 ++++++++----------- .../Sinewave_R2R_DAC_74HC595.ino | 19 +++++++------------ .../Stereo_Pan_MCP4922_stereo_12bits.ino | 18 ++++++++---------- internal/MozziGuts.hpp | 8 ++++++++ internal/MozziGuts_impl_AVR.hpp | 4 ++-- internal/config_checks_avr.h | 8 +++++--- 10 files changed, 61 insertions(+), 64 deletions(-) diff --git a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino index d3ffabb37..c9734bb37 100644 --- a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino +++ b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino @@ -3,8 +3,6 @@ using an user-defined audioOutput() function. Based on Mozzi's example: FMsynth. - #define EXTERNAL_AUDIO_OUTPUT true should be uncommented in mozzi_config.h. - Circuit: (see the DAC library README for details) MCP4921 // Connect to: @@ -29,6 +27,12 @@ T. Combriat 2020, CC by-nc-sa. */ +// before including Mozzi.h, configure external audio output mode: +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +// Note: For demonstration purposes, this sketch does *not* set the following (although it would make sense): +//#define MOZZI_AUDIO_BITS 12 // the default value of 16 for external audio is thus used, instead + #include #include #include // table for Oscils to play diff --git a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino index 96c505a79..a590e21a2 100644 --- a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino +++ b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino @@ -4,9 +4,6 @@ WARNING: YOU CANNOT ACHEIVE MORE THAN 16BITS ON AN AVR ARDUINO, THIS EXAMPLE WON'T WORK AS IT IS. - #define EXTERNAL_AUDIO_OUTPUT true should be uncommented in mozzi_config.h. - #define EXTERNAL_AUDIO_BITS 24 should be set in mozzi_config.h - Circuit: (see the DAC library README for details) MCP4921 // Connect to: @@ -50,6 +47,11 @@ T. Combriat 2020, CC by-nc-sa. */ +// before including Mozzi.h, configure external audio output mode: +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +#define MOZZI_AUDIO_BITS 24 + #include #include #include // table for Oscils to play @@ -71,7 +73,6 @@ Oscil kEnv1(COS2048_DATA); // External audio output parameters and DAC declaration #define SS_PIN 38 // if you are on AVR and using PortWrite you need still need to put the pin you are actually using: 7 on Uno, 38 on Mega -//#define AUDIO_BIAS 8388608 // we are at 24 bits, so we have to bias the signal of 2^(24-1) = 8388608 (not needed since PR #98) #define BITS_PER_CHANNEL 12 // each channel of the DAC is outputting 12 bits DAC_MCP49xx dac(DAC_MCP49xx::MCP4922, SS_PIN); @@ -80,7 +81,7 @@ DAC_MCP49xx dac(DAC_MCP49xx::MCP4922, SS_PIN); void audioOutput(const AudioOutput f) // f is a structure containing both channels { - int out = AUDIO_BIAS + f.l(); + int out = MOZZI_AUDIO_BIAS + f.l(); unsigned short lowBits = (unsigned short) out; // unsigned short highBits = out >> BITS_PER_CHANNEL; diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino index 258c74f41..20664d4d1 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino @@ -5,10 +5,6 @@ using an user-defined audioOutput() function. I2S, the protocol used by this DAC, is here emulated in synced way using SPI. - #define EXTERNAL_AUDIO_OUTPUT true should be uncommented in mozzi_config.h. - #define AUDIO_CHANNELS STEREO should be set in mozzi_config.h - - Circuit: PT8211 // Connect to: @@ -30,13 +26,17 @@ T. Combriat 2020, CC by-nc-sa. */ +// before including Mozzi.h, configure external audio output mode: +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO +#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable + #include #include #include // table for Oscils to play #include -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - // Synthesis part Oscil aCos1(COS2048_DATA); @@ -50,11 +50,6 @@ Oscil kEnv2(COS2048_DATA); // External audio output parameters #define WS_pin 5 // channel select pin for the DAC -//#define AUDIO_BIAS 0 // this DAC works on 0-centered signals - - - - @@ -67,7 +62,7 @@ void audioOutput(const AudioOutput f) // f is a structure containing both channe */ digitalWrite(WS_pin, LOW); //select Right channel - SPI.transfer16(f.r()); + SPI.transfer16(f.r()); // Note: This DAC works on 0-centered samples, no need to add MOZZI_AUDIO_BIAS digitalWrite(WS_pin, HIGH); // select Left channel SPI.transfer16(f.l()); diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino index e9b8eb751..1904cc1c7 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino @@ -4,11 +4,6 @@ using Mozzi sonification library and an external dual DAC PT8211 (inspired by: https://sparklogic.ru/code-snipplets/i2s-example-code.html) using an user-defined audioOutput() function. I2S, the protocol used by this DAC, is here emulated in synced way using SPI. - - #define EXTERNAL_AUDIO_OUTPUT true should be uncommented in mozzi_config.h. - #define AUDIO_CHANNELS STEREO should be set in mozzi_config.h - - Circuit: PT8211 // Connect to: @@ -29,6 +24,9 @@ Tim Barrass 2012, CC by-nc-sa. T. Combriat 2020, CC by-nc-sa. */ +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO #include #include @@ -50,7 +48,6 @@ Oscil kEnv2(COS2048_DATA); // External audio output parameters #define WS_pin PB12 // channel select pin for the DAC -//#define AUDIO_BIAS 0 // this DAC works on 0-centered signals SPIClass mySPI(2); // declaration of SPI for using SPI2 and thus freeing all ADC pins @@ -60,7 +57,7 @@ SPIClass mySPI(2); // declaration of SPI for using SPI2 and thus freeing all void audioOutput(const AudioOutput f) // f is a structure containing both channels { digitalWrite(WS_pin, LOW); //select Right channel - mySPI.transfer16(f.r()); + mySPI.transfer16(f.r()); // Note: This DAC works on 0-centered samples, no need to add MOZZI_AUDIO_BIAS digitalWrite(WS_pin, HIGH); // select Left channel mySPI.transfer16(f.l()); diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino index dfa5635a7..716824085 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino @@ -2,9 +2,6 @@ using Mozzi sonification library and an user-defined audioOutput() function. - #define EXTERNAL_AUDIO_OUTPUT true should be uncommented in mozzi_config.h. - #define EXTERNAL_AUDIO_BITS 6 should be set in mozzi_config.h (you can increase that if you want, but will need to increase the number of step of the ladder accordingly). - Demonstrates the use of audioOutput() using a R/2R DAC connected on 6 digital pins of an Arduino. @@ -42,6 +39,11 @@ T. Combriat 2020, CC by-nc-sa. */ +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +#define MOZZI_AUDIO_BITS 6 +#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable + #include #include // oscillator template #include // sine table for oscillator @@ -49,22 +51,17 @@ // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aSin(SIN2048_DATA); -// use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - - - // External output parameters for this example -#define R2R_N_PIN EXTERNAL_AUDIO_BITS // Number of stage of the resistance ladder = number of digits of the DAC, can be defined through EXTERNAL_AUDIO_BITS in mozzi_config.h +#define R2R_N_PIN MOZZI_AUDIO_BITS // Number of stage of the resistance ladder = number of digits of the DAC, can be defined through MOZZI_AUDIO_BITS const int r2r_pin[R2R_N_PIN] = {30, 31, 32, 33, 34, 35}; // pins to the resistance ladder, in order, // starting with LSB (pin closer to GND) // so D0, D1, etc. //#define AUDIO_BIAS 32 // we are at 6 bits so we have to bias the signal of 2^(6-1)=32, not needed since PR#98 -void audioOutput(const AudioOutput f) // f is a structure potentially containing both channels, scaled according to EXTERNAL_AUDIO_BITS +void audioOutput(const AudioOutput f) // f is a structure potentially containing both channels, scaled according to MOZZI_AUDIO_BITS { - int out = f.l() + AUDIO_BIAS; // get the audio and make it positive + int out = f.l() + MOZZI_AUDIO_BIAS; // get the audio and make it positive int mask = 0b00000001; // mask for outputting only 1 bit (one per pin) for (int i = 0; i < R2R_N_PIN; i++) { diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino index 3b2e95d93..9b06cb232 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino @@ -2,9 +2,6 @@ using Mozzi sonification library and an user-defined audioOutput() function. - #define EXTERNAL_AUDIO_OUTPUT true should be uncommented in mozzi_config.h. - #define EXTERNAL_AUDIO_BITS 8 should be set in mozzi_config.h, as the 74HC595 has 8 outputs. - Demonstrates the use of audioOutput() using a R/2R DAC connected on a shift register 74HC595. @@ -47,6 +44,11 @@ T. Combriat 2020, CC by-nc-sa. */ +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +#define MOZZI_AUDIO_BITS 8 +#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable + #include #include // oscillator template #include // sine table for oscillator @@ -55,19 +57,12 @@ // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aSin(SIN2048_DATA); -// use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - - - // External output parameters for this example #define LATCH_PIN 31 // Number of stage of the resistance ladder = number of digits of the DAC -//#define AUDIO_BIAS 128 // not needed since PR#98 - -void audioOutput(const AudioOutput f) // f is a structure potentially containing both channels, scaled according to EXTERNAL_AUDIO_BITS +void audioOutput(const AudioOutput f) // f is a structure potentially containing both channels, scaled according to MOZZI_AUDIO_BITS { - int out = f.l() + AUDIO_BIAS; // make the signal positive + int out = f.l() + MOZZI_AUDIO_BIAS; // make the (zero centered) signal positive digitalWrite(LATCH_PIN, LOW); SPI.transfer(out); digitalWrite(LATCH_PIN, HIGH); diff --git a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino index 3beb39f78..61e4e3c9a 100644 --- a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino +++ b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino @@ -2,12 +2,6 @@ using Mozzi sonification library and an external dual DAC MCP4922 (original library by Thomas Backman - https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx) using an user-defined audioOutput() function. - - #define EXTERNAL_AUDIO_OUTPUT true should be uncommented in mozzi_config.h. - #define AUDIO_CHANNELS STEREO should be set in mozzi_config.h - - - Circuit: (see the DAC library README for details) MCP4921 // Connect to: @@ -32,6 +26,12 @@ T. Combriat 2020, CC by-nc-sa. */ +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO +#define MOZZI_AUDIO_BITS 12 +#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable + #include #include #include // table for Oscils to play @@ -39,8 +39,6 @@ #include // https://github.com/tomcombriat/DAC_MCP49XX // which is an adapted fork from https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx (Thomas Backman) -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - // Synthesis part Oscil aCos1(COS2048_DATA); @@ -60,8 +58,8 @@ DAC_MCP49xx dac(DAC_MCP49xx::MCP4922, SS_PIN); void audioOutput(const AudioOutput f) // f is a structure containing both channels { - int out_l = f.l() + AUDIO_BIAS; // the DAC wants positive signals only, so we need to add a bias. - int out_r = f.r() + AUDIO_BIAS; + int out_l = f.l() + MOZZI_AUDIO_BIAS; // the DAC wants positive signals only, so we need to add a bias. + int out_r = f.r() + MOZZI_AUDIO_BIAS; dac.output2(out_l, out_r); // outputs the two channels in one call. diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 4ce3c0f8f..7b00c7029 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -309,3 +309,11 @@ void setupFastAnalogRead(int8_t speed) { MozziPrivate::setupFastAnalogRead(speed uint8_t adcPinToChannelNum(uint8_t pin) { return MozziPrivate::adcPinToChannelNum(pin); }; #endif void audioHook() { MozziPrivate::audioHook(); }; + +// This is not strictly needed, but we want it to throw an error, if users have audioOutput() in their sketch without external output configured +#if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) +MOZZI_DEPRECATED("n/a", "Sketch has audioOutput() function, although external output is not configured.") void audioOutput(const AudioOutput) {}; +#endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) +MOZZI_DEPRECATED("n/a", "Sketch has canBufferAudioOutput() function, although custom external output is not configured.") bool canBufferAudioOutput() {}; +#endif diff --git a/internal/MozziGuts_impl_AVR.hpp b/internal/MozziGuts_impl_AVR.hpp index 3053cb559..8b0c71ea2 100644 --- a/internal/MozziGuts_impl_AVR.hpp +++ b/internal/MozziGuts_impl_AVR.hpp @@ -194,7 +194,7 @@ static void startAudio() { } // namespace MozziPrivate ISR(TIMER1_OVF_vect, ISR_BLOCK) { - defaultAudioOutput(); + MozziPrivate::defaultAudioOutput(); } namespace MozziPrivate { @@ -247,7 +247,7 @@ ISR(TIMER1_OVF_vect, ISR_BLOCK) { if (alternate) return; # endif - MozziPrivate::defaultAudioOutput(); + MozziPrivate::defaultAudioOutput(); } namespace MozziPrivate { diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index 18454f219..424eb96fa 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -156,9 +156,11 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_RATE, 16384, 32768) MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD) #include "../config/known_16bit_timers.h" -#if defined(TIMER1_C_PIN) + +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM) +# if defined(TIMER1_C_PIN) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN, TIMER1_C_PIN); -#else +# else MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN); +# endif #endif - From 0eb96c63dfc306017e278e6ad24531f84e433f49 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 22:41:39 +0100 Subject: [PATCH 082/215] Convert HIFI examples to in-line configuration --- AudioOutput.h | 6 ++-- .../01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino | 19 ++++++------- .../Line_Gliss_Double_32k_HIFI.ino | 27 ++++++++---------- .../Audio_Input/Audio_Input.ino | 13 +++++---- .../Audio_Input_with_Knob_Filter.ino | 12 ++++++-- .../Audio_and_Control_Input.ino | 11 ++++---- .../AMsynth_HIFI/AMsynth_HIFI.ino | 18 +++++------- .../FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino | 25 ++++++++--------- .../AudioDelayFeedback_HIFI.ino | 28 ++++++++----------- .../StateVariableFilter_HIFI.ino | 17 +++++------ .../Mozzi_Processing_Serial.ino | 5 ++-- .../Sinewave_PWM_leds_HIFI.ino | 25 ++++++++--------- .../12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino | 9 ++++-- .../Risset_Beat_HIFI/Risset_Beat_HIFI.ino | 6 +++- .../Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino | 6 +++- 15 files changed, 113 insertions(+), 114 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index 367ba7f9f..2f2288cb9 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -77,7 +77,7 @@ */ #define AudioOutput_t AudioOutputStorage_t /** Representation of an single audio output sample/frame. This #define maps to either MonoOutput or StereoOutput, depending on what is configured - * in mozzi_config.h. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g. + * in MOZZI_AUDIO_CHANNELS. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g. * both have functions l() and r(), to return "two" audio channels (which will be the same in case of mono). * * You will not usually use or encounter this definition, unless using @ref external_audio output mode. @@ -96,7 +96,7 @@ struct StereoOutput { /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning). This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ - inline AudioOutput_t portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check mozzi_config.h."))) { return _l; }; + inline AudioOutput_t portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; }; #endif AudioOutputStorage_t l() const { return _l; }; AudioOutputStorage_t r() const { return _r; }; @@ -137,7 +137,7 @@ struct MonoOutput { /** Conversion to stereo operator: If used in a stereo config, returns identical channels (and gives a compile time warning). This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ - inline StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check mozzi_config.h."))) { return StereoOutput(_l, _l); }; + inline StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check MOZZI_AUDIO_CHANNELS setting."))) { return StereoOutput(_l, _l); }; #else /** Conversion to int operator. */ inline operator AudioOutput_t() const { return _l; }; diff --git a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino index c80cd3c76..fb1769c8c 100644 --- a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino +++ b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino @@ -3,16 +3,10 @@ Demonstrates the use of Oscil to play a wavetable. - This sketch using HIFI mode on AVR (i.e. the classic Arduino borads, not Teensy 3.x and friends). - - IMPORTANT: this sketch requires Mozzi/mozzi_config.h to be - be changed from STANDARD mode to HIFI. - In Mozz/mozzi_config.h, change - #define AUDIO_MODE STANDARD - //#define AUDIO_MODE HIFI - to - //#define AUDIO_MODE STANDARD - #define AUDIO_MODE HIFI + Important: + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -41,6 +35,9 @@ Tim Barrass 2012-13, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM + #include #include // oscillator template #include // sine table for oscillator @@ -49,7 +46,7 @@ Oscil aSin(SIN2048_DATA); void setup(){ - startMozzi(); // uses the default control rate of 64, defined in mozzi_config.h + startMozzi(); // uses the default control rate of 64 aSin.setFreq(440); // set the frequency } diff --git a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino index 70d92bcec..1120af986 100644 --- a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino +++ b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino @@ -14,21 +14,14 @@ Also shows how to use random offsets between the oscillators' frequencies to produce a chorusing/doubling effect. - This sketch using HIFI mode is not for Teensy 3.1. - - IMPORTANT: this sketch requires Mozzi/mozzi_config.h to be - be changed from STANDARD mode to HIFI. - In Mozz/mozzi_config.h, change - #define AUDIO_MODE STANDARD - //#define AUDIO_MODE STANDARD_PLUS - //#define AUDIO_MODE HIFI - to - //#define AUDIO_MODE STANDARD - //#define AUDIO_MODE STANDARD_PLUS - #define AUDIO_MODE HIFI - - Also, AUDIO_RATE can be changed from 16384 to 32768 in mozzi_config.h, - to try out the higher sample rate. + Important: + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). + + The MOZZI_AUDIO_RATE (sample rate) is additionally configured at 32768 Hz, + which is the default on most platforms, but twice the standard rate on + AVR-CPUs. Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -57,6 +50,10 @@ Tim Barrass 2012, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#define MOZZI_AUDIO_RATE 32768 + #include #include // for smooth transitions #include // oscillator template diff --git a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino index 301eb4b61..5ca020913 100644 --- a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino +++ b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino @@ -1,11 +1,10 @@ /* Test of audio input using Mozzi sonification library. - An audio input using the range between 0 to 5V on analog pin A0 - is sampled and output on digital pin 9. + An audio input using the range between 0 to 5V on analog pin A0 (or as + set in MOZZI_AUDIO_INPUT_PIN) is sampled and output on digital pin 9. - Configuration: requires these lines in the Mozzi/mozzi_config.h file: - #define USE_AUDIO_INPUT true - #define AUDIO_INPUT_PIN 0 + NOTE: MOZZI_AUDIO_INPUT_STANDARD is not available as an option on all + platforms. Circuit: Audio cable centre wire on pin A0, outer shielding to Arduino Ground. @@ -18,6 +17,10 @@ Tim Barrass 2013, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD +#define MOZZI_AUDIO_INPUT_PIN 0 + #include void setup(){ diff --git a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino index 21957048d..d8a991925 100644 --- a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino +++ b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino @@ -2,9 +2,11 @@ Test of audio input and processing with control input, using Mozzi sonification library. - Configuration: requires these lines in the Mozzi/mozzi_config.h file: - #define USE_AUDIO_INPUT true - #define AUDIO_INPUT_PIN 0 + An audio input using the range between 0 to 5V on analog pin A0 (or as + set in MOZZI_AUDIO_INPUT_PIN) is sampled and output on digital pin 9. + + NOTE: MOZZI_AUDIO_INPUT_STANDARD is not available as an option on all + platforms. Circuit: Audio input on pin analog 0 @@ -23,6 +25,10 @@ */ +#include +#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD +#define MOZZI_AUDIO_INPUT_PIN 0 + #include #include diff --git a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino index 51392a138..ed7493616 100644 --- a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino +++ b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino @@ -5,12 +5,10 @@ All the other analog channels are sampled at control rate and printed to Serial. Demonstrates mozziAnalogRead(pin), which reads analog inputs in the background, - and getAudioInput(), which samples audio on AUDIO_INPUT_PIN, configured in mozzi_config.h. - - Configuration: requires these lines in the Mozzi/mozzi_config.h file: - #define USE_AUDIO_INPUT true - #define AUDIO_INPUT_PIN 0 + and getAudioInput(), which samples audio on MOZZI_AUDIO_INPUT_PIN, configured below. + NOTE: MOZZI_AUDIO_INPUT_STANDARD is not available as an option on all + platforms. Circuit: Audio cable centre wire on pin A0, outer shielding to Arduino Ground. @@ -28,6 +26,9 @@ Tim Barrass 2013, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD +#define MOZZI_AUDIO_INPUT_PIN 0 #include diff --git a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino index 52302497f..91ae70b9a 100644 --- a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino +++ b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino @@ -7,17 +7,10 @@ values, random numbers with rand(), and EventDelay() for scheduling. - This sketch using HIFI mode is not for Teensy 3.1. - - IMPORTANT: this sketch requires Mozzi/mozzi_config.h to be - be changed from STANDARD mode to HIFI. - In Mozz/mozzi_config.h, change - #define AUDIO_MODE STANDARD - //#define AUDIO_MODE HIFI - to - //#define AUDIO_MODE STANDARD - #define AUDIO_MODE HIFI - + Important: + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -46,6 +39,9 @@ Tim Barrass 2012-13, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM + #include #include #include // table for Oscils to play diff --git a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino index 90e0bab18..95bc0e8d3 100644 --- a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino +++ b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino @@ -7,20 +7,13 @@ This sketch using HIFI mode is not for Teensy 3.1. - IMPORTANT: this sketch requires Mozzi/mozzi_config.h to be - be changed from STANDARD mode to HIFI. - In Mozz/mozzi_config.h, change - //#define AUDIO_MODE STANDARD - #define AUDIO_MODE STANDARD_PLUS - //#define AUDIO_MODE HIFI - to - //#define AUDIO_MODE STANDARD - //#define AUDIO_MODE STANDARD_PLUS - #define AUDIO_MODE HIFI - - The sketch also sounds better with a faster sample rate, for less aliasing - #define AUDIO_RATE 32768 - in mozzi_config. + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). + + The MOZZI_AUDIO_RATE (sample rate) is additionally configured at 32768 Hz, + which is the default on most platforms, but twice the standard rate on + AVR-CPUs. Try chaging it back to hear the difference. Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -49,6 +42,10 @@ Tim Barrass 2012-13, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#define MOZZI_AUDIO_RATE 32768 + #include #include #include // table for Oscils to play diff --git a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino index ee048d561..d5f4c59b2 100644 --- a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino +++ b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino @@ -3,22 +3,14 @@ Demonstrates AudioDelayFeedback. - This sketch using HIFI mode is not for Teensy 3.1. - - IMPORTANT: this sketch requires Mozzi/mozzi_config.h to be - be changed from STANDARD mode to HIFI. - In Mozz/mozzi_config.h, change - //#define AUDIO_MODE STANDARD - #define AUDIO_MODE STANDARD_PLUS - //#define AUDIO_MODE HIFI - to - //#define AUDIO_MODE STANDARD - //#define AUDIO_MODE STANDARD_PLUS - #define AUDIO_MODE HIFI - - The sketch also sounds better with a faster sample rate, for less aliasing - #define AUDIO_RATE 32768 - in mozzi_config. + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). + + Important: + The MOZZI_AUDIO_RATE (sample rate) is additionally configured at 32768 Hz, + which is the default on most platforms, but twice the standard rate on + AVR-CPUs. Try chaging it back to hear the difference. Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -47,6 +39,10 @@ Tim Barrass 2012-13, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#define MOZZI_AUDIO_RATE 32768 + #include #include #include // wavetable diff --git a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino index fc6afb006..5b0681aad 100644 --- a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino +++ b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino @@ -5,16 +5,10 @@ which in this case requires the input signal level to be reduced to avoid distortion which can occur with sharp resonance settings. - This sketch using HIFI mode is not for Teensy 3.1. - - IMPORTANT: this sketch requires Mozzi/mozzi_config.h to be - be changed from STANDARD mode to HIFI. - In Mozz/mozzi_config.h, change - #define AUDIO_MODE STANDARD - //#define AUDIO_MODE HIFI - to - //#define AUDIO_MODE STANDARD - #define AUDIO_MODE HIFI + Important: + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -43,6 +37,9 @@ Tim Barrass 2012, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM + #include #include #include diff --git a/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino b/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino index 27ecb18ac..904960bbf 100644 --- a/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino +++ b/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino @@ -6,7 +6,7 @@ in individual bytes, each of which ranges from 0 to 255. Arduino reads these bytes and uses them to set the frequency of the oscillator. - Circuit: Audio output on digital pin 9. (STANDARD_PLUS mode in mozzi_config.h) + Circuit: Audio output on digital pin 9. (on Arduino Uno/Nano, in default config) Serial connection to Processing, Max/MSP, or another serial application Dimmer example created 2006 @@ -19,8 +19,7 @@ */ - - +#include #include // oscillator template #include // sine table for oscillator diff --git a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino index 746192fe1..0a5cd25bc 100644 --- a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino +++ b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino @@ -8,22 +8,16 @@ between 0-255. The technique is explained here: http://playground.arduino.cc/Main/PWMallPins - With AUDIO_RATE at 16384 Hz, this gives a 64 Hz pwm duty cycle for the LEDs. + + With MOZZI_AUDIO_RATE at 16384 Hz (default on AVR), this gives a 64 Hz pwm duty cycle for the LEDs. If there is visible flicker, the resolution of the pwm could be made lower, - or the AUDIO_RATE could be increased to 32768 Hz, if the + or the MOZZI_AUDIO_RATE could be increased to 32768 Hz, if the cpu isn't too busy. - HIFI mode is not for Teensy 3.x, but the PWM led part should work. - - IMPORTANT: this sketch requires Mozzi/mozzi_config.h to be - be changed from STANDARD mode to HIFI. - In Mozz/mozzi_config.h, change - #define AUDIO_MODE STANDARD - //#define AUDIO_MODE HIFI - to - //#define AUDIO_MODE STANDARD - #define AUDIO_MODE HIFI - + Important: + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -56,6 +50,9 @@ Tim Barrass 2012-13, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +//#define MOZZI_AUDIO_RATE 32768 #include #include // oscillator template @@ -100,7 +97,7 @@ void setup(){ kBlue.setFreq(0.27f); // set audio oscil frequency aSin.setFreq(440); - startMozzi(); // uses the default control rate of 64, defined in mozzi_config.h + startMozzi(); // uses the default control rate of 64 } diff --git a/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino b/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino index 3bc9df8e2..f8de1c267 100644 --- a/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino +++ b/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino @@ -3,8 +3,10 @@ The Arduino-compatible "Pro Micro" board sent with Mozzibytes needs "Arduino Leonardo" to be set under Arduino>Tools>Board. - Important: - #define AUDIO_MODE HIFI in mozzi_config.h + Important: + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -28,7 +30,10 @@ Tim Barrass 2018, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#include #include #include #include diff --git a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino index 3c3954618..f5116c239 100644 --- a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino +++ b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino @@ -5,7 +5,9 @@ Demonstrates Sample(), EventDelay(), Line(), fixed pint numbers and bit-shifting Important: - #define AUDIO_MODE HIFI in mozzi_config.h + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -32,6 +34,8 @@ Tim Barrass 2018, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM #include #include // Sample template diff --git a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino index 51334ddb3..64c828aae 100644 --- a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino +++ b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino @@ -7,7 +7,9 @@ More oscillators could be added for a more convincing effect. Important: - #define AUDIO_MODE HIFI in mozzi_config.h + This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which + is not available on all boards (among others, it works on the + classic Arduino boards, but not Teensy 3.x and friends). Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar), Check the Mozzi core module documentation for others and more detail @@ -29,6 +31,8 @@ Tim Barrass 2018, CC by-nc-sa. */ +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM #include #include From 373daf8e4b9bf60e1c89be52b5529d1d43d12746 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Fri, 5 Jan 2024 23:52:55 +0100 Subject: [PATCH 083/215] Allow compilation of unsupported HIFI and STEREO examples to pass in the automated testing workflow --- .github/workflows/compile_examples.yml | 3 +++ AudioOutput.h | 3 +++ internal/config_checks_esp32.h | 1 + internal/config_checks_esp8266.h | 2 ++ internal/config_checks_mbed.h | 1 + internal/config_checks_renesas.h | 2 ++ internal/config_checks_rp2040.h | 1 + internal/config_checks_samd21.h | 2 ++ internal/config_checks_stm32duino.h | 1 + internal/config_checks_stm32maple.h | 1 + internal/config_checks_teensy.h | 3 +++ internal/config_checks_template.h | 3 +++ internal/disable_2pinmode_on_github_workflow.h | 11 +++++++++++ internal/disable_stereo_on_github_workflow.h | 13 +++++++++++++ 14 files changed, 47 insertions(+) create mode 100644 internal/disable_2pinmode_on_github_workflow.h create mode 100644 internal/disable_stereo_on_github_workflow.h diff --git a/.github/workflows/compile_examples.yml b/.github/workflows/compile_examples.yml index e43891ca6..cc8472533 100644 --- a/.github/workflows/compile_examples.yml +++ b/.github/workflows/compile_examples.yml @@ -62,6 +62,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 + - name: Add marker file for github run + run: echo "#define IN_GITHUB_RUNNER 1" > detect_github_runner.h + - name: Compile examples uses: arduino/compile-sketches@v1 with: diff --git a/AudioOutput.h b/AudioOutput.h index 2f2288cb9..077a32955 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -97,6 +97,9 @@ struct StereoOutput { This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ inline AudioOutput_t portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; }; +# if GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO + inline operator AudioOutput_t() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; }; +# endif #endif AudioOutputStorage_t l() const { return _l; }; AudioOutputStorage_t r() const { return _r; }; diff --git a/internal/config_checks_esp32.h b/internal/config_checks_esp32.h index 1d462385f..e7024ce1a 100644 --- a/internal/config_checks_esp32.h +++ b/internal/config_checks_esp32.h @@ -70,6 +70,7 @@ #error This header should be included for ESP32 architecture, only #endif +#include "disable_2pinmode_on_github_workflow.h" #if !defined(MOZZI_AUDIO_MODE) #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC #endif diff --git a/internal/config_checks_esp8266.h b/internal/config_checks_esp8266.h index b4ed95087..3e6ab227b 100644 --- a/internal/config_checks_esp8266.h +++ b/internal/config_checks_esp8266.h @@ -62,6 +62,7 @@ #error This header should be included for ESP architecture, only #endif +#include "disable_2pinmode_on_github_workflow.h" #if !defined(MOZZI_AUDIO_MODE) #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PDM_VIA_SERIAL #endif @@ -86,6 +87,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) # if !defined(PDM_RESOLUTION) # define MOZZI_PDM_RESOLUTION 2 # endif +# include "disable_stereo_on_github_workflow.h" MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16) #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) diff --git a/internal/config_checks_mbed.h b/internal/config_checks_mbed.h index e92b33414..ea2e84dfc 100644 --- a/internal/config_checks_mbed.h +++ b/internal/config_checks_mbed.h @@ -56,6 +56,7 @@ #error This header should be included for MBED architecture, only #endif +#include "disable_2pinmode_on_github_workflow.h" #if !defined(MOZZI_AUDIO_MODE) #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC #endif diff --git a/internal/config_checks_renesas.h b/internal/config_checks_renesas.h index 53e33a40c..a006c5be5 100644 --- a/internal/config_checks_renesas.h +++ b/internal/config_checks_renesas.h @@ -35,6 +35,7 @@ #error This header should be included for RENESAS (Arduino Uno R4) architecture, only #endif +#include "disable_2pinmode_on_github_workflow.h" #if !defined(MOZZI_AUDIO_MODE) #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC #endif @@ -62,6 +63,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_RE # define MOZZI_AUDIO_PIN_1 A0 # endif # define BYPASS_MOZZI_OUTPUT_BUFFER true +# include "disable_stereo_on_github_workflow.h" MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) #endif diff --git a/internal/config_checks_rp2040.h b/internal/config_checks_rp2040.h index 467f9948b..270e1af49 100644 --- a/internal/config_checks_rp2040.h +++ b/internal/config_checks_rp2040.h @@ -62,6 +62,7 @@ #error This header should be included for RP2040 architecture (Raspberry Pi Pico and others), only #endif +#include "disable_2pinmode_on_github_workflow.h" #if !defined(MOZZI_AUDIO_MODE) # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM #endif diff --git a/internal/config_checks_samd21.h b/internal/config_checks_samd21.h index dc340fb2d..1176fb75a 100644 --- a/internal/config_checks_samd21.h +++ b/internal/config_checks_samd21.h @@ -35,6 +35,7 @@ #error This header should be included for SAMD21 architecture (Arduino Circuitplayground M0 and others), only #endif +#include "disable_2pinmode_on_github_workflow.h" #if !defined(MOZZI_AUDIO_MODE) #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC #endif @@ -61,6 +62,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) # if !defined(MOZZI_AUDIO_PIN_1) # define MOZZI_AUDIO_PIN_1 DAC0 # endif +# include "disable_stereo_on_github_workflow.h" MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) #endif diff --git a/internal/config_checks_stm32duino.h b/internal/config_checks_stm32duino.h index 3c3f1d419..ca0889660 100644 --- a/internal/config_checks_stm32duino.h +++ b/internal/config_checks_stm32duino.h @@ -117,6 +117,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU # if !defined(MOZZI_AUDIO_PIN_1_LOW) # define MOZZI_AUDIO_PIN_1_LOW PA9 # endif +# include "disable_stereo_on_github_workflow.h" MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) # if !defined(MOZZI_AUDIO_PER_CHANNEL) # define MOZZI_AUDIO_PER_CHANNEL 7 diff --git a/internal/config_checks_stm32maple.h b/internal/config_checks_stm32maple.h index 27b08736f..507f93b31 100644 --- a/internal/config_checks_stm32maple.h +++ b/internal/config_checks_stm32maple.h @@ -108,6 +108,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU # if !defined(MOZZI_AUDIO_PIN_1_LOW) # define MOZZI_AUDIO_PIN_1_LOW PB9 # endif +# include "disable_stereo_on_github_workflow.h" MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) # if !defined(MOZZI_AUDIO_PER_CHANNEL) # define MOZZI_AUDIO_PER_CHANNEL 7 diff --git a/internal/config_checks_teensy.h b/internal/config_checks_teensy.h index 6f2e642a9..875addc18 100644 --- a/internal/config_checks_teensy.h +++ b/internal/config_checks_teensy.h @@ -84,11 +84,13 @@ #if IS_TEENSY3() +# include "disable_2pinmode_on_github_workflow.h" # if !defined(MOZZI_AUDIO_MODE) # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC # endif MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC) #elif IS_TEENSY4() +# include "disable_2pinmode_on_github_workflow.h" # if !defined(MOZZI_AUDIO_MODE) # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM # endif @@ -124,6 +126,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_RE # error DAC pin not know for this board. Please define MOZZI_AUDIO_PIN_1 as appropriate # endif # endif +# include "disable_stereo_on_github_workflow.h" MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) # define MOZZI_AUDIO_BITS 10 // not configurable diff --git a/internal/config_checks_template.h b/internal/config_checks_template.h index f957545f0..8227934a7 100644 --- a/internal/config_checks_template.h +++ b/internal/config_checks_template.h @@ -9,6 +9,8 @@ * 3) Document some details of your port */ +/** NOTE: If your port doesn't support MOZZI_OUTPUT_2PIN_PWM, add this include to make compilation of HIFI examples pass on the github runner */ +#include "disable_2pinmode_on_github_workflow.h" /** NOTE: All ports need to provide a default for this */ #if not defined(MOZZI_AUDIO_MODE) # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM @@ -39,6 +41,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_ # define MOZZI_AUDIO_BITS 10 # endif /** NOTE: If only mono is supported in this output mode: */ +# include "disable_stereo_on_github_workflow.h" // This allows stereo sketches to compile (in mono) in automated testing builds. MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO) #endif diff --git a/internal/disable_2pinmode_on_github_workflow.h b/internal/disable_2pinmode_on_github_workflow.h new file mode 100644 index 000000000..68bd88f44 --- /dev/null +++ b/internal/disable_2pinmode_on_github_workflow.h @@ -0,0 +1,11 @@ +/* This purely internal header takes care of disabling stereo mode when on a github runner. Intended to be used + * on platforms that don't support stereo, allowing the compilation to proceed without error. */ + +#if __has_include("../detect_github_runner.h") // the marker file we added inside the workflow + // do nothing, if this isn't present +# if defined(MOZZI_AUDIO_MODE) && MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) +# undef MOZZI_AUDIO_MODE +# warning Disabled 2pin pwm output mode on github runner +# endif + +#endif diff --git a/internal/disable_stereo_on_github_workflow.h b/internal/disable_stereo_on_github_workflow.h new file mode 100644 index 000000000..1360a5a8d --- /dev/null +++ b/internal/disable_stereo_on_github_workflow.h @@ -0,0 +1,13 @@ +/* This purely internal header takes care of disabling stereo mode when on a github runner. Intended to be used + * on platforms that don't support stereo, allowing the compilation to proceed without error. */ + +#if __has_include("../detect_github_runner.h") // the marker file we added inside the workflow + // do nothing, if this isn't present +# if defined(MOZZI_AUDIO_CHANNELS) && (MOZZI_AUDIO_CHANNELS > 1) +# define GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO +# undef MOZZI_AUDIO_CHANNELS +# define MOZZI_AUDIO_CHANNELS MOZZI_MONO +# warning Disabled stereo compilation while in Github runner. +# endif + +#endif From 9d64122be1a52b10f332267c56f1b36d3e3714fb Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 6 Jan 2024 00:14:17 +0100 Subject: [PATCH 084/215] Fix HIFI compilation of STM32duino core --- internal/config_checks_stm32duino.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/config_checks_stm32duino.h b/internal/config_checks_stm32duino.h index ca0889660..2efbbdd5d 100644 --- a/internal/config_checks_stm32duino.h +++ b/internal/config_checks_stm32duino.h @@ -120,9 +120,9 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU # include "disable_stereo_on_github_workflow.h" MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) # if !defined(MOZZI_AUDIO_PER_CHANNEL) -# define MOZZI_AUDIO_PER_CHANNEL 7 +# define MOZZI_AUDIO_BITS_PER_CHANNEL 7 # endif -# define MOZZI_AUDIO_BITS MOZZI_AUDIO_BITS_PER_CHANNEL * 2 +# define MOZZI_AUDIO_BITS (MOZZI_AUDIO_BITS_PER_CHANNEL * 2) #endif #if !defined(MOZZI_ANALOG_READ) From 27392d82ec28c9cd71247657cacfac3e44067f37 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Thu, 11 Jan 2024 23:57:04 +0100 Subject: [PATCH 085/215] Implemented some inverse functions. Not as straight-forward as it seems --- FixMath.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/FixMath.h b/FixMath.h index eff01c296..87a96d856 100644 --- a/FixMath.h +++ b/FixMath.h @@ -69,6 +69,7 @@ #define MAX(N1,N2) (N1 > N2 ? N1 : N2) #define UBITSTOBYTES(N) (((N-1)>>3)+1) #define SBITSTOBYTES(N) (((N)>>3)+1) +#define ONESBITMASK(N) ((1ULL<<(N)) - 1) // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1< invFast() const + { + return UFixMath((ONESBITMASK(NI+NF)/internal_value),true); + } + + + + UFixMath invAccurate() const + { + return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); + } + + + //////// SHIFTS OVERLOADS /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. @@ -1025,6 +1041,7 @@ bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) #undef MAX #undef UBITSTOBYTES #undef SBITSTOBYTES +#undef ONESBITMASK #endif From b12d5db4a2db0da0d9a2130196930322404b909c Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 14 Jan 2024 13:54:41 +0100 Subject: [PATCH 086/215] Fix copyright info --- Mozzi.h | 2 +- MozziHeadersOnly.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mozzi.h b/Mozzi.h index 6dca6b0ed..38bfcf71e 100644 --- a/Mozzi.h +++ b/Mozzi.h @@ -1,7 +1,7 @@ /* * Mozzi.h * - * Copyright 2023, Thomas Combriat and the Mozzi team + * Copyright 2024, Tim Barrass and the Mozzi team * * This file is part of Mozzi. * diff --git a/MozziHeadersOnly.h b/MozziHeadersOnly.h index 6bd0f7b22..5d28041b3 100644 --- a/MozziHeadersOnly.h +++ b/MozziHeadersOnly.h @@ -1,7 +1,7 @@ /* - * Mozzi.h + * MozziHeadersOnly.h * - * Copyright 2023, Thomas Combriat and the Mozzi team + * Copyright 2024, Tim Barrass and the Mozzi team * * This file is part of Mozzi. * From 353f91a3d2507671949751dc58482e4a5a2d56a6 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 14 Jan 2024 13:57:22 +0100 Subject: [PATCH 087/215] Fix typo --- Readme_Mozzi_2_0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index 2a2834cff..c9b8c82af 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -1,6 +1,6 @@ Porting to Mozzi 2.0 -// TODO: properly type up +// TODO: These are just short notes taken while working. Needs to be typed up properly, in the end. changed config names and semantics TODO (incomplete) @@ -37,7 +37,7 @@ Other removed stuff: - Since Mozzi (AVR-port) no longer uses Timer 0 since a long time, the corresponding library (utility/TimerZero.h) has now been removed, too. The Arduino functions delay(), millis(), micros() and delayMicroseconds() should now be usable in theory. That said, you should avoid these functions, as they are slow (or even blocking). For measuring time, refer - to mozziMircos(). For delaying events, you can use Mozzi's EventDelay() unit instead (not to be confused with AudioDelay()). + to mozziMicros(). For delaying events, you can use Mozzi's EventDelay() unit instead (not to be confused with AudioDelay()). Moved headers: - Header files not meant for user inclusion have been moved to "internal" From 48f0e8d0e672dea923ab3a5e6c001cea62206c1f Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 14 Jan 2024 21:29:47 +0100 Subject: [PATCH 088/215] Fixed One definition rule for FixMath --- FixMath.h | 151 +++++++++++++++++++++++++++--------------------------- 1 file changed, 76 insertions(+), 75 deletions(-) diff --git a/FixMath.h b/FixMath.h index 87a96d856..8491be5d9 100644 --- a/FixMath.h +++ b/FixMath.h @@ -63,6 +63,7 @@ #ifndef FIXMATH2_H_ #define FIXMATH2_H_ +#include #include "IntegerType.h" #define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. @@ -278,7 +279,7 @@ class UFixMath - UFixMath invAccurate() const + UFixMath invAccurate() const // TODO ADD STATIC ASSERT { return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); } @@ -409,96 +410,96 @@ class UFixMath // Multiplication template -UFixMath operator*(uint8_t op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(uint8_t op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(uint16_t op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(uint16_t op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(uint32_t op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(uint32_t op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(uint64_t op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(uint64_t op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(int8_t op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(int8_t op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(int16_t op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(int16_t op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(int32_t op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(int32_t op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(int64_t op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(int64_t op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(float op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(float op, const UFixMath& uf) {return uf*op;} template -UFixMath operator*(double op, const UFixMath& uf) {return uf*op;} +inline UFixMath operator*(double op, const UFixMath& uf) {return uf*op;} // Addition template -UFixMath operator+(uint8_t op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(uint8_t op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(uint16_t op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(uint16_t op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(uint32_t op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(uint32_t op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(uint64_t op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(uint64_t op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(int8_t op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(int8_t op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(int16_t op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(int16_t op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(int32_t op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(int32_t op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(int64_t op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(int64_t op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(float op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(float op, const UFixMath& uf) {return uf+op;} template -UFixMath operator+(double op, const UFixMath& uf) {return uf+op;} +inline UFixMath operator+(double op, const UFixMath& uf) {return uf+op;} // Substraction template -SFixMath operator-(uint8_t op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(uint8_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(uint16_t op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(uint16_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(uint32_t op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(uint32_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(uint64_t op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(uint64_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(int8_t op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(int8_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(int16_t op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(int16_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(int32_t op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(int32_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(int64_t op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(int64_t op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(float op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(float op, const UFixMath& uf) {return -uf+op;} template -SFixMath operator-(double op, const UFixMath& uf) {return -uf+op;} +inline SFixMath operator-(double op, const UFixMath& uf) {return -uf+op;} @@ -780,96 +781,96 @@ class SFixMath // Multiplication template -SFixMath operator*(uint8_t op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(uint8_t op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(uint16_t op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(uint16_t op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(uint32_t op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(uint32_t op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(uint64_t op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(uint64_t op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(int8_t op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(int8_t op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(int16_t op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(int16_t op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(int32_t op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(int32_t op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(int64_t op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(int64_t op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(float op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(float op, const SFixMath& uf) {return uf*op;} template -SFixMath operator*(double op, const SFixMath& uf) {return uf*op;} +inline SFixMath operator*(double op, const SFixMath& uf) {return uf*op;} // Addition template -SFixMath operator+(uint8_t op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(uint8_t op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(uint16_t op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(uint16_t op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(uint32_t op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(uint32_t op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(uint64_t op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(uint64_t op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(int8_t op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(int8_t op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(int16_t op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(int16_t op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(int32_t op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(int32_t op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(int64_t op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(int64_t op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(float op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(float op, const SFixMath& uf) {return uf+op;} template -SFixMath operator+(double op, const SFixMath& uf) {return uf+op;} +inline SFixMath operator+(double op, const SFixMath& uf) {return uf+op;} // Substraction template -SFixMath operator-(uint8_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(uint8_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(uint16_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(uint16_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(uint32_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(uint32_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(uint64_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(uint64_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(int8_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(int8_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(int16_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(int16_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(int32_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(int32_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(int64_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(int64_t op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(float op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(float op, const SFixMath& uf) {return (-uf)+op;} template -SFixMath operator-(double op, const SFixMath& uf) {return (-uf)+op;} +inline SFixMath operator-(double op, const SFixMath& uf) {return (-uf)+op;} @@ -885,7 +886,7 @@ SFixMath operator-(double op, const SFixMath& uf) {return (-uf)+ @return The result of the multiplication of op1 and op2. As a SFixMath */ template -SFixMath operator* (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline SFixMath operator* (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { typedef typename IntegerType< SBITSTOBYTES(NI+_NI+NF+_NF)>::signed_type return_type ; return_type tt = return_type(op1.asRaw())*op2.asRaw(); @@ -898,7 +899,7 @@ SFixMath operator* (const SFixMath& op1, const UFixMath<_N @return The result of the multiplication of op1 and op2. As a SFixMath */ template -SFixMath operator* (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline SFixMath operator* (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2*op1; } @@ -913,7 +914,7 @@ SFixMath operator* (const UFixMath& op1, const SFixMath<_N @return The result of the addition of op1 and op2. As a SFixMath */ template -SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); @@ -931,7 +932,7 @@ SFixMath operator+ (const SFixMath& op1, const @return The result of the addition of op1 and op2. As a SFixMath */ template -SFixMath operator+ (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline SFixMath operator+ (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2+op1; } @@ -944,7 +945,7 @@ SFixMath operator+ (const UFixMath& op1, const @return The result of the subtraction of op1 by op2. As a SFixMath */ template -SFixMath operator- (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline SFixMath operator- (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); @@ -962,7 +963,7 @@ SFixMath operator- (const SFixMath& op1, const @return The result of the subtraction of op1 by op2. As a SFixMath */ template -SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return -op2+op1; } @@ -970,7 +971,7 @@ SFixMath operator- (const UFixMath& op1, const // Comparaison between SFixMath and UFixmath template -bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); @@ -980,7 +981,7 @@ bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) } template -bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); @@ -990,13 +991,13 @@ bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) } template -bool operator< (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline bool operator< (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2 > op1; } template -bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { return op2 > op1; } @@ -1004,7 +1005,7 @@ bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) template -bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); @@ -1014,13 +1015,13 @@ bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) } template -bool operator== (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline bool operator== (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2 == op1; } template -bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); @@ -1030,7 +1031,7 @@ bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) } template -bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2 != op1; } From 937865d50120a015bbd2bc3dea3ffe268f1a1133 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 14 Jan 2024 21:31:48 +0100 Subject: [PATCH 089/215] Made MAX macro safer --- FixMath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FixMath.h b/FixMath.h index 8491be5d9..2c10c3afe 100644 --- a/FixMath.h +++ b/FixMath.h @@ -67,7 +67,7 @@ #include "IntegerType.h" #define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. -#define MAX(N1,N2) (N1 > N2 ? N1 : N2) +#define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) #define UBITSTOBYTES(N) (((N-1)>>3)+1) #define SBITSTOBYTES(N) (((N)>>3)+1) #define ONESBITMASK(N) ((1ULL<<(N)) - 1) From 77c6132ac048c315646695a6ce304a0a79f2779d Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 14 Jan 2024 21:48:28 +0100 Subject: [PATCH 090/215] Added inverse functions to SFixMath --- FixMath.h | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/FixMath.h b/FixMath.h index 2c10c3afe..257be9b73 100644 --- a/FixMath.h +++ b/FixMath.h @@ -272,17 +272,30 @@ class UFixMath //////// INVERSE + + /** Compute the inverse of a UFixMath, as a UFixMath (not a typo). + This inverse is able to represent accurately the inverse of the smallest and biggest of the initial number, but might lead to a lot of duplicates in between. + Good if precision is not a premium but type conservation and speeds are. + This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. + @return The inverse of the number. + */ + UFixMath invFast() const { + static_assert(NI+NF<=63, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); return UFixMath((ONESBITMASK(NI+NF)/internal_value),true); } - - + /** Compute the inverse of a UFixMath, as a UFixMath. + This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. + This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. + @return The inverse of the number. + */ UFixMath invAccurate() const // TODO ADD STATIC ASSERT { + static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); - } + } @@ -669,6 +682,32 @@ class SFixMath } + //////// INVERSE + + /** Compute the inverse of a SFixMath, as a SFixMath (not a typo). + This inverse is able to represent accurately the inverse of the smallest and biggest of the initial number, but might lead to a lot of duplicates in between. + Good if precision is not a premium but type conservation and speeds are. + This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. + @return The inverse of the number. + */ + + SFixMath invFast() const + { + static_assert(NI+NF<=62, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); + return SFixMath((ONESBITMASK(NI+NF)/internal_value),true); + } + + /** Compute the inverse of a SFixMath, as a SFixMath. + This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. + This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. + @return The inverse of the number. + */ + SFixMath invAccurate() const // TODO ADD STATIC ASSERT + { + static_assert(2*NI+2*NF<=62, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); + return SFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); + } + //////// SHIFTS OVERLOADS /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. From 6cdc837f4a923ba088b50548edee2bbe9d8b758b Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 16 Jan 2024 22:31:50 +0100 Subject: [PATCH 091/215] Switch onesbit to constexpr --- FixMath.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/FixMath.h b/FixMath.h index 257be9b73..5a14d3d72 100644 --- a/FixMath.h +++ b/FixMath.h @@ -283,7 +283,8 @@ class UFixMath UFixMath invFast() const { static_assert(NI+NF<=63, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); - return UFixMath((ONESBITMASK(NI+NF)/internal_value),true); + //return UFixMath((ONESBITMASK(NI+NF)/internal_value),true); + return UFixMath((onesbitmask()/internal_value),true); } /** Compute the inverse of a UFixMath, as a UFixMath. @@ -294,7 +295,8 @@ class UFixMath UFixMath invAccurate() const // TODO ADD STATIC ASSERT { static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); - return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); + //return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); + return UFixMath((onesbitmaskfull()/ (typename IntegerType::unsigned_type)internal_value),true); } @@ -415,6 +417,8 @@ class UFixMath private: internal_type internal_value; + static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } + static constexpr typename IntegerType::unsigned_type onesbitmaskfull() { return (typename IntegerType::unsigned_type) ((1ULL<< (NI*2+NF*2)) - 1); } }; From 7252b2adac5cad27e948f1be274ad75f45a4efdd Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 16 Jan 2024 22:58:35 +0100 Subject: [PATCH 092/215] Changed all inverses to constexpr, gain of 40% --- FixMath.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/FixMath.h b/FixMath.h index 5a14d3d72..62f05b939 100644 --- a/FixMath.h +++ b/FixMath.h @@ -287,6 +287,7 @@ class UFixMath return UFixMath((onesbitmask()/internal_value),true); } + /** Compute the inverse of a UFixMath, as a UFixMath. This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @@ -296,7 +297,7 @@ class UFixMath { static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); //return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); - return UFixMath((onesbitmaskfull()/ (typename IntegerType::unsigned_type)internal_value),true); + return UFixMath((onesbitmaskfull() / (typename IntegerType::unsigned_type)internal_value),true); } @@ -698,7 +699,8 @@ class SFixMath SFixMath invFast() const { static_assert(NI+NF<=62, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); - return SFixMath((ONESBITMASK(NI+NF)/internal_value),true); + //return SFixMath((ONESBITMASK(NI+NF)/internal_value),true); + return SFixMath((onesbitmask()/internal_value),true); } /** Compute the inverse of a SFixMath, as a SFixMath. @@ -709,7 +711,8 @@ class SFixMath SFixMath invAccurate() const // TODO ADD STATIC ASSERT { static_assert(2*NI+2*NF<=62, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); - return SFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); + //return SFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::signed_type)internal_value),true); + return SFixMath((onesbitmaskfull() / (typename IntegerType::signed_type)internal_value),true); } //////// SHIFTS OVERLOADS @@ -817,6 +820,8 @@ class SFixMath private: internal_type internal_value; + static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } + static constexpr typename IntegerType::signed_type onesbitmaskfull() { return (typename IntegerType::signed_type) ((1ULL<< (NI*2+NF*2)) - 1); } }; From 8b9c8dca4afc76eddc5d7fafdeb2b3060ebbd354 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 21 Jan 2024 20:51:49 +0100 Subject: [PATCH 093/215] Added constexpr as replacements of macros, but not sure it is better as they will spill out. --- FixMath.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/FixMath.h b/FixMath.h index 62f05b939..249527bf7 100644 --- a/FixMath.h +++ b/FixMath.h @@ -70,7 +70,7 @@ #define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) #define UBITSTOBYTES(N) (((N-1)>>3)+1) #define SBITSTOBYTES(N) (((N)>>3)+1) -#define ONESBITMASK(N) ((1ULL<<(N)) - 1) +//#define ONESBITMASK(N) ((1ULL<<(N)) - 1) // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1<>3)+1);} +//constexpr byte UBITSTOBYTES(byte N) { return (((N-1)>>3)+1);} // Forward declaration @@ -1090,7 +1092,7 @@ inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 #undef MAX #undef UBITSTOBYTES #undef SBITSTOBYTES -#undef ONESBITMASK +//#undef ONESBITMASK #endif From 358a45bdc13ef10c13e17f545711862a4fcfd1b7 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 21 Jan 2024 21:25:37 +0100 Subject: [PATCH 094/215] Bugfix in SFixMath::fromRaw --- FixMath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FixMath.h b/FixMath.h index 249527bf7..d9bce132b 100644 --- a/FixMath.h +++ b/FixMath.h @@ -572,7 +572,7 @@ class SFixMath @return A SFixMath. */ template - static SFixMath fromRaw(T raw){return UFixMath(raw,true);} + static SFixMath fromRaw(T raw){return SFixMath(raw,true);} /** Constructor from another SFixMath. From 7cdebee02c180f04cfb2cca4b3c27dbcf5dbb258 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 21 Jan 2024 22:27:57 +0100 Subject: [PATCH 095/215] Moved Vibrato example to FixMath --- examples/01.Basics/Vibrato/Vibrato.ino | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/examples/01.Basics/Vibrato/Vibrato.ino b/examples/01.Basics/Vibrato/Vibrato.ino index a232275f8..d431f0e7a 100644 --- a/examples/01.Basics/Vibrato/Vibrato.ino +++ b/examples/01.Basics/Vibrato/Vibrato.ino @@ -20,14 +20,18 @@ #include #include // table for Oscils to play #include // for mtof -#include +//#include +#include // Fixed point arithmetics #define CONTROL_RATE 64 // Hz, powers of 2 are most reliable Oscil aCos(COS2048_DATA); Oscil aVibrato(COS2048_DATA); -const byte intensity = 255; +//const byte intensity = 255; +const UFixMath<0,8> intensity = 0.5; // amplitude of the phase modulation + // 0.5 leads to a modulation of half the + // wavetable void setup(){ startMozzi(CONTROL_RATE); @@ -41,7 +45,8 @@ void updateControl(){ AudioOutput_t updateAudio(){ - Q15n16 vibrato = (Q15n16) intensity * aVibrato.next(); + //Q15n16 vibrato = (Q15n16) intensity * aVibrato.next(); + auto vibrato = intensity * SFixMath<0, 7>::fromRaw(aVibrato.next()); // Oscils in Mozzi are 8bits: 7bits of signal plus one bit of sign, so what they fit into a SFixMath<0,7> which is a signed fixMath type with 7 bits of value. return MonoOutput::from8Bit(aCos.phMod(vibrato)); // phase modulation to modulate frequency } From 267b69bf5b7a3129a60ef8089164fe5977e7fb03 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 21 Jan 2024 23:09:23 +0100 Subject: [PATCH 096/215] Moved S/Ubitstobyte to constexpr --- FixMath.h | 62 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/FixMath.h b/FixMath.h index d9bce132b..1e71f6dff 100644 --- a/FixMath.h +++ b/FixMath.h @@ -68,8 +68,8 @@ #define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) -#define UBITSTOBYTES(N) (((N-1)>>3)+1) -#define SBITSTOBYTES(N) (((N)>>3)+1) +//#define UBITSTOBYTES(N) (((N-1)>>3)+1) +//#define SBITSTOBYTES(N) (((N)>>3)+1) //#define ONESBITMASK(N) ((1ULL<<(N)) - 1) // Experiments @@ -94,9 +94,11 @@ // This works, but then spills out of this file. The results of the macros need to be known at compile time for the templates // hence it is fair to think that this should be equivalent. -//constexpr byte SBITSTOBYTES(byte N) { return (((N)>>3)+1);} -//constexpr byte UBITSTOBYTES(byte N) { return (((N-1)>>3)+1);} +namespace MozziPrivate { +constexpr byte sBitsToBytes(byte N) { return (((N)>>3)+1);} +constexpr byte uBitsToBytes(byte N) { return (((N-1)>>3)+1);} +} // Forward declaration template @@ -112,8 +114,8 @@ template // NI and NF being the number of bits for the integra class UFixMath { static_assert(NI+NF<=64, "The total width of a UFixMath cannot exceed 64bits"); - typedef typename IntegerType::unsigned_type internal_type ; // smallest size that fits our internal integer - typedef typename IntegerType::unsigned_type next_greater_type ; // smallest size that fits 1<::unsigned_type internal_type ; // smallest size that fits our internal integer + typedef typename IntegerType::unsigned_type next_greater_type ; // smallest size that fits 1< UFixMath(const UFixMath<_NI,_NF>& uf) { //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } /** Constructor from another SFixMath. @@ -175,7 +177,7 @@ class UFixMath */ template UFixMath(const SFixMath<_NI,_NF>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -190,7 +192,7 @@ class UFixMath { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType::unsigned_type return_type; + typedef typename IntegerType::unsigned_type return_type; UFixMath left(*this); UFixMath right(op); @@ -220,7 +222,7 @@ class UFixMath { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType::signed_type return_type; + typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -244,7 +246,7 @@ class UFixMath */ SFixMath operator-() const { - return SFixMath( -(typename IntegerType::signed_type)(internal_value),true); + return SFixMath( -(typename IntegerType::signed_type)(internal_value),true); } //////// MULTIPLICATION OVERLOADS @@ -257,7 +259,7 @@ class UFixMath UFixMath operator* (const UFixMath<_NI,_NF>& op) const { //typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; - typedef typename IntegerType::unsigned_type return_type ; + typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return UFixMath(tt,true); } @@ -298,8 +300,8 @@ class UFixMath UFixMath invAccurate() const // TODO ADD STATIC ASSERT { static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); - //return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); - return UFixMath((onesbitmaskfull() / (typename IntegerType::unsigned_type)internal_value),true); + //return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); + return UFixMath((onesbitmaskfull() / (typename IntegerType::unsigned_type)internal_value),true); } @@ -421,7 +423,7 @@ class UFixMath private: internal_type internal_value; static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } - static constexpr typename IntegerType::unsigned_type onesbitmaskfull() { return (typename IntegerType::unsigned_type) ((1ULL<< (NI*2+NF*2)) - 1); } + static constexpr typename IntegerType::unsigned_type onesbitmaskfull() { return (typename IntegerType::unsigned_type) ((1ULL<< (NI*2+NF*2)) - 1); } }; @@ -533,8 +535,8 @@ template // NI and NF being the number of bits for the integra class SFixMath { static_assert(NI+NF<64, "The total width of a SFixMath cannot exceed 63bits"); - typedef typename IntegerType::signed_type internal_type ; // smallest size that fits our internal integer - typedef typename IntegerType::signed_type next_greater_type ; // smallest size that fits 1<::signed_type internal_type ; // smallest size that fits our internal integer + typedef typename IntegerType::signed_type next_greater_type ; // smallest size that fits 1< SFixMath(const SFixMath<_NI,_NF>& uf) { //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -592,7 +594,7 @@ class SFixMath */ template SFixMath(const UFixMath<_NI,_NF>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS @@ -606,7 +608,7 @@ class SFixMath { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType::unsigned_type return_type; + typedef typename IntegerType::unsigned_type return_type; SFixMath left(*this); SFixMath right(op); @@ -636,7 +638,7 @@ class SFixMath { constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType::unsigned_type return_type; + typedef typename IntegerType::unsigned_type return_type; SFixMath left(*this); SFixMath right(op); @@ -673,7 +675,7 @@ class SFixMath template SFixMath operator* (const SFixMath<_NI,_NF>& op) const { - typedef typename IntegerType::signed_type return_type ; + typedef typename IntegerType::signed_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return SFixMath(tt,true); } @@ -713,8 +715,8 @@ class SFixMath SFixMath invAccurate() const // TODO ADD STATIC ASSERT { static_assert(2*NI+2*NF<=62, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); - //return SFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::signed_type)internal_value),true); - return SFixMath((onesbitmaskfull() / (typename IntegerType::signed_type)internal_value),true); + //return SFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::signed_type)internal_value),true); + return SFixMath((onesbitmaskfull() / (typename IntegerType::signed_type)internal_value),true); } //////// SHIFTS OVERLOADS @@ -823,7 +825,7 @@ class SFixMath private: internal_type internal_value; static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } - static constexpr typename IntegerType::signed_type onesbitmaskfull() { return (typename IntegerType::signed_type) ((1ULL<< (NI*2+NF*2)) - 1); } + static constexpr typename IntegerType::signed_type onesbitmaskfull() { return (typename IntegerType::signed_type) ((1ULL<< (NI*2+NF*2)) - 1); } }; @@ -938,7 +940,7 @@ inline SFixMath operator-(double op, const SFixMath& uf) {return template inline SFixMath operator* (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - typedef typename IntegerType< SBITSTOBYTES(NI+_NI+NF+_NF)>::signed_type return_type ; + typedef typename IntegerType< MozziPrivate::sBitsToBytes(NI+_NI+NF+_NF)>::signed_type return_type ; return_type tt = return_type(op1.asRaw())*op2.asRaw(); return SFixMath(tt,true); } @@ -969,7 +971,7 @@ inline SFixMath operator+ (const SFixMath& op1 constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType::signed_type return_type; + typedef typename IntegerType::signed_type return_type; SFixMath left(op1); SFixMath right(op2); return_type tt = return_type(left.asRaw()) + right.asRaw(); @@ -1000,7 +1002,7 @@ inline SFixMath operator- (const SFixMath& op1 constexpr byte new_NI = MAX(NI, _NI) + 1; constexpr byte new_NF = MAX(NF, _NF); - typedef typename IntegerType::signed_type return_type; + typedef typename IntegerType::signed_type return_type; SFixMath left(op1); SFixMath right(op2); return_type tt = return_type(left.asRaw()) - right.asRaw(); @@ -1090,8 +1092,8 @@ inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 #undef MAX -#undef UBITSTOBYTES -#undef SBITSTOBYTES +//#undef UBITSTOBYTES +//#undef SBITSTOBYTES //#undef ONESBITMASK From 89ddc913778a338e90d26d8bfba701fc794875d8 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 23 Jan 2024 21:29:43 +0100 Subject: [PATCH 097/215] Added a Vibrato example fully using FixMath Used conventions for audio vs control rate oscillator in example --- .../Vibrato_Midi_Note/Vibrato_Midi_Note.ino | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino diff --git a/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino b/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino new file mode 100644 index 000000000..18cddc8e2 --- /dev/null +++ b/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino @@ -0,0 +1,64 @@ +/* Example playing a sinewave with vibrato, + using Mozzi sonification library. + + Demonstrates how to use fixed point arithmetics and midi notes to make an easy-to-adjust vibrato effect. + This is probably less efficient than the Vibrato example, but is also easier to understand the amount + of modulation + + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. +*/ + +#include +#include +#include // table for Oscils to play +#include // for mtof +#include // Fixed point arithmetics + +#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable \ + // we chose here an higher number than in the Vibrato example \ + // because the modulation is performed at CONTROL_RATE + +Oscil aCos(COS2048_DATA); +Oscil kVibrato(COS2048_DATA); + +UFixMath<7, 0> midi_note = 65; +UFixMath<2, 1> mod_amplitude = 2.5; // the amplitude of the vibrato, in semi-tones. + // 2.5 can be represented with only 2 integer bits + // and 1 fractionnal bit + // hence UFixMath<2,1> is good enough to represent + // that number. You can put numbers with decimals + // or higher ones, but beware to adjust the number + // of bits NI and NF of the UFixMath accordingly. + // It is always good to keep these as small as possible + // for performances. + + +void setup() { + startMozzi(CONTROL_RATE); + aCos.setFreq(mtof(midi_note)); + kVibrato.setFreq(UFixMath<16, 16>(10)); // frequency of the modulation +} + + +void updateControl() { + auto modulation = SFixMath<0, 7>::fromRaw(kVibrato.next()) * mod_amplitude; // Oscil in Mozzi are fundamentally 8 bits: 7bits of data and 1bit of sign. + // Here, we make it oscillate between nearly -1 and 1 (no integer bit). + // The FixMath class will take care of making modulation the correct type + // to preserve range and precision. + aCos.setFreq(mtof(midi_note + modulation)); // changing the frequency of the main oscillator, adding the modulation as a midi note. +} + + +AudioOutput_t updateAudio() { + return MonoOutput::from8Bit(aCos.next()); +} + +void loop() { + audioHook(); +} From d3f97026285d2c1ba7c13b7d21c27d55d91154a3 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 27 Jan 2024 19:32:07 +0100 Subject: [PATCH 098/215] Fixed merge bug with midi_table --- mozzi_midi_table.cpp | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 mozzi_midi_table.cpp diff --git a/mozzi_midi_table.cpp b/mozzi_midi_table.cpp deleted file mode 100644 index 50bb1cbb6..000000000 --- a/mozzi_midi_table.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "mozzi_midi.h" - -/* MidiToFreqPrivate -Stores the frequency values corresponding to whole MIDI notes -in fixed point format (Q16n16). -Used internally by the functions defined in mozzi_midi.h. - */ - -CONSTTABLE_STORAGE(uint32_t) MidiToFreqPrivate::midiToFreq[128] = - { - 0, 567670, 601425, 637188, 675077, 715219, 757748, 802806, 850544, 901120, - 954703, 1011473, 1071618, 1135340, 1202851, 1274376, 1350154, 1430438, 1515497, - 1605613, 1701088, 1802240, 1909406, 2022946, 2143236, 2270680, 2405702, 2548752, - 2700309, 2860877, 3030994, 3211226, 3402176, 3604479, 3818813, 4045892, 4286472, - 4541359, 4811404, 5097504, 5400618, 5721756, 6061988, 6422452, 6804352, 7208959, - 7637627, 8091785, 8572945, 9082719, 9622808, 10195009, 10801235, 11443507, - 12123974, 12844905, 13608704, 14417917, 15275252, 16183563, 17145888, 18165438, - 19245616, 20390018, 21602470, 22887014, 24247948, 25689810, 27217408, 28835834, - 30550514, 32367136, 34291776, 36330876, 38491212, 40780036, 43204940, 45774028, - 48495912, 51379620, 54434816, 57671668, 61101028, 64734272, 68583552, 72661752, - 76982424, 81560072, 86409880, 91548056, 96991792, 102759240, 108869632, - 115343336, 122202056, 129468544, 137167104, 145323504, 153964848, 163120144, - 172819760, 183096224, 193983648, 205518336, 217739200, 230686576, 244403840, - 258937008, 274334112, 290647008, 307929696, 326240288, 345639520, 366192448, - 387967040, 411036672, 435478400, 461373152, 488807680, 517874016, 548668224, - 581294016, 615859392, 652480576, 691279040, 732384896, 775934592, 822073344 - }; From ca533d2846a0dce7efd7f94a944808fed83ddd88 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 28 Jan 2024 13:33:39 +0100 Subject: [PATCH 099/215] Fix logic around MOZZI_OUTPUT_EXTERNAL_CUSTOM --- internal/MozziGuts.hpp | 2 +- internal/MozziGuts_impl_AVR.hpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 7b00c7029..55efaddc3 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -314,6 +314,6 @@ void audioHook() { MozziPrivate::audioHook(); }; #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) MOZZI_DEPRECATED("n/a", "Sketch has audioOutput() function, although external output is not configured.") void audioOutput(const AudioOutput) {}; #endif -#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) +#if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) MOZZI_DEPRECATED("n/a", "Sketch has canBufferAudioOutput() function, although custom external output is not configured.") bool canBufferAudioOutput() {}; #endif diff --git a/internal/MozziGuts_impl_AVR.hpp b/internal/MozziGuts_impl_AVR.hpp index 8b0c71ea2..54853880e 100644 --- a/internal/MozziGuts_impl_AVR.hpp +++ b/internal/MozziGuts_impl_AVR.hpp @@ -177,7 +177,7 @@ static uint8_t mozzi_TCCR4A, mozzi_TCCR4B, mozzi_TCCR4C, mozzi_TCCR4D, #endif #endif -#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // TODO: Check: This block used to compile also for BYPASS_MOZZI_OUTPUT_BUFFER, but I think unneccessarily so. +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) static void startAudio() { backupPreMozziTimer1(); Timer1.initializeCPUCycles( @@ -198,6 +198,8 @@ ISR(TIMER1_OVF_vect, ISR_BLOCK) { } namespace MozziPrivate { +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) +static void startAudio() {} #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) inline void audioOutput(const AudioOutput f) { From 9d7ec25b3a90fa13e2beccd7bd51236f15b1b7d4 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 28 Jan 2024 14:37:42 +0100 Subject: [PATCH 100/215] Fix compilation --- internal/MozziGuts.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 55efaddc3..f3525f395 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -315,5 +315,5 @@ void audioHook() { MozziPrivate::audioHook(); }; MOZZI_DEPRECATED("n/a", "Sketch has audioOutput() function, although external output is not configured.") void audioOutput(const AudioOutput) {}; #endif #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) -MOZZI_DEPRECATED("n/a", "Sketch has canBufferAudioOutput() function, although custom external output is not configured.") bool canBufferAudioOutput() {}; +//MOZZI_DEPRECATED("n/a", "Sketch has canBufferAudioOutput() function, although custom external output is not configured.") bool canBufferAudioOutput() {}; #endif From dc5bf31c9680f46f513a597f94486963fb8f7aea Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 28 Jan 2024 22:00:22 +0100 Subject: [PATCH 101/215] Add explanation --- internal/MozziGuts.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index f3525f395..e2994d4f0 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -315,5 +315,6 @@ void audioHook() { MozziPrivate::audioHook(); }; MOZZI_DEPRECATED("n/a", "Sketch has audioOutput() function, although external output is not configured.") void audioOutput(const AudioOutput) {}; #endif #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) +// TODO: This won't work without a rename: //MOZZI_DEPRECATED("n/a", "Sketch has canBufferAudioOutput() function, although custom external output is not configured.") bool canBufferAudioOutput() {}; #endif From aa90380599eb7e6e6aaff4ff31f9f5d1948605ab Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 29 Jan 2024 21:10:39 +0100 Subject: [PATCH 102/215] Added a more general inv member for FixMath, reimplemanted .invAccurate with it, saving one constexpr --- FixMath.h | 57 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/FixMath.h b/FixMath.h index 1e71f6dff..1a1edbfe2 100644 --- a/FixMath.h +++ b/FixMath.h @@ -92,12 +92,10 @@ */ -// This works, but then spills out of this file. The results of the macros need to be known at compile time for the templates -// hence it is fair to think that this should be equivalent. namespace MozziPrivate { -constexpr byte sBitsToBytes(byte N) { return (((N)>>3)+1);} -constexpr byte uBitsToBytes(byte N) { return (((N-1)>>3)+1);} + constexpr byte sBitsToBytes(byte N) { return (((N)>>3)+1);} + constexpr byte uBitsToBytes(byte N) { return (((N-1)>>3)+1);} } // Forward declaration @@ -288,21 +286,37 @@ class UFixMath { static_assert(NI+NF<=63, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); //return UFixMath((ONESBITMASK(NI+NF)/internal_value),true); - return UFixMath((onesbitmask()/internal_value),true); + return UFixMath((onesbitmask()/internal_value),true); } + /** Compute the inverse of a UFixMath, as a UFixMath. + _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invAccurate() (_NF=2*NI+NF) + @return The inverse of the number. + */ + template + UFixMath inv() const + { + return UFixMath<_NF,NF>(internal_value,true).invFast(); + } + + + /** Compute the inverse of a UFixMath, as a UFixMath. This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - UFixMath invAccurate() const // TODO ADD STATIC ASSERT - { - static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); - //return UFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::unsigned_type)internal_value),true); - return UFixMath((onesbitmaskfull() / (typename IntegerType::unsigned_type)internal_value),true); + UFixMath invAccurate() const + {/* + static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); + return UFixMath(internal_value,true).invFast(); */ + //return UFixMath(internal_value,true).inv(); + return inv(); } + + + @@ -423,7 +437,7 @@ class UFixMath private: internal_type internal_value; static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } - static constexpr typename IntegerType::unsigned_type onesbitmaskfull() { return (typename IntegerType::unsigned_type) ((1ULL<< (NI*2+NF*2)) - 1); } + //static constexpr typename IntegerType::unsigned_type onesbitmaskfull() { return (typename IntegerType::unsigned_type) ((1ULL<< (NI*2+NF*2)) - 1); } }; @@ -691,7 +705,7 @@ class SFixMath } - //////// INVERSE + //////// INVERSE /** Compute the inverse of a SFixMath, as a SFixMath (not a typo). This inverse is able to represent accurately the inverse of the smallest and biggest of the initial number, but might lead to a lot of duplicates in between. @@ -707,18 +721,27 @@ class SFixMath return SFixMath((onesbitmask()/internal_value),true); } + /** Compute the inverse of a SFixMath, as a SFixMath. + _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invAccurate() (_NF=2*NI+NF) + @return The inverse of the number. + */ + template + SFixMath inv() const + { + return SFixMath<_NF,NF>(internal_value,true).invFast(); + } + /** Compute the inverse of a SFixMath, as a SFixMath. This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - SFixMath invAccurate() const // TODO ADD STATIC ASSERT + SFixMath invAccurate() const { - static_assert(2*NI+2*NF<=62, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); - //return SFixMath((ONESBITMASK(NI*2+NF*2)/ (typename IntegerType::signed_type)internal_value),true); - return SFixMath((onesbitmaskfull() / (typename IntegerType::signed_type)internal_value),true); + return inv(); } + //////// SHIFTS OVERLOADS /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. @@ -825,7 +848,7 @@ class SFixMath private: internal_type internal_value; static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } - static constexpr typename IntegerType::signed_type onesbitmaskfull() { return (typename IntegerType::signed_type) ((1ULL<< (NI*2+NF*2)) - 1); } + //static constexpr typename IntegerType::signed_type onesbitmaskfull() { return (typename IntegerType::signed_type) ((1ULL<< (NI*2+NF*2)) - 1); } }; From cd805d5c15a01d18808110b0f5140a99ea4ab71f Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 29 Jan 2024 21:42:14 +0100 Subject: [PATCH 103/215] Added auto constructors to pure fractionnal and pure integer for U/SFIX --- FixMath.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/FixMath.h b/FixMath.h index 1a1edbfe2..bd72d9c6d 100644 --- a/FixMath.h +++ b/FixMath.h @@ -281,7 +281,6 @@ class UFixMath This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - UFixMath invFast() const { static_assert(NI+NF<=63, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); @@ -537,6 +536,39 @@ inline SFixMath operator-(float op, const UFixMath& uf) {return template inline SFixMath operator-(double op, const UFixMath& uf) {return -uf+op;} +////// Helper functions to build SFix from a normal type automatically + + +/** Create a *pure* fractional unsigned fixed number (UFixMath) from an unsigned integer. + The number of fractional bits (NF) is chosen automatically depending on the input + type. Hence toUFraction(255) and toUFraction(uint8_t(255)) *do not* lead to the + same thing: on an AVR, the former will lead to NF=16 - which is overkill and + incorrect if you expect toUFraction(255) = 1 - + whereas the latter will lead to NF=8. Mozzi's objects (Oscil and the like) + returns correct types, hence you can use this function to convert the return + value of a Mozzi's function/class member into a pure fractional number. + @param val The value to be converted into a pure fractional number. + @return A UFixMath<0,NF> with NF chosen according to the input type +*/ +template +inline UFixMath<0, sizeof(T)*8> toUFraction(T val) { + return UFixMath<0, sizeof(T)*8>::fromRaw(val); +} + +/** Create a *pure* integer unsigned fixed number (UFixMath) from an unsigned integer. + The number of fractional bits (NI) is chosen automatically depending on the input + type. Hence toUInt(255) and toSInt(uint8_t(255)) *do not* lead to the + same thing: on an AVR, the former will lead to NI=16 - which is overkill - + whereas the latter will lead to NI=8. Mozzi's objects (Oscil and the like) + returns correct types, hence you can use this function to convert the return + value of a Mozzi's function/class member into a pure fractional number. + @param val The value to be converted into a pure unsigned integer fixed math number. + @return A UFixMath with NI chosen according to the input type +*/ +template +inline UFixMath toUInt(T val) { + return UFixMath::fromRaw(val); +} @@ -1111,6 +1143,40 @@ inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 return op2 != op1; } +////// Helper functions to build SFix from a normal type automatically + + +/** Create a *pure* fractional signed fixed number (SFixMath) from a integer. + The number of fractional bits (NF) is chosen automatically depending on the input + type. Hence toSFraction(127) and toSFraction(int8_t(127)) *do not* lead to the + same thing: on an AVR, the former will lead to NF=15 - which is overkill and + incorrect if you expect toSFraction(127) = 1 - + whereas the latter will lead to NF=7. Mozzi's objects (Oscil and the like) + returns correct types, hence you can use this function to convert the return + value of a Mozzi's function/class member into a pure fractional number. + @param val The value to be converted into a pure fractional number. + @return A SFixMath<0,NF> with NF chosen according to the input type +*/ +template +inline SFixMath<0, sizeof(T)*8-1> toSFraction(T val) { + return SFixMath<0, sizeof(T)*8-1>::fromRaw(val); +} + +/** Create a *pure* integer signed fixed number (SFixMath) from a integer. + The number of fractional bits (NI) is chosen automatically depending on the input + type. Hence toSInt(127) and toSInt(int8_t(127)) *do not* lead to the + same thing: on an AVR, the former will lead to NI=15 - which is overkill - + whereas the latter will lead to NI=7. Mozzi's objects (Oscil and the like) + returns correct types, hence you can use this function to convert the return + value of a Mozzi's function/class member into a pure fractional number. + @param val The value to be converted into a pure integer fixed math number. + @return A SFixMath with NI chosen according to the input type +*/ +template +inline SFixMath toSInt(T val) { + return SFixMath::fromRaw(val); +} + From 0f1a3131fedff0bd09ff06cfaec9b32c23575856 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Thu, 1 Feb 2024 21:36:07 +0100 Subject: [PATCH 104/215] Starting implementing auto Range promotion for FixMath --- FixMath.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FixMath.h b/FixMath.h index bd72d9c6d..94c9a379e 100644 --- a/FixMath.h +++ b/FixMath.h @@ -71,6 +71,7 @@ //#define UBITSTOBYTES(N) (((N-1)>>3)+1) //#define SBITSTOBYTES(N) (((N)>>3)+1) //#define ONESBITMASK(N) ((1ULL<<(N)) - 1) +#define FULLRANGE(N) ((1ULL<<(N)) - 1) // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1< // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath { static_assert(NI+NF<=64, "The total width of a UFixMath cannot exceed 64bits"); @@ -1181,6 +1182,7 @@ inline SFixMath toSInt(T val) { #undef MAX +#undef FULLRANGE //#undef UBITSTOBYTES //#undef SBITSTOBYTES //#undef ONESBITMASK From 7b4e6a028a0021f569891ac30adabaef6319d3d7 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Thu, 1 Feb 2024 22:09:14 +0100 Subject: [PATCH 105/215] Addition between UFix now does not promote when not needed. Moved autorange add for UF into the class --- FixMath.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/FixMath.h b/FixMath.h index 94c9a379e..a5eb7ae0e 100644 --- a/FixMath.h +++ b/FixMath.h @@ -72,6 +72,7 @@ //#define SBITSTOBYTES(N) (((N)>>3)+1) //#define ONESBITMASK(N) ((1ULL<<(N)) - 1) #define FULLRANGE(N) ((1ULL<<(N)) - 1) +#define NEEDEDNI(NI, _NI, RANGE, _RANGE) ((RANGE+_RANGE)>FULLRANGE(MAX(NI, _NI)) ? (MAX(NI, _NI)+1) : (MAX(NI, _NI))) // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1< - UFixMath(const UFixMath<_NI,_NF>& uf) { + template + UFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -181,23 +182,23 @@ class UFixMath //////// ADDITION OVERLOADS - + /** Addition with another UFixMath. Safe. @param op The UFixMath to be added. @return The result of the addition as a UFixMath. */ - template - UFixMath operator+ (const UFixMath<_NI,_NF>& op) const + template + UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const { - constexpr byte new_NI = MAX(NI, _NI) + 1; + constexpr byte new_NI = NEEDEDNI(NI,_NI,RANGE,_RANGE); constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; UFixMath left(*this); UFixMath right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return UFixMath(tt,true); - } + return UFixMath(tt,true); + } /** Addition with another type. Unsafe @param op The number to be added. @@ -442,6 +443,7 @@ class UFixMath }; + /// Reverse overloadings, making a template here leads to an ambiguity, forcing us to specify them one by one?? // Multiplication From 19445afe86631cf634ba4ea2c533b0f788da5507 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Thu, 1 Feb 2024 22:51:37 +0100 Subject: [PATCH 106/215] Autoranging of subtraction with UFixMath --- FixMath.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/FixMath.h b/FixMath.h index a5eb7ae0e..e9e60ab03 100644 --- a/FixMath.h +++ b/FixMath.h @@ -101,7 +101,7 @@ namespace MozziPrivate { } // Forward declaration -template +template class SFixMath; @@ -217,8 +217,8 @@ class UFixMath @param op The UFixMath to be subtracted. @return The result of the subtraction as a SFixMath. */ - template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - SFixMath operator- (const UFixMath<_NI,_NF>& op) const + template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. + SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const { constexpr byte new_NI = MAX(NI, _NI); constexpr byte new_NF = MAX(NF, _NF); @@ -227,7 +227,7 @@ class UFixMath SFixMath right(op); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath(tt,true); + return SFixMath(tt,true); } @@ -241,6 +241,7 @@ class UFixMath return UFixMath(internal_value-((internal_type)op< toUInt(T val) { @param NF The number of bits encoding the fractional part @note The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFixMath<7,0>. */ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class SFixMath { static_assert(NI+NF<64, "The total width of a SFixMath cannot exceed 63bits"); From 0204f8cb52fbb57ecd938899797902eb1753e6a2 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 3 Feb 2024 22:44:58 +0100 Subject: [PATCH 107/215] Added RANGE to mul between UFix * FixMath.h: --- FixMath.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/FixMath.h b/FixMath.h index e9e60ab03..217847afc 100644 --- a/FixMath.h +++ b/FixMath.h @@ -73,6 +73,7 @@ //#define ONESBITMASK(N) ((1ULL<<(N)) - 1) #define FULLRANGE(N) ((1ULL<<(N)) - 1) #define NEEDEDNI(NI, _NI, RANGE, _RANGE) ((RANGE+_RANGE)>FULLRANGE(MAX(NI, _NI)) ? (MAX(NI, _NI)+1) : (MAX(NI, _NI))) +#define NEEDEDNIMUL(NI, _NI, RANGE, _RANGE) ((RANGE*_RANGE)>FULLRANGE((NI+ _NI-1)) ? ((NI+ _NI)) : ((NI+ _NI-1))) // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1< - UFixMath operator* (const UFixMath<_NI,_NF>& op) const + template + //UFixMath operator* (const UFixMath<_NI,_NF>& op) const + UFixMath operator* (const UFixMath<_NI,_NF>& op) const // TODO: check, throughfully, probably only true for UFix { //typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; - typedef typename IntegerType::unsigned_type return_type ; + typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); - return UFixMath(tt,true); + return UFixMath<(tt,true); } /** Multiplication with another type. Unsafe. @@ -1186,6 +1188,7 @@ inline SFixMath toSInt(T val) { #undef MAX #undef FULLRANGE +#undef NEEDEDNI //#undef UBITSTOBYTES //#undef SBITSTOBYTES //#undef ONESBITMASK From dcd0057ab41a0915ce7c7d924c5b037c9a279180 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 4 Feb 2024 10:29:01 +0100 Subject: [PATCH 108/215] Fix compilation on ESP32 --- MozziGuts.h | 2 +- internal/MozziGuts_impl_ESP32.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MozziGuts.h b/MozziGuts.h index e6a79e76d..131bfe8d5 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -53,7 +53,7 @@ typedef signed long int32_t; /*! @defgroup core Mozzi Core Functions -/** @ingroup core +@ingroup core Sets up the timers for audio and control rate processes, storing the timer registers so they can be restored when Mozzi stops. startMozzi() goes in your sketch's setup() routine. diff --git a/internal/MozziGuts_impl_ESP32.hpp b/internal/MozziGuts_impl_ESP32.hpp index 32d8535c2..71baaa983 100644 --- a/internal/MozziGuts_impl_ESP32.hpp +++ b/internal/MozziGuts_impl_ESP32.hpp @@ -126,7 +126,7 @@ static void startAudio() { timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer0_audio_output_isr, nullptr, 0, &s_timer_handle); timer_start(TIMER_GROUP_0, TIMER_0); -#else +#elif !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) static const i2s_config_t i2s_config = { # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), From 5e38d90a4d2363ed103ba4c213c61002470274d8 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 4 Feb 2024 10:52:58 +0100 Subject: [PATCH 109/215] Add bluetooth output example (only for ESP32, for the time being) --- .../ESP32_Bluetooth/ESP32_Bluetooth.ino | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino diff --git a/examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino b/examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino new file mode 100644 index 000000000..7ce1b6611 --- /dev/null +++ b/examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino @@ -0,0 +1,126 @@ + +/* Example of simple and stereo synthesis, + using Mozzi sonification library with output to an A2DP sink + (i.e. a Bluetooth speaker / headphone). + + + IMPORTANT: + - This example requires the ESP32-A2DP library by Phil Schatzmann: + https://github.com/pschatzmann/ESP32-A2DP/ + - This example works on ESP32, only + (Examples for other bluetooth-capable boards will follow, eventually.) + - You will want to adjust at least the "BLUETOOTH_DEVICE"-define, below! + + Technical notes: + The BT-lib expects to read samples at its own pace, so we cannot + just "push" samples at the MOZZI_AUDIO_RATE, but rather they get + "pulled" via get_data_frames(). + + We therefore need a custom buffering scheme, i.e we select + MOZZI_OUTPUT_EXTERNAL_CUSTOM as output mode, and keep an own, custom buffer + (which is visible to Mozzi via the two special functions + canBufferAudioOutput(), and audioOutput()). + + Note that the BT default sample rate is 44100, which is not one of the powers + of two that Mozzi likes so much (32768 in this example). Ignoring this would + "work", but everything would essentially play too fast, resulting in an upward + frequency shift. To fix this, we use a very crude sample rate adjustment, + simply by repeating some of the frames to stay in sync. + + Support for Bluetooth A2DP is also provided by the Espressif IDF, so this sketch *could* + be made to work without an external library. However this is fairly low level, + and Phil's ESP32-A2DP library does a great job of managing all the scary details. + + + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Tim Barrass 2012, CC by-nc-sa. + T. Friedrichsmeier 2024, CC by-nc-sa. +*/ + +// before including Mozzi.h, configure external audio output mode: +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO +#define MOZZI_AUDIO_RATE 32768 +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable + +#include +#include +#include // table for Oscils to play +#include +#include + +// devicce to connect to +#define BLUETOOTH_DEVICE "BKH 274" +#define BLUETOOTH_VOLUME 100 + +// Synthesis part +Oscil aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); +Oscil kEnv2(COS2048_DATA); + +CircularBuffer buf; +void audioOutput(const AudioOutput f) { + buf.write(f); +} + +bool canBufferAudioOutput() { + return !buf.isFull(); +} + + +BluetoothA2DPSource a2dp_source; +const int BT_RATE = 44100; +const int lag_per_frame = BT_RATE-MOZZI_AUDIO_RATE; +int lag = 0; +AudioOutput last_sample; + +int32_t get_data_frames(Frame *frame, int32_t frame_count) { + for (int i = 0; i < frame_count; ++i) { + lag += lag_per_frame; + if (lag > BT_RATE) { + lag -= BT_RATE; + } else { + if (!buf.isEmpty()) last_sample = buf.read(); + } + frame[i].channel1 = last_sample.l(); + frame[i].channel2 = last_sample.r(); + } + return frame_count; +} + +void setup() { + a2dp_source.set_auto_reconnect(false); + a2dp_source.start(BLUETOOTH_DEVICE, get_data_frames); + a2dp_source.set_volume(BLUETOOTH_VOLUME); + + aCos1.setFreq(440.f); + aCos2.setFreq(220.f); + kEnv1.setFreq(0.25f); + kEnv2.setFreq(0.30f); + startMozzi(); +} + +// Carry enveloppes +int env1, env2; + +void updateControl() { + env1 = kEnv1.next(); + env2 = kEnv2.next(); +} + + +AudioOutput_t updateAudio() { + return StereoOutput::from16Bit(aCos1.next() * env1, aCos2.next() * env2); +} + + +void loop() { + audioHook(); +} From ca960336836f03413cf0e42f6aa5af122e78d927 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 4 Feb 2024 14:58:52 +0100 Subject: [PATCH 110/215] UFix correct automatic add --- FixMath.h | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/FixMath.h b/FixMath.h index 217847afc..46e3c2539 100644 --- a/FixMath.h +++ b/FixMath.h @@ -74,6 +74,9 @@ #define FULLRANGE(N) ((1ULL<<(N)) - 1) #define NEEDEDNI(NI, _NI, RANGE, _RANGE) ((RANGE+_RANGE)>FULLRANGE(MAX(NI, _NI)) ? (MAX(NI, _NI)+1) : (MAX(NI, _NI))) #define NEEDEDNIMUL(NI, _NI, RANGE, _RANGE) ((RANGE*_RANGE)>FULLRANGE((NI+ _NI-1)) ? ((NI+ _NI)) : ((NI+ _NI-1))) +#define RANGEADD(NF, _NF, RANGE, _RANGE) ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF)))) // resulting range when adding +#define NEEDEDNIADD(NI, NF, RANGE) (RANGE > (FULLRANGE(NI+NF)) ? (NI+1) : (NI)) // NEEDED NI TO AVOID OVERFLOW +#define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (FULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (FULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1< +template class SFixMath; @@ -111,7 +114,7 @@ class SFixMath; @param NI The number of bits encoding the integer part. The integral part can range into [0, 2^NI -1] @param NF The number of bits encoding the fractional part */ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath { static_assert(NI+NF<=64, "The total width of a UFixMath cannot exceed 64bits"); @@ -166,9 +169,8 @@ class UFixMath @param uf An unsigned fixed type number which value can be represented in this type. @return A unsigned fixed type number */ - template + template // maybe move as free function to allow setting of the RANGE? UFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { - //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF-1,_NI+_NF-1))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -189,16 +191,17 @@ class UFixMath @return The result of the addition as a UFixMath. */ template - UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const + UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const { - constexpr byte new_NI = NEEDEDNI(NI,_NI,RANGE,_RANGE); + constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); + constexpr byte new_NI = NEEDEDNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); constexpr byte new_NF = MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; - UFixMath left(*this); - UFixMath right(op); + UFixMath left(*this); + UFixMath right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return UFixMath(tt,true); + return UFixMath(tt,true); } /** Addition with another type. Unsafe @@ -262,9 +265,9 @@ class UFixMath UFixMath operator* (const UFixMath<_NI,_NF>& op) const // TODO: check, throughfully, probably only true for UFix { //typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; - typedef typename IntegerType::unsigned_type return_type ; + typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); - return UFixMath<(tt,true); + return UFixMath(tt,true); } /** Multiplication with another type. Unsafe. @@ -1186,9 +1189,9 @@ inline SFixMath toSInt(T val) { -#undef MAX -#undef FULLRANGE -#undef NEEDEDNI +//#undef MAX +//#undef FULLRANGE +//#undef NEEDEDNI //#undef UBITSTOBYTES //#undef SBITSTOBYTES //#undef ONESBITMASK From dae84b7f92aa0a5d01c3dac024b725be31083dd1 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 4 Feb 2024 18:12:34 +0100 Subject: [PATCH 111/215] Converted template type to int8_t for FixMath, corrected safe shifts --- FixMath.h | 315 +++++++++++++++++++++++++++--------------------------- 1 file changed, 159 insertions(+), 156 deletions(-) diff --git a/FixMath.h b/FixMath.h index 46e3c2539..19c08db0d 100644 --- a/FixMath.h +++ b/FixMath.h @@ -77,6 +77,8 @@ #define RANGEADD(NF, _NF, RANGE, _RANGE) ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF)))) // resulting range when adding #define NEEDEDNIADD(NI, NF, RANGE) (RANGE > (FULLRANGE(NI+NF)) ? (NI+1) : (NI)) // NEEDED NI TO AVOID OVERFLOW #define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (FULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (FULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW +#define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (MOZZI_SHIFTR(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) + // Experiments /*#define NBITSREAL(X,N) (abs(X) < (1< - constexpr byte nBitsReal(T x, byte n=0) { + constexpr int8_t nBitsReal(T x, int8_t n=0) { if (abs(x) < ((T)1 << n)) { return n; } else { @@ -100,12 +102,12 @@ namespace MozziPrivate { - constexpr byte sBitsToBytes(byte N) { return (((N)>>3)+1);} - constexpr byte uBitsToBytes(byte N) { return (((N-1)>>3)+1);} + constexpr int8_t sBitsToBytes(int8_t N) { return (((N)>>3)+1);} + constexpr int8_t uBitsToBytes(int8_t N) { return (((N-1)>>3)+1);} } // Forward declaration -template +template class SFixMath; @@ -114,7 +116,7 @@ class SFixMath; @param NI The number of bits encoding the integer part. The integral part can range into [0, 2^NI -1] @param NF The number of bits encoding the fractional part */ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath { static_assert(NI+NF<=64, "The total width of a UFixMath cannot exceed 64bits"); @@ -169,7 +171,7 @@ class UFixMath @param uf An unsigned fixed type number which value can be represented in this type. @return A unsigned fixed type number */ - template // maybe move as free function to allow setting of the RANGE? + template // maybe move as free function to allow setting of the RANGE? UFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -178,7 +180,7 @@ class UFixMath @param uf An signed fixed type number which value can be represented in this type: sign is thus discarded. @return A unsigned fixed type number */ - template + template UFixMath(const SFixMath<_NI,_NF>& uf) { internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -190,15 +192,15 @@ class UFixMath @param op The UFixMath to be added. @return The result of the addition as a UFixMath. */ - template + template UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); - constexpr byte new_NI = NEEDEDNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = NEEDEDNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; - UFixMath left(*this); - UFixMath right(op); + UFixMath left(*this); + UFixMath right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); return UFixMath(tt,true); @@ -221,17 +223,18 @@ class UFixMath @param op The UFixMath to be subtracted. @return The result of the subtraction as a SFixMath. */ - template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. + //SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath(tt,true); + return SFixMath(tt,true); } @@ -249,9 +252,9 @@ class UFixMath /** Opposite of the number. @return The opposite numberas a SFixMath. */ - SFixMath operator-() const + SFixMath operator-() const { - return SFixMath( -(typename IntegerType::signed_type)(internal_value),true); + return SFixMath( -(typename IntegerType::signed_type)(internal_value),true); } //////// MULTIPLICATION OVERLOADS @@ -260,7 +263,7 @@ class UFixMath @param op The UFixMath to be multiplied. @return The result of the multiplication as a UFixMath. */ - template + template //UFixMath operator* (const UFixMath<_NI,_NF>& op) const UFixMath operator* (const UFixMath<_NI,_NF>& op) const // TODO: check, throughfully, probably only true for UFix { @@ -301,7 +304,7 @@ class UFixMath _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invAccurate() (_NF=2*NI+NF) @return The inverse of the number. */ - template + template UFixMath inv() const { return UFixMath<_NF,NF>(internal_value,true).invFast(); @@ -334,7 +337,7 @@ class UFixMath @param op The shift number @return The result of the shift as a UFixMath. */ - UFixMath operator>> (const byte op) const + UFixMath operator>> (const int8_t op) const { return UFixMath(internal_value>>op,true); } @@ -344,7 +347,7 @@ class UFixMath @param op The shift number @return The result of the shift as a UFixMath. */ - UFixMath operator<< (const byte op) const + UFixMath operator<< (const int8_t op) const { return UFixMath(internal_value< - UFixMath sR() + template + UFixMath sR() { - return UFixMath(internal_value,true); + return UFixMath(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @param op The shift number @return The result of the shift as a UFixMath of bigger size. */ - template - UFixMath sL() + template + UFixMath sL() { - return UFixMath(internal_value,true); + return UFixMath(internal_value,true); } //////// COMPARISON OVERLOADS - template + template bool operator> (const UFixMath<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()>right.asRaw(); } - template + template bool operator< (const UFixMath<_NI,_NF>& op) const { return op > *this; } - template + template bool operator== (const UFixMath<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()==right.asRaw(); } - template + template bool operator!= (const UFixMath<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()!=right.asRaw(); @@ -411,7 +414,7 @@ class UFixMath // Division. Might actually more misleading than helping. NON Working version below. /* - template + template UFixMath operator/(const UFixMath& op1, const UFixMath& op2) { typedef typename IntegerType< ((NI1-NI2+NF1-NF2+1)>>3)+1>::unsigned_type return_type ; @@ -434,13 +437,13 @@ class UFixMath /** The number of bits used to encode the integral part. @return The number of bits used to encode the integral part. */ - byte getNI(){return NI;} + int8_t getNI(){return NI;} /** The number of bits used to encode the fractional part. @return The number of bits used to encode the fractional part. */ - byte getNF(){return NF;} - + int8_t getNF(){return NF;} + private: internal_type internal_value; static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } @@ -453,96 +456,96 @@ class UFixMath /// Reverse overloadings, making a template here leads to an ambiguity, forcing us to specify them one by one?? // Multiplication -template +template inline UFixMath operator*(uint8_t op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(uint16_t op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(uint32_t op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(uint64_t op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(int8_t op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(int16_t op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(int32_t op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(int64_t op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(float op, const UFixMath& uf) {return uf*op;} -template +template inline UFixMath operator*(double op, const UFixMath& uf) {return uf*op;} // Addition -template +template inline UFixMath operator+(uint8_t op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(uint16_t op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(uint32_t op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(uint64_t op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(int8_t op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(int16_t op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(int32_t op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(int64_t op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(float op, const UFixMath& uf) {return uf+op;} -template +template inline UFixMath operator+(double op, const UFixMath& uf) {return uf+op;} // Substraction -template +template inline SFixMath operator-(uint8_t op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(uint16_t op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(uint32_t op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(uint64_t op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(int8_t op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(int16_t op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(int32_t op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(int64_t op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(float op, const UFixMath& uf) {return -uf+op;} -template +template inline SFixMath operator-(double op, const UFixMath& uf) {return -uf+op;} ////// Helper functions to build SFix from a normal type automatically @@ -586,7 +589,7 @@ inline UFixMath toUInt(T val) { @param NF The number of bits encoding the fractional part @note The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFixMath<7,0>. */ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class SFixMath { static_assert(NI+NF<64, "The total width of a SFixMath cannot exceed 63bits"); @@ -636,7 +639,7 @@ class SFixMath @param uf A signed fixed type number which value can be represented in this type. @return A signed fixed type number */ - template + template SFixMath(const SFixMath<_NI,_NF>& uf) { //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); @@ -647,7 +650,7 @@ class SFixMath @param uf A unsigned fixed type number which value can be represented in this type. @return A signed fixed type number */ - template + template SFixMath(const UFixMath<_NI,_NF>& uf) { internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -658,11 +661,11 @@ class SFixMath @param op The SFixMath to be added. @return The result of the addition as a SFixMath. */ - template + template SFixMath operator+ (const SFixMath<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI) + 1; - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI) + 1; + constexpr int8_t new_NF = MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; SFixMath left(*this); SFixMath right(op); @@ -688,11 +691,11 @@ class SFixMath @param op The SFixMath to be subtracted. @return The result of the subtraction as a SFixMath. */ - template + template SFixMath operator- (const SFixMath<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI) + 1; - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI) + 1; + constexpr int8_t new_NF = MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; SFixMath left(*this); SFixMath right(op); @@ -727,7 +730,7 @@ class SFixMath @param op The SFixMath to be multiplied. @return The result of the multiplication as a SFixMath. */ - template + template SFixMath operator* (const SFixMath<_NI,_NF>& op) const { typedef typename IntegerType::signed_type return_type ; @@ -766,7 +769,7 @@ class SFixMath _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invAccurate() (_NF=2*NI+NF) @return The inverse of the number. */ - template + template SFixMath inv() const { return SFixMath<_NF,NF>(internal_value,true).invFast(); @@ -790,7 +793,7 @@ class SFixMath @param op The shift number @return The result of the shift as a SFixMath. */ - SFixMath operator>> (const byte op) const + SFixMath operator>> (const int8_t op) const { return SFixMath(internal_value>>op,true); } @@ -800,7 +803,7 @@ class SFixMath @param op The shift number @return The result of the shift as a UFixMath. */ - SFixMath operator<< (const byte op) const + SFixMath operator<< (const int8_t op) const { return SFixMath(internal_value< + template SFixMath sR() { return SFixMath(internal_value,true); @@ -819,7 +822,7 @@ class SFixMath @param op The shift number @return The result of the shift as a UFixMath of bigger size. */ - template + template SFixMath sL() { return SFixMath(internal_value,true); @@ -828,37 +831,37 @@ class SFixMath //////// COMPARISON OVERLOADS - template + template bool operator> (const SFixMath<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()>right.asRaw(); } - template + template bool operator< (const SFixMath<_NI,_NF>& op) const { return op > *this; } - template + template bool operator== (const SFixMath<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()==right.asRaw(); } - template + template bool operator!= (const SFixMath<_NI,_NF>& op) const { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()!=right.asRaw(); @@ -878,12 +881,12 @@ class SFixMath /** The number of bits used to encode the integral part. @return The number of bits used to encode the integral part. */ - byte getNI(){return NI;} + int8_t getNI(){return NI;} /** The number of bits used to encode the fractional part. @return The number of bits used to encode the fractional part. */ - byte getNF(){return NF;} + int8_t getNF(){return NF;} private: @@ -896,96 +899,96 @@ class SFixMath /// Reverse overloadings, // Multiplication -template +template inline SFixMath operator*(uint8_t op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(uint16_t op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(uint32_t op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(uint64_t op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(int8_t op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(int16_t op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(int32_t op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(int64_t op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(float op, const SFixMath& uf) {return uf*op;} -template +template inline SFixMath operator*(double op, const SFixMath& uf) {return uf*op;} // Addition -template +template inline SFixMath operator+(uint8_t op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(uint16_t op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(uint32_t op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(uint64_t op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(int8_t op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(int16_t op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(int32_t op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(int64_t op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(float op, const SFixMath& uf) {return uf+op;} -template +template inline SFixMath operator+(double op, const SFixMath& uf) {return uf+op;} // Substraction -template +template inline SFixMath operator-(uint8_t op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(uint16_t op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(uint32_t op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(uint64_t op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(int8_t op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(int16_t op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(int32_t op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(int64_t op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(float op, const SFixMath& uf) {return (-uf)+op;} -template +template inline SFixMath operator-(double op, const SFixMath& uf) {return (-uf)+op;} @@ -1001,7 +1004,7 @@ inline SFixMath operator-(double op, const SFixMath& uf) {return @param op2 A UFixMath @return The result of the multiplication of op1 and op2. As a SFixMath */ -template +template inline SFixMath operator* (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { typedef typename IntegerType< MozziPrivate::sBitsToBytes(NI+_NI+NF+_NF)>::signed_type return_type ; @@ -1014,7 +1017,7 @@ inline SFixMath operator* (const SFixMath& op1, const UFix @param op2 A SFixMath @return The result of the multiplication of op1 and op2. As a SFixMath */ -template +template inline SFixMath operator* (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2*op1; @@ -1029,11 +1032,11 @@ inline SFixMath operator* (const UFixMath& op1, const SFix @param op2 A UFixMath @return The result of the addition of op1 and op2. As a SFixMath */ -template +template inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI) + 1; - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI) + 1; + constexpr int8_t new_NF = MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(op1); @@ -1047,7 +1050,7 @@ inline SFixMath operator+ (const SFixMath& op1 @param op2 A SFixMath @return The result of the addition of op1 and op2. As a SFixMath */ -template +template inline SFixMath operator+ (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2+op1; @@ -1060,11 +1063,11 @@ inline SFixMath operator+ (const UFixMath& op1 @param op2 A UFixMath @return The result of the subtraction of op1 by op2. As a SFixMath */ -template +template inline SFixMath operator- (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI) + 1; - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI) + 1; + constexpr int8_t new_NF = MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(op1); @@ -1078,7 +1081,7 @@ inline SFixMath operator- (const SFixMath& op1 @param op2 A SFixMath @return The result of the subtraction of op1 by op2. As a SFixMath */ -template +template inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return -op2+op1; @@ -1086,33 +1089,33 @@ inline SFixMath operator- (const UFixMath& op1 // Comparaison between SFixMath and UFixmath -template +template inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() > right.asRaw(); } -template +template inline bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() > right.asRaw(); } -template +template inline bool operator< (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2 > op1; } -template +template inline bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { return op2 > op1; @@ -1120,33 +1123,33 @@ inline bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 -template +template inline bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() == right.asRaw(); } -template +template inline bool operator== (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2 == op1; } -template +template inline bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr byte new_NI = MAX(NI, _NI); - constexpr byte new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MAX(NI, _NI); + constexpr int8_t new_NF = MAX(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() != right.asRaw(); } -template +template inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2 != op1; From 2ac43615a9ad8317bbdbc670515eedaf4c2ced6e Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 4 Feb 2024 21:34:37 +0100 Subject: [PATCH 112/215] Fixed compilator errors for UFix --- FixMath.h | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/FixMath.h b/FixMath.h index 19c08db0d..b59891446 100644 --- a/FixMath.h +++ b/FixMath.h @@ -68,15 +68,19 @@ #define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) +#define MIN(N1,N2) ((N1) > (N2) ? (N2) : (N1)) //#define UBITSTOBYTES(N) (((N-1)>>3)+1) //#define SBITSTOBYTES(N) (((N)>>3)+1) //#define ONESBITMASK(N) ((1ULL<<(N)) - 1) -#define FULLRANGE(N) ((1ULL<<(N)) - 1) -#define NEEDEDNI(NI, _NI, RANGE, _RANGE) ((RANGE+_RANGE)>FULLRANGE(MAX(NI, _NI)) ? (MAX(NI, _NI)+1) : (MAX(NI, _NI))) -#define NEEDEDNIMUL(NI, _NI, RANGE, _RANGE) ((RANGE*_RANGE)>FULLRANGE((NI+ _NI-1)) ? ((NI+ _NI)) : ((NI+ _NI-1))) +#define UFULLRANGE(N) ((1ULL<<(N)) - 1) // MAX value represented by an unsigned of N bits +#define SFULLRANGE(N) ((1ULL<<(N))) // MAX value represented by a signed of N bits +//#define NEEDEDNI(NI, _NI, RANGE, _RANGE) ((RANGE+_RANGE)>UFULLRANGE(MAX(NI, _NI)) ? (MAX(NI, _NI)+1) : (MAX(NI, _NI))) +//#define NEEDEDNIMUL(NI, _NI, RANGE, _RANGE) ((RANGE*_RANGE)>UFULLRANGE((NI+ _NI-1)) ? ((NI+ _NI)) : ((NI+ _NI-1))) // NEEDED NI TO AVOID OVERFLOW WHEN MULTIPLYING + #define RANGEADD(NF, _NF, RANGE, _RANGE) ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF)))) // resulting range when adding -#define NEEDEDNIADD(NI, NF, RANGE) (RANGE > (FULLRANGE(NI+NF)) ? (NI+1) : (NI)) // NEEDED NI TO AVOID OVERFLOW -#define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (FULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (FULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW +//#define NEEDEDNIADD(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (NI)) // NEEDED NI TO AVOID OVERFLOW +#define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW, GIVEN A RANGE +//#define NEEDEDNIMULEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1)) #define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (MOZZI_SHIFTR(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) @@ -107,7 +111,7 @@ namespace MozziPrivate { } // Forward declaration -template +template class SFixMath; @@ -116,7 +120,7 @@ class SFixMath; @param NI The number of bits encoding the integer part. The integral part can range into [0, 2^NI -1] @param NF The number of bits encoding the fractional part */ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath { static_assert(NI+NF<=64, "The total width of a UFixMath cannot exceed 64bits"); @@ -151,8 +155,13 @@ class UFixMath template UFixMath(T value,bool as_raw=false) { + if (as_raw) internal_value = value; - else internal_value = (internal_type(value) << NF); + else + { + //static_assert(NI>0, "Creating an UFixMath as an integer with NI=0 is not possible"); + internal_value = (internal_type(value) << NF); + } } @@ -265,12 +274,15 @@ class UFixMath */ template //UFixMath operator* (const UFixMath<_NI,_NF>& op) const - UFixMath operator* (const UFixMath<_NI,_NF>& op) const // TODO: check, throughfully, probably only true for UFix + //UFixMath operator* (const UFixMath<_NI,_NF>& op) const // TODO: check, throughfully, probably only true for UFix + UFixMath operator* (const UFixMath<_NI,_NF,_RANGE>& op) const // TODO: check, throughfully, probably only true for UFix { + constexpr int8_t NEW_NI = NEEDEDNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); //typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; - typedef typename IntegerType::unsigned_type return_type ; + //typedef typename IntegerType::unsigned_type return_type ; + typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); - return UFixMath(tt,true); + return UFixMath(tt,true); } /** Multiplication with another type. Unsafe. @@ -317,11 +329,13 @@ class UFixMath This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - UFixMath invAccurate() const + UFixMath invAccurate() const // The MIN is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) {/* static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); return UFixMath(internal_value,true).invFast(); */ //return UFixMath(internal_value,true).inv(); + + static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); return inv(); } @@ -1193,7 +1207,7 @@ inline SFixMath toSInt(T val) { //#undef MAX -//#undef FULLRANGE +//#undef UFULLRANGE //#undef NEEDEDNI //#undef UBITSTOBYTES //#undef SBITSTOBYTES From 0407b27b57652398cb133bb2d6e23611e2dfa8bc Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 4 Feb 2024 22:34:30 +0100 Subject: [PATCH 113/215] Correct add and sub for SFixMath --- FixMath.h | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/FixMath.h b/FixMath.h index b59891446..7de1ded74 100644 --- a/FixMath.h +++ b/FixMath.h @@ -81,6 +81,7 @@ //#define NEEDEDNIADD(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (NI)) // NEEDED NI TO AVOID OVERFLOW #define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW, GIVEN A RANGE //#define NEEDEDNIMULEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1)) +#define NEEDEDSNIEXTRA(NI, NF, RANGE) (RANGE > (SFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (SFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) #define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (MOZZI_SHIFTR(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) @@ -653,10 +654,10 @@ class SFixMath @param uf A signed fixed type number which value can be represented in this type. @return A signed fixed type number */ - template - SFixMath(const SFixMath<_NI,_NF>& uf) { + template + SFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MOZZI_SHIFTR((typename IntegerType::signed_type) uf.asRaw(),(_NF-NF)); } @@ -675,17 +676,19 @@ class SFixMath @param op The SFixMath to be added. @return The result of the addition as a SFixMath. */ - template - SFixMath operator+ (const SFixMath<_NI,_NF>& op) const + template + //SFixMath operator+ (const SFixMath<_NI,_NF>& op) const + SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI) + 1; + constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); constexpr int8_t new_NF = MAX(NF, _NF); - typedef typename IntegerType::unsigned_type return_type; + typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFixMath(tt,true); + return SFixMath(tt,true); } /** Addition with another type. Unsafe @@ -705,17 +708,18 @@ class SFixMath @param op The SFixMath to be subtracted. @return The result of the subtraction as a SFixMath. */ - template - SFixMath operator- (const SFixMath<_NI,_NF>& op) const + template + //SFixMath operator- (const SFixMath<_NI,_NF>& op) const + SFixMath operator- (const SFixMath<_NI,_NF, _RANGE>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI) + 1; + constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); constexpr int8_t new_NF = MAX(NF, _NF); - typedef typename IntegerType::unsigned_type return_type; + typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); - - return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath(tt,true); + return_type tt = return_type(left.asRaw()) - return_type(right.asRaw()); + return SFixMath(tt,true); } @@ -723,11 +727,11 @@ class SFixMath @param op The number to be subtracted. @return The result of the subtraction as a SFixMath. */ - template + template SFixMath operator- (const T op) const { return SFixMath(internal_value-(op< invAccurate() const + SFixMath invAccurate() const { return inv(); - } + } //////// SHIFTS OVERLOADS From c42ce35a0325922c1b649b5c8a1ab87f9af19eb7 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 5 Feb 2024 20:49:55 +0100 Subject: [PATCH 114/215] Mul, shifts and inv with Range for SFix --- FixMath.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/FixMath.h b/FixMath.h index 7de1ded74..5ac835807 100644 --- a/FixMath.h +++ b/FixMath.h @@ -276,7 +276,7 @@ class UFixMath template //UFixMath operator* (const UFixMath<_NI,_NF>& op) const //UFixMath operator* (const UFixMath<_NI,_NF>& op) const // TODO: check, throughfully, probably only true for UFix - UFixMath operator* (const UFixMath<_NI,_NF,_RANGE>& op) const // TODO: check, throughfully, probably only true for UFix + UFixMath operator* (const UFixMath<_NI,_NF,_RANGE>& op) const { constexpr int8_t NEW_NI = NEEDEDNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); //typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; @@ -737,9 +737,9 @@ class SFixMath /** Opposite of the number. @return The opposite numberas a SFixMath. */ - SFixMath operator-() const + SFixMath operator-() const { - return SFixMath(-internal_value,true); + return SFixMath(-internal_value,true); } //////// MULTIPLICATION OVERLOADS @@ -748,9 +748,11 @@ class SFixMath @param op The SFixMath to be multiplied. @return The result of the multiplication as a SFixMath. */ - template - SFixMath operator* (const SFixMath<_NI,_NF>& op) const + template + //SFixMath operator* (const SFixMath<_NI,_NF>& op) const + SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const { + constexpr int8_t NEW_NI = NEEDEDSNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); typedef typename IntegerType::signed_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return SFixMath(tt,true); @@ -798,7 +800,7 @@ class SFixMath This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - SFixMath invAccurate() const + SFixMath invAccurate() const { return inv(); } @@ -831,19 +833,19 @@ class SFixMath @return The result of the shift as a UFixMath of smaller size. */ template - SFixMath sR() + SFixMath sR() { - return SFixMath(internal_value,true); + return SFixMath(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @param op The shift number @return The result of the shift as a UFixMath of bigger size. */ - template - SFixMath sL() +template + SFixMath sL() { - return SFixMath(internal_value,true); + return SFixMath(internal_value,true); } From e822946a31d54a5872b0568ed16153c1a2ce30b3 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 5 Feb 2024 21:11:11 +0100 Subject: [PATCH 115/215] Added mixed add (S/U) with Range --- FixMath.h | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/FixMath.h b/FixMath.h index 5ac835807..19f7a41dd 100644 --- a/FixMath.h +++ b/FixMath.h @@ -216,6 +216,25 @@ class UFixMath return UFixMath(tt,true); } + /** Addition with a SFixMath. Safe. + @param op The UFixMath to be added. + @return The result of the addition as a SFixMath. + */ + template + SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const + { + constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = NEEDEDNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MAX(NF, _NF); + typedef typename IntegerType::signed_type return_type; + SFixMath left(*this); + SFixMath right(op); + + return_type tt = return_type(left.asRaw()) + right.asRaw(); + return SFixMath(tt,true); + } + + /** Addition with another type. Unsafe @param op The number to be added. @return The result of the addition as a UFixMath. @@ -1052,8 +1071,8 @@ inline SFixMath operator* (const UFixMath& op1, const SFix @param op2 A UFixMath @return The result of the addition of op1 and op2. As a SFixMath */ -template -inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +/*template +inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr int8_t new_NI = MAX(NI, _NI) + 1; constexpr int8_t new_NF = MAX(NF, _NF); @@ -1063,18 +1082,18 @@ inline SFixMath operator+ (const SFixMath& op1 SFixMath right(op2); return_type tt = return_type(left.asRaw()) + right.asRaw(); return SFixMath(tt,true); -} + }*/ /** Addition between a UFixMath and a SFixMath. Safe. @param op1 A UFixMath @param op2 A SFixMath @return The result of the addition of op1 and op2. As a SFixMath */ -template -inline SFixMath operator+ (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +template +SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) { return op2+op1; -} + } // Substraction between SFixMath and UFixMath (promotion to next SFixMath) From ed35b629772c8b6e2826b5a1f5cd590b2e66026d Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 5 Feb 2024 22:21:15 +0100 Subject: [PATCH 116/215] Added cross ADD and SUB --- FixMath.h | 62 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/FixMath.h b/FixMath.h index 19f7a41dd..6b8717f0c 100644 --- a/FixMath.h +++ b/FixMath.h @@ -221,10 +221,10 @@ class UFixMath @return The result of the addition as a SFixMath. */ template - SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const + SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = NEEDEDNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); constexpr int8_t new_NF = MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); @@ -710,6 +710,26 @@ class SFixMath return SFixMath(tt,true); } + /** Addition with a UFixMath. Safe. + @param op The UFixMath to be added. + @return The result of the addition as a SFixMath. + */ + /*template + SFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const + { + constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MAX(NF, _NF); + typedef typename IntegerType::signed_type return_type; + SFixMath left(*this); + SFixMath right(op); + + return_type tt = return_type(left.asRaw()) + right.asRaw(); + return SFixMath(tt,true); + }*/ + + + /** Addition with another type. Unsafe @param op The number to be added. @return The result of the addition as a UFixMath. @@ -741,6 +761,24 @@ class SFixMath return SFixMath(tt,true); } + /** Subtraction with a UFixMath. Safe. + @param op The SFixMath to be subtracted. + @return The result of the subtraction as a SFixMath. + */ + template + //SFixMath operator- (const SFixMath<_NI,_NF>& op) const + SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + { + constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MAX(NF, _NF); + typedef typename IntegerType::signed_type return_type; + SFixMath left(*this); + SFixMath right(op); + return_type tt = return_type(left.asRaw()) - return_type(right.asRaw()); + return SFixMath(tt,true); + } + /** Subtraction with another type. Unsafe @param op The number to be subtracted. @@ -1084,25 +1122,25 @@ inline SFixMath operator+ (const SFixMath return SFixMath(tt,true); }*/ -/** Addition between a UFixMath and a SFixMath. Safe. - @param op1 A UFixMath - @param op2 A SFixMath +/** Addition between a SFixMath and a UFixMath. Safe. + @param op1 A SFixMath + @param op2 A UFixMath @return The result of the addition of op1 and op2. As a SFixMath */ template -SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) +SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) { return op2+op1; } -// Substraction between SFixMath and UFixMath (promotion to next SFixMath) +// Substraction between UFixMath and SFixMath /** Subtraction between a SFixMath and a UFixMath. Safe. @param op1 A SFixMath @param op2 A UFixMath @return The result of the subtraction of op1 by op2. As a SFixMath */ -template +/*template inline SFixMath operator- (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { constexpr int8_t new_NI = MAX(NI, _NI) + 1; @@ -1113,18 +1151,18 @@ inline SFixMath operator- (const SFixMath& op1 SFixMath right(op2); return_type tt = return_type(left.asRaw()) - right.asRaw(); return SFixMath(tt,true); -} + }*/ /** Subtraction between a UFixMath and a SFixMath. Safe. @param op1 A UFixMath @param op2 A SFixMath @return The result of the subtraction of op1 by op2. As a SFixMath */ -template -inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +template +inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF, _RANGE>& op2) { return -op2+op1; -} + } // Comparaison between SFixMath and UFixmath From c038c78008df857454f8032250ae44e1a868829a Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 5 Feb 2024 22:42:17 +0100 Subject: [PATCH 117/215] Fixed cross MUL, cleanup --- FixMath.h | 92 ++++++++++++++----------------------------------------- 1 file changed, 23 insertions(+), 69 deletions(-) diff --git a/FixMath.h b/FixMath.h index 6b8717f0c..eaac72cb4 100644 --- a/FixMath.h +++ b/FixMath.h @@ -69,18 +69,10 @@ #define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) #define MIN(N1,N2) ((N1) > (N2) ? (N2) : (N1)) -//#define UBITSTOBYTES(N) (((N-1)>>3)+1) -//#define SBITSTOBYTES(N) (((N)>>3)+1) -//#define ONESBITMASK(N) ((1ULL<<(N)) - 1) #define UFULLRANGE(N) ((1ULL<<(N)) - 1) // MAX value represented by an unsigned of N bits #define SFULLRANGE(N) ((1ULL<<(N))) // MAX value represented by a signed of N bits -//#define NEEDEDNI(NI, _NI, RANGE, _RANGE) ((RANGE+_RANGE)>UFULLRANGE(MAX(NI, _NI)) ? (MAX(NI, _NI)+1) : (MAX(NI, _NI))) -//#define NEEDEDNIMUL(NI, _NI, RANGE, _RANGE) ((RANGE*_RANGE)>UFULLRANGE((NI+ _NI-1)) ? ((NI+ _NI)) : ((NI+ _NI-1))) // NEEDED NI TO AVOID OVERFLOW WHEN MULTIPLYING - #define RANGEADD(NF, _NF, RANGE, _RANGE) ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF)))) // resulting range when adding -//#define NEEDEDNIADD(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (NI)) // NEEDED NI TO AVOID OVERFLOW #define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW, GIVEN A RANGE -//#define NEEDEDNIMULEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1)) #define NEEDEDSNIEXTRA(NI, NF, RANGE) (RANGE > (SFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (SFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) #define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (MOZZI_SHIFTR(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) @@ -305,6 +297,19 @@ class UFixMath return UFixMath(tt,true); } + /** Multiplication with a SFixMath. Safe. + @param op The SFixMath to be multiplied. + @return The result of the multiplication as a SFixMath. + */ + template + SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const + { + constexpr int8_t NEW_NI = NEEDEDSNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); + typedef typename IntegerType::signed_type return_type ; + return_type tt = return_type(internal_value)*op.asRaw(); + return SFixMath(tt,true); + } + /** Multiplication with another type. Unsafe. @param op The number to be multiplied. @return The result of the multiplication as a UFixMath. @@ -1081,47 +1086,13 @@ inline SFixMath operator-(double op, const SFixMath& uf) {return @param op2 A UFixMath @return The result of the multiplication of op1 and op2. As a SFixMath */ -template -inline SFixMath operator* (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) -{ - typedef typename IntegerType< MozziPrivate::sBitsToBytes(NI+_NI+NF+_NF)>::signed_type return_type ; - return_type tt = return_type(op1.asRaw())*op2.asRaw(); - return SFixMath(tt,true); -} - -/** Multiplication between a UFixMath and a SFixMath. Safe. - @param op1 A UFixMath - @param op2 A SFixMath - @return The result of the multiplication of op1 and op2. As a SFixMath -*/ -template -inline SFixMath operator* (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +template +inline SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op1, const UFixMath& op2) { return op2*op1; } -// Addition between SFixMath and UFixMath (promotion to next SFixMath) - - -/** Addition between a SFixMath and a UFixMath. Safe. - @param op1 A SFixMath - @param op2 A UFixMath - @return The result of the addition of op1 and op2. As a SFixMath -*/ -/*template -inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) -{ - constexpr int8_t new_NI = MAX(NI, _NI) + 1; - constexpr int8_t new_NF = MAX(NF, _NF); - - typedef typename IntegerType::signed_type return_type; - SFixMath left(op1); - SFixMath right(op2); - return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFixMath(tt,true); - }*/ - /** Addition between a SFixMath and a UFixMath. Safe. @param op1 A SFixMath @param op2 A UFixMath @@ -1133,25 +1104,6 @@ SFixMath -inline SFixMath operator- (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) -{ - constexpr int8_t new_NI = MAX(NI, _NI) + 1; - constexpr int8_t new_NF = MAX(NF, _NF); - - typedef typename IntegerType::signed_type return_type; - SFixMath left(op1); - SFixMath right(op2); - return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath(tt,true); - }*/ /** Subtraction between a UFixMath and a SFixMath. Safe. @param op1 A UFixMath @@ -1269,12 +1221,14 @@ inline SFixMath toSInt(T val) { -//#undef MAX -//#undef UFULLRANGE -//#undef NEEDEDNI -//#undef UBITSTOBYTES -//#undef SBITSTOBYTES -//#undef ONESBITMASK +#undef MAX +#undef MIN +#undef UFULLRANGE +#undef SFULLRANGE +#undef RANGEADD +#undef NEEDEDNIEXTRA +#undef NEEDEDSNIEXTRA +#undef RANGESHIFT #endif From aee4ff2563afd7cf9c81eb83dba93ea451ceee61 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 5 Feb 2024 22:53:17 +0100 Subject: [PATCH 118/215] Cleanup --- FixMath.h | 93 ++++++++++++------------------------------------------- 1 file changed, 19 insertions(+), 74 deletions(-) diff --git a/FixMath.h b/FixMath.h index eaac72cb4..161055960 100644 --- a/FixMath.h +++ b/FixMath.h @@ -146,15 +146,10 @@ class UFixMath @return An unsigned fixed point number */ template - UFixMath(T value,bool as_raw=false) - { + UFixMath(T value,bool as_raw=false) { if (as_raw) internal_value = value; - else - { - //static_assert(NI>0, "Creating an UFixMath as an integer with NI=0 is not possible"); - internal_value = (internal_type(value) << NF); - } + else internal_value = (internal_type(value) << NF); } @@ -173,11 +168,13 @@ class UFixMath @param uf An unsigned fixed type number which value can be represented in this type. @return A unsigned fixed type number */ - template // maybe move as free function to allow setting of the RANGE? + template UFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } + + // IS THAT REALLY NEEDED? /** Constructor from another SFixMath. @param uf An signed fixed type number which value can be represented in this type: sign is thus discarded. @return A unsigned fixed type number @@ -245,7 +242,6 @@ class UFixMath @return The result of the subtraction as a SFixMath. */ template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - //SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const { constexpr int8_t new_NI = MAX(NI, _NI); @@ -271,7 +267,7 @@ class UFixMath /** Opposite of the number. - @return The opposite numberas a SFixMath. + @return The opposite number as a SFixMath. */ SFixMath operator-() const { @@ -285,13 +281,9 @@ class UFixMath @return The result of the multiplication as a UFixMath. */ template - //UFixMath operator* (const UFixMath<_NI,_NF>& op) const - //UFixMath operator* (const UFixMath<_NI,_NF>& op) const // TODO: check, throughfully, probably only true for UFix UFixMath operator* (const UFixMath<_NI,_NF,_RANGE>& op) const { constexpr int8_t NEW_NI = NEEDEDNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); - //typedef typename IntegerType< ((NI+_NI+NF+_NF-1)>>3)+1>::unsigned_type return_type ; - //typedef typename IntegerType::unsigned_type return_type ; typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return UFixMath(tt,true); @@ -332,7 +324,6 @@ class UFixMath UFixMath invFast() const { static_assert(NI+NF<=63, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); - //return UFixMath((ONESBITMASK(NI+NF)/internal_value),true); return UFixMath((onesbitmask()/internal_value),true); } @@ -355,11 +346,7 @@ class UFixMath @return The inverse of the number. */ UFixMath invAccurate() const // The MIN is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) - {/* - static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); - return UFixMath(internal_value,true).invFast(); */ - //return UFixMath(internal_value,true).inv(); - + { static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); return inv(); } @@ -451,17 +438,6 @@ class UFixMath } - // Division. Might actually more misleading than helping. NON Working version below. - /* - template - UFixMath operator/(const UFixMath& op1, const UFixMath& op2) - { - typedef typename IntegerType< ((NI1-NI2+NF1-NF2+1)>>3)+1>::unsigned_type return_type ; - return_type tt = (return_type(op1.getInt())<<(NF1-NF2))/op2.getInt(); - return UFixMath(tt,true); - } - */ - /** Returns the value as floating point number. @return The floating point value. @@ -486,14 +462,10 @@ class UFixMath private: internal_type internal_value; static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } - //static constexpr typename IntegerType::unsigned_type onesbitmaskfull() { return (typename IntegerType::unsigned_type) ((1ULL<< (NI*2+NF*2)) - 1); } - }; -/// Reverse overloadings, making a template here leads to an ambiguity, forcing us to specify them one by one?? - // Multiplication template inline UFixMath operator*(uint8_t op, const UFixMath& uf) {return uf*op;} @@ -680,7 +652,6 @@ class SFixMath */ template SFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { - //internal_value = MOZZI_SHIFTR((typename IntegerType<((MAX(NI+NF,_NI+_NF))>>3)+1>::unsigned_type) uf.asRaw(),(_NF-NF)); internal_value = MOZZI_SHIFTR((typename IntegerType::signed_type) uf.asRaw(),(_NF-NF)); } @@ -701,7 +672,6 @@ class SFixMath @return The result of the addition as a SFixMath. */ template - //SFixMath operator+ (const SFixMath<_NI,_NF>& op) const SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); @@ -714,25 +684,6 @@ class SFixMath return_type tt = return_type(left.asRaw()) + right.asRaw(); return SFixMath(tt,true); } - - /** Addition with a UFixMath. Safe. - @param op The UFixMath to be added. - @return The result of the addition as a SFixMath. - */ - /*template - SFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const - { - constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MAX(NF, _NF); - typedef typename IntegerType::signed_type return_type; - SFixMath left(*this); - SFixMath right(op); - - return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFixMath(tt,true); - }*/ - /** Addition with another type. Unsafe @@ -753,7 +704,6 @@ class SFixMath @return The result of the subtraction as a SFixMath. */ template - //SFixMath operator- (const SFixMath<_NI,_NF>& op) const SFixMath operator- (const SFixMath<_NI,_NF, _RANGE>& op) const { constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); @@ -771,7 +721,6 @@ class SFixMath @return The result of the subtraction as a SFixMath. */ template - //SFixMath operator- (const SFixMath<_NI,_NF>& op) const SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const { constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); @@ -811,7 +760,6 @@ class SFixMath @return The result of the multiplication as a SFixMath. */ template - //SFixMath operator* (const SFixMath<_NI,_NF>& op) const SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const { constexpr int8_t NEW_NI = NEEDEDSNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); @@ -843,7 +791,6 @@ class SFixMath SFixMath invFast() const { static_assert(NI+NF<=62, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); - //return SFixMath((ONESBITMASK(NI+NF)/internal_value),true); return SFixMath((onesbitmask()/internal_value),true); } @@ -974,8 +921,6 @@ template private: internal_type internal_value; static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } - //static constexpr typename IntegerType::signed_type onesbitmaskfull() { return (typename IntegerType::signed_type) ((1ULL<< (NI*2+NF*2)) - 1); } - }; /// Reverse overloadings, @@ -1081,18 +1026,6 @@ inline SFixMath operator-(double op, const SFixMath& uf) {return -/** Multiplication between a SFixMath and a UFixMath. Safe. - @param op1 A SFixMath - @param op2 A UFixMath - @return The result of the multiplication of op1 and op2. As a SFixMath -*/ -template -inline SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op1, const UFixMath& op2) -{ - return op2*op1; -} - - /** Addition between a SFixMath and a UFixMath. Safe. @param op1 A SFixMath @param op2 A UFixMath @@ -1116,6 +1049,18 @@ inline SFixMath +inline SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op1, const UFixMath& op2) +{ + return op2*op1; +} + // Comparaison between SFixMath and UFixmath template From 19de8a50b4398e609dcd42d50278d38c2b6a72e3 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 5 Feb 2024 23:04:57 +0100 Subject: [PATCH 119/215] Removed unsafe function to std SFixMath (activate with #define FIXMATHUNSAFE before including FixMath Added missing inline --- FixMath.h | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/FixMath.h b/FixMath.h index 161055960..041c7d6f7 100644 --- a/FixMath.h +++ b/FixMath.h @@ -63,6 +63,7 @@ #ifndef FIXMATH2_H_ #define FIXMATH2_H_ + #include #include "IntegerType.h" @@ -223,7 +224,7 @@ class UFixMath return SFixMath(tt,true); } - +#ifdef FIXMATHUNSAFE /** Addition with another type. Unsafe @param op The number to be added. @return The result of the addition as a UFixMath. @@ -233,7 +234,7 @@ class UFixMath { return UFixMath(internal_value+((internal_type)op<(tt,true); } - + #ifdef FIXMATHUNSAFE /** Subtraction with another type. Unsafe @param op The number to be subtracted. @return The result of the subtraction as a UFixMath. @@ -264,7 +265,7 @@ class UFixMath { return UFixMath(internal_value-((internal_type)op<(tt,true); } + #ifdef FIXMATHUNSAFE /** Multiplication with another type. Unsafe. @param op The number to be multiplied. @return The result of the multiplication as a UFixMath. @@ -311,7 +313,7 @@ class UFixMath { return UFixMath(internal_value*op,true); } - +#endif //////// INVERSE @@ -368,6 +370,8 @@ class UFixMath return UFixMath(internal_value>>op,true); } + + #ifdef FIXMATHUNSAFE /** Left shift. This can overflow if you shift to a value that cannot be represented. Better to use .sL() if possible instead. @param op The shift number @@ -377,7 +381,8 @@ class UFixMath { return UFixMath(internal_value< inline UFixMath operator*(uint8_t op, const UFixMath& uf) {return uf*op;} @@ -558,7 +563,7 @@ inline SFixMath operator-(float op, const UFixMath& uf) {return template inline SFixMath operator-(double op, const UFixMath& uf) {return -uf+op;} - +#endif ////// Helper functions to build SFix from a normal type automatically @@ -685,7 +690,7 @@ class SFixMath return SFixMath(tt,true); } - +#ifdef FIXMATHUNSAFE /** Addition with another type. Unsafe @param op The number to be added. @return The result of the addition as a UFixMath. @@ -695,7 +700,7 @@ class SFixMath { return SFixMath(internal_value+(op<(tt,true); } - + #ifdef FIXMATHUNSAFE /** Subtraction with another type. Unsafe @param op The number to be subtracted. @return The result of the subtraction as a SFixMath. @@ -743,7 +748,7 @@ class SFixMath { return SFixMath(internal_value-(op<(tt,true); } + #ifdef FIXMATHUNSAFE /** Multiplication with another type. Unsafe. @param op The number to be multiplied. @return The result of the multiplication as a UFixMath. @@ -777,6 +783,7 @@ class SFixMath { return SFixMath(internal_value*op,true); } +#endif //////// INVERSE @@ -827,6 +834,7 @@ class SFixMath return SFixMath(internal_value>>op,true); } + #ifdef FIXMATHUNSAFE /** Left shift. This can overflow if you shift to a value that cannot be represented. Better to use .sL() if possible instead. @param op The shift number @@ -836,6 +844,7 @@ class SFixMath { return SFixMath(internal_value< static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); } }; + +#ifdef FIXMATHUNSAFE /// Reverse overloadings, // Multiplication @@ -1018,8 +1029,7 @@ inline SFixMath operator-(float op, const SFixMath& uf) {return template inline SFixMath operator-(double op, const SFixMath& uf) {return (-uf)+op;} - - +#endif @@ -1032,7 +1042,7 @@ inline SFixMath operator-(double op, const SFixMath& uf) {return @return The result of the addition of op1 and op2. As a SFixMath */ template -SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) +inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) { return op2+op1; } From 0fb44fb433246b507fc68504e2e60e05ed5b6f97 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 5 Feb 2024 23:33:43 +0100 Subject: [PATCH 120/215] Small optimization of UFULLRANGE macro (overflow one step later) --- FixMath.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FixMath.h b/FixMath.h index 041c7d6f7..55e61c44f 100644 --- a/FixMath.h +++ b/FixMath.h @@ -70,8 +70,9 @@ #define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. #define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) #define MIN(N1,N2) ((N1) > (N2) ? (N2) : (N1)) -#define UFULLRANGE(N) ((1ULL<<(N)) - 1) // MAX value represented by an unsigned of N bits +//#define UFULLRANGE(N) ((1ULL<<(N)) - 1) // MAX value represented by an unsigned of N bits #define SFULLRANGE(N) ((1ULL<<(N))) // MAX value represented by a signed of N bits +#define UFULLRANGE(N) (((1ULL<<(N-1)) - 1) + (1ULL << (N-1))) #define RANGEADD(NF, _NF, RANGE, _RANGE) ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF)))) // resulting range when adding #define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW, GIVEN A RANGE #define NEEDEDSNIEXTRA(NI, NF, RANGE) (RANGE > (SFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (SFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) From a99b574d9d511a6a874a89fdd9d064470051f05e Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 5 Feb 2024 23:44:05 +0100 Subject: [PATCH 121/215] Fixed cross construction of FixMath types --- FixMath.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FixMath.h b/FixMath.h index 55e61c44f..16e7863d4 100644 --- a/FixMath.h +++ b/FixMath.h @@ -176,13 +176,13 @@ class UFixMath } - // IS THAT REALLY NEEDED? - /** Constructor from another SFixMath. + + /** Constructor from a SFixMath. @param uf An signed fixed type number which value can be represented in this type: sign is thus discarded. @return A unsigned fixed type number */ - template - UFixMath(const SFixMath<_NI,_NF>& uf) { + template + UFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -662,12 +662,12 @@ class SFixMath } - /** Constructor from another UFixMath. + /** Constructor from an UFixMath. @param uf A unsigned fixed type number which value can be represented in this type. @return A signed fixed type number */ - template - SFixMath(const UFixMath<_NI,_NF>& uf) { + template + SFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } From 15aeeb46aa328fc3d6b3962db6c311ba24bc0583 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 7 Feb 2024 22:30:22 +0100 Subject: [PATCH 122/215] Added cross converters for S/UFix --- FixMath.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/FixMath.h b/FixMath.h index 16e7863d4..64a59de5f 100644 --- a/FixMath.h +++ b/FixMath.h @@ -442,8 +442,14 @@ class UFixMath UFixMath right(op); return left.asRaw()!=right.asRaw(); } - - + + /** Returns the number as a SFixMath of same range and precision. This is more optimized than a cast. + @return a SFixMath + */ + SFixMath asSFix() + { + return SFixMath(internal_value,true); + } /** Returns the value as floating point number. @return The floating point value. @@ -905,6 +911,15 @@ template SFixMath right(op); return left.asRaw()!=right.asRaw(); } + + + /** Returns the number as a UFixMath of same (positive) range and precision. The initial value has to be positive to return something correct. This is more optimized than a cast. + @return a UFixMath + */ + UFixMath asUFix() + { + return UFixMath(internal_value,true); + } /** Returns the value as floating point number. From 53841b638f62de71362d461145a984c39515f300 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 7 Feb 2024 22:50:47 +0100 Subject: [PATCH 123/215] Replaced all macro with constexpr in FixMath --- FixMath.h | 185 +++++++++++++++++++++++++++++------------------------- 1 file changed, 98 insertions(+), 87 deletions(-) diff --git a/FixMath.h b/FixMath.h index 64a59de5f..31b8a97a6 100644 --- a/FixMath.h +++ b/FixMath.h @@ -67,16 +67,18 @@ #include #include "IntegerType.h" -#define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. -#define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) -#define MIN(N1,N2) ((N1) > (N2) ? (N2) : (N1)) +//#define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. + +//#define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) +//#define MIN(N1,N2) ((N1) > (N2) ? (N2) : (N1)) //#define UFULLRANGE(N) ((1ULL<<(N)) - 1) // MAX value represented by an unsigned of N bits -#define SFULLRANGE(N) ((1ULL<<(N))) // MAX value represented by a signed of N bits -#define UFULLRANGE(N) (((1ULL<<(N-1)) - 1) + (1ULL << (N-1))) -#define RANGEADD(NF, _NF, RANGE, _RANGE) ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF)))) // resulting range when adding -#define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW, GIVEN A RANGE -#define NEEDEDSNIEXTRA(NI, NF, RANGE) (RANGE > (SFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (SFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) -#define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (MOZZI_SHIFTR(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) +//#define SFULLRANGE(N) ((1ULL<<(N))) // MAX value represented by a signed of N bits +//#define UFULLRANGE(N) (((1ULL<<(N-1)) - 1) + (1ULL << (N-1))) +//#define RANGEADD(NF, _NF, RANGE, _RANGE) ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF)))) // resulting range when adding +//#define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW, GIVEN A RANGE +//#define NEEDEDSNIEXTRA(NI, NF, RANGE) (RANGE > (SFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (SFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) +//#define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (MOZZI_SHIFTR(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) +//#define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (mozzi_shiftr(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) // Experiments @@ -101,12 +103,21 @@ namespace MozziPrivate { + template constexpr T shiftR(T x, int8_t bits) {return (bits > 0 ? (x >> (bits)) : (x << (-bits)));} constexpr int8_t sBitsToBytes(int8_t N) { return (((N)>>3)+1);} constexpr int8_t uBitsToBytes(int8_t N) { return (((N-1)>>3)+1);} + template constexpr T MAX(T N1, T N2) { return (N1) > (N2) ? (N1) : (N2);} + template constexpr T MIN(T N1, T N2) { return (N1) > (N2) ? (N2) : (N1);} + constexpr uint64_t sFullRange(int8_t N) { return uint64_t(1)< _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF))));} + constexpr int8_t neededNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (uFullRange(NI+NF)) ? (NI+1) : (RANGE > (uFullRange(NI+NF-1)) ? (NI) : (NI-1)));} + constexpr int8_t neededSNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (sFullRange(NI+NF)) ? (NI+1) : (RANGE > (sFullRange(NI+NF-1)) ? (NI) : (NI-1)));} + constexpr uint64_t RANGESHIFT(int8_t N, int8_t SH, uint64_t RANGE) { return ((SH < N) ? (RANGE) : (shiftR(RANGE,(N-SH))));} } // Forward declaration -template +template class SFixMath; @@ -115,7 +126,7 @@ class SFixMath; @param NI The number of bits encoding the integer part. The integral part can range into [0, 2^NI -1] @param NF The number of bits encoding the fractional part */ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. +template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. class UFixMath { static_assert(NI+NF<=64, "The total width of a UFixMath cannot exceed 64bits"); @@ -172,7 +183,7 @@ class UFixMath */ template UFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -183,7 +194,7 @@ class UFixMath */ template UFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -194,11 +205,11 @@ class UFixMath @return The result of the addition as a UFixMath. */ template - UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const + UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const { - constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = NEEDEDNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = MozziPrivate::neededNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); typedef typename IntegerType::unsigned_type return_type; UFixMath left(*this); UFixMath right(op); @@ -212,11 +223,11 @@ class UFixMath @return The result of the addition as a SFixMath. */ template - SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const + SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const { - constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -243,17 +254,17 @@ class UFixMath @param op The UFixMath to be subtracted. @return The result of the subtraction as a SFixMath. */ - template // We do not have the +1 after MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + template // We do not have the +1 after MozziPrivate::MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. + SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath(tt,true); + return SFixMath(tt,true); } #ifdef FIXMATHUNSAFE @@ -283,9 +294,9 @@ class UFixMath @return The result of the multiplication as a UFixMath. */ template - UFixMath operator* (const UFixMath<_NI,_NF,_RANGE>& op) const + UFixMath operator* (const UFixMath<_NI,_NF,_RANGE>& op) const { - constexpr int8_t NEW_NI = NEEDEDNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); + constexpr int8_t NEW_NI = MozziPrivate::neededNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return UFixMath(tt,true); @@ -296,9 +307,9 @@ class UFixMath @return The result of the multiplication as a SFixMath. */ template - SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const + SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const { - constexpr int8_t NEW_NI = NEEDEDSNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); + constexpr int8_t NEW_NI = MozziPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); typedef typename IntegerType::signed_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return SFixMath(tt,true); @@ -348,7 +359,7 @@ class UFixMath This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - UFixMath invAccurate() const // The MIN is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) + UFixMath invAccurate() const // The MozziPrivate::MIN is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) { static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); return inv(); @@ -389,9 +400,9 @@ class UFixMath @return The result of the shift as a UFixMath of smaller size. */ template - UFixMath sR() + UFixMath sR() { - return UFixMath(internal_value,true); + return UFixMath(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @@ -399,9 +410,9 @@ class UFixMath @return The result of the shift as a UFixMath of bigger size. */ template - UFixMath sL() + UFixMath sL() { - return UFixMath(internal_value,true); + return UFixMath(internal_value,true); } @@ -410,8 +421,8 @@ class UFixMath template bool operator> (const UFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()>right.asRaw(); @@ -426,8 +437,8 @@ class UFixMath template bool operator== (const UFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()==right.asRaw(); @@ -436,8 +447,8 @@ class UFixMath template bool operator!= (const UFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()!=right.asRaw(); @@ -664,7 +675,7 @@ class SFixMath */ template SFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType::signed_type) uf.asRaw(),(_NF-NF)); + internal_value = MozziPrivate::shiftR((typename IntegerType::signed_type) uf.asRaw(),(_NF-NF)); } @@ -674,7 +685,7 @@ class SFixMath */ template SFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { - internal_value = MOZZI_SHIFTR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS @@ -684,11 +695,11 @@ class SFixMath @return The result of the addition as a SFixMath. */ template - SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const + SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const { - constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -716,11 +727,11 @@ class SFixMath @return The result of the subtraction as a SFixMath. */ template - SFixMath operator- (const SFixMath<_NI,_NF, _RANGE>& op) const + SFixMath operator- (const SFixMath<_NI,_NF, _RANGE>& op) const { - constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -733,11 +744,11 @@ class SFixMath @return The result of the subtraction as a SFixMath. */ template - SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const { - constexpr uint64_t new_RANGE = RANGEADD(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = NEEDEDSNIEXTRA(MAX(NI,_NI),MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); + constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -772,9 +783,9 @@ class SFixMath @return The result of the multiplication as a SFixMath. */ template - SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const + SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const { - constexpr int8_t NEW_NI = NEEDEDSNIEXTRA(NI+_NI, NF+_NF, RANGE*_RANGE); + constexpr int8_t NEW_NI = MozziPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); typedef typename IntegerType::signed_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); return SFixMath(tt,true); @@ -823,7 +834,7 @@ class SFixMath This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - SFixMath invAccurate() const + SFixMath invAccurate() const { return inv(); } @@ -858,9 +869,9 @@ class SFixMath @return The result of the shift as a UFixMath of smaller size. */ template - SFixMath sR() + SFixMath sR() { - return SFixMath(internal_value,true); + return SFixMath(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @@ -868,9 +879,9 @@ class SFixMath @return The result of the shift as a UFixMath of bigger size. */ template - SFixMath sL() + SFixMath sL() { - return SFixMath(internal_value,true); + return SFixMath(internal_value,true); } @@ -879,8 +890,8 @@ template template bool operator> (const SFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()>right.asRaw(); @@ -895,8 +906,8 @@ template template bool operator== (const SFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()==right.asRaw(); @@ -905,8 +916,8 @@ template template bool operator!= (const SFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()!=right.asRaw(); @@ -1058,7 +1069,7 @@ inline SFixMath operator-(double op, const SFixMath& uf) {return @return The result of the addition of op1 and op2. As a SFixMath */ template -inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) +inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) { return op2+op1; } @@ -1070,7 +1081,7 @@ inline SFixMath -inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF, _RANGE>& op2) +inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF, _RANGE>& op2) { return -op2+op1; } @@ -1082,7 +1093,7 @@ inline SFixMath -inline SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op1, const UFixMath& op2) +inline SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op1, const UFixMath& op2) { return op2*op1; } @@ -1092,8 +1103,8 @@ inline SFixMath inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() > right.asRaw(); @@ -1102,8 +1113,8 @@ inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 template inline bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() > right.asRaw(); @@ -1126,8 +1137,8 @@ inline bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 template inline bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() == right.asRaw(); @@ -1142,8 +1153,8 @@ inline bool operator== (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 template inline bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr int8_t new_NI = MAX(NI, _NI); - constexpr int8_t new_NF = MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() != right.asRaw(); @@ -1192,14 +1203,14 @@ inline SFixMath toSInt(T val) { -#undef MAX -#undef MIN -#undef UFULLRANGE -#undef SFULLRANGE -#undef RANGEADD -#undef NEEDEDNIEXTRA -#undef NEEDEDSNIEXTRA -#undef RANGESHIFT +// #undef MAX +// #undef MIN +// #undef UFULLRANGE +// #undef SFULLRANGE +// #undef RANGEADD +// #undef NEEDEDNIEXTRA +// #undef NEEDEDSNIEXTRA +// #undef RANGESHIFT #endif From 67e39bf8a4af06aa1e5c78711d54dc50daa3c080 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 7 Feb 2024 23:40:41 +0100 Subject: [PATCH 124/215] Fixed conflicting Macros/constexpr for some platforms --- FixMath.h | 116 +++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/FixMath.h b/FixMath.h index 31b8a97a6..60b2ecf49 100644 --- a/FixMath.h +++ b/FixMath.h @@ -106,8 +106,8 @@ namespace MozziPrivate { template constexpr T shiftR(T x, int8_t bits) {return (bits > 0 ? (x >> (bits)) : (x << (-bits)));} constexpr int8_t sBitsToBytes(int8_t N) { return (((N)>>3)+1);} constexpr int8_t uBitsToBytes(int8_t N) { return (((N-1)>>3)+1);} - template constexpr T MAX(T N1, T N2) { return (N1) > (N2) ? (N1) : (N2);} - template constexpr T MIN(T N1, T N2) { return (N1) > (N2) ? (N2) : (N1);} + template constexpr T mozziMax(T N1, T N2) { return (N1) > (N2) ? (N1) : (N2);} + template constexpr T mozziMin(T N1, T N2) { return (N1) > (N2) ? (N2) : (N1);} constexpr uint64_t sFullRange(int8_t N) { return uint64_t(1)< _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF))));} @@ -183,7 +183,7 @@ class UFixMath */ template UFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { - internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -194,7 +194,7 @@ class UFixMath */ template UFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { - internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } @@ -205,11 +205,11 @@ class UFixMath @return The result of the addition as a UFixMath. */ template - UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const + UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::neededNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::unsigned_type return_type; UFixMath left(*this); UFixMath right(op); @@ -223,11 +223,11 @@ class UFixMath @return The result of the addition as a SFixMath. */ template - SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const + SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -254,17 +254,17 @@ class UFixMath @param op The UFixMath to be subtracted. @return The result of the subtraction as a SFixMath. */ - template // We do not have the +1 after MozziPrivate::MAX(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + template // We do not have the +1 after MozziPrivate::mozziMax(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. + SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath(tt,true); + return SFixMath(tt,true); } #ifdef FIXMATHUNSAFE @@ -359,7 +359,7 @@ class UFixMath This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - UFixMath invAccurate() const // The MozziPrivate::MIN is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) + UFixMath invAccurate() const // The MozziPrivate::mozziMin is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) { static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); return inv(); @@ -400,9 +400,9 @@ class UFixMath @return The result of the shift as a UFixMath of smaller size. */ template - UFixMath sR() + UFixMath sR() { - return UFixMath(internal_value,true); + return UFixMath(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @@ -410,9 +410,9 @@ class UFixMath @return The result of the shift as a UFixMath of bigger size. */ template - UFixMath sL() + UFixMath sL() { - return UFixMath(internal_value,true); + return UFixMath(internal_value,true); } @@ -421,8 +421,8 @@ class UFixMath template bool operator> (const UFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()>right.asRaw(); @@ -437,8 +437,8 @@ class UFixMath template bool operator== (const UFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()==right.asRaw(); @@ -447,8 +447,8 @@ class UFixMath template bool operator!= (const UFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); UFixMath left(*this); UFixMath right(op); return left.asRaw()!=right.asRaw(); @@ -675,7 +675,7 @@ class SFixMath */ template SFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { - internal_value = MozziPrivate::shiftR((typename IntegerType::signed_type) uf.asRaw(),(_NF-NF)); + internal_value = MozziPrivate::shiftR((typename IntegerType::signed_type) uf.asRaw(),(_NF-NF)); } @@ -685,7 +685,7 @@ class SFixMath */ template SFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { - internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); + internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS @@ -695,11 +695,11 @@ class SFixMath @return The result of the addition as a SFixMath. */ template - SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const + SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -727,11 +727,11 @@ class SFixMath @return The result of the subtraction as a SFixMath. */ template - SFixMath operator- (const SFixMath<_NI,_NF, _RANGE>& op) const + SFixMath operator- (const SFixMath<_NI,_NF, _RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -744,11 +744,11 @@ class SFixMath @return The result of the subtraction as a SFixMath. */ template - SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::MAX(NI,_NI),MozziPrivate::MAX(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; SFixMath left(*this); SFixMath right(op); @@ -834,7 +834,7 @@ class SFixMath This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - SFixMath invAccurate() const + SFixMath invAccurate() const { return inv(); } @@ -869,9 +869,9 @@ class SFixMath @return The result of the shift as a UFixMath of smaller size. */ template - SFixMath sR() + SFixMath sR() { - return SFixMath(internal_value,true); + return SFixMath(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @@ -879,9 +879,9 @@ class SFixMath @return The result of the shift as a UFixMath of bigger size. */ template - SFixMath sL() + SFixMath sL() { - return SFixMath(internal_value,true); + return SFixMath(internal_value,true); } @@ -890,8 +890,8 @@ template template bool operator> (const SFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()>right.asRaw(); @@ -906,8 +906,8 @@ template template bool operator== (const SFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()==right.asRaw(); @@ -916,8 +916,8 @@ template template bool operator!= (const SFixMath<_NI,_NF>& op) const { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); SFixMath left(*this); SFixMath right(op); return left.asRaw()!=right.asRaw(); @@ -1069,7 +1069,7 @@ inline SFixMath operator-(double op, const SFixMath& uf) {return @return The result of the addition of op1 and op2. As a SFixMath */ template -inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) +inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) { return op2+op1; } @@ -1081,7 +1081,7 @@ inline SFixMath -inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF, _RANGE>& op2) +inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF, _RANGE>& op2) { return -op2+op1; } @@ -1103,8 +1103,8 @@ inline SFixMath inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() > right.asRaw(); @@ -1113,8 +1113,8 @@ inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 template inline bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() > right.asRaw(); @@ -1137,8 +1137,8 @@ inline bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 template inline bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() == right.asRaw(); @@ -1153,8 +1153,8 @@ inline bool operator== (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 template inline bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { - constexpr int8_t new_NI = MozziPrivate::MAX(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::MAX(NF, _NF); + constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); + constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); SFixMath left(op1); SFixMath right(op2); return left.asRaw() != right.asRaw(); From fb2ae79833d597db279b34d3016750ff095f6c78 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 10 Feb 2024 16:19:37 +0100 Subject: [PATCH 125/215] Documentation - cleanup --- FixMath.h | 236 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 151 insertions(+), 85 deletions(-) diff --git a/FixMath.h b/FixMath.h index 60b2ecf49..afa84e91a 100644 --- a/FixMath.h +++ b/FixMath.h @@ -17,43 +17,68 @@ signed (SFixMath) or unsigned (UFixMath). A fixed point number has its range defined by the number of bits encoding the integer part (NI - in the following) and its precision by the number of bits encoding the fractional part (NF). For UFixMath types, the integral part can hold values in [0,2^NI-1], for SFixMath types, the integral part can hold values in [-2^NI,2^NI-1]. + in the following) and its precision by the number of bits encoding the fractional part (NF). For UFixMath types, the integral part can hold values in [0,2^NI-1], for SFixMath types, the integral part can hold values in [-2^NI,2^NI-1]. The number of bits encoding the fractional can be considered as the precision of the number: given NF, the number of possible values in the [0,1[ range will 2^NF. Hence, given NF, the resolution will be 1/(2^NF). + + Under the hood, these types will keep track of the maximum possible value they might hold (this is the RANGE template parameter), and, if only *SAFE* operations (see below) are used, will automatically adjust there NI and NF to accomodate the result of a operation. It will also try not to promote there internal type when possible, assuming that you use the complete range of a given type. + + The operations possible with these types can be divided into two categories: + - the operations between FixMath types are all safe (aka won't overflow) and are the only one included by default + - the operations between a FixMath and a native C type (int, float) are NOT safe and are not included by default. In order to activate them, you need to `#define FIXMATHUNSAFE` before including FixMath.h. + Like standard C(++) types, the fixed point numbers defined here are following some rules: - any fixed type can be converted to another *as long as the value can be represented in the destination type*. Casting to a bigger type in term of NI and NF is safe, but reducing NI can lead to an overflow if the new type cannot hold the integer value and reducing NF leads to a loss of precision. + - Fixed types can be constructed from and converted to standard C types. - all operations between fixed point number is safe (it won't overflow) and preserve the precision. In particular: - - only addition, subtraction and multiplication are implemented + - only addition, subtraction and multiplication are implemented (this is a design choice, see below) - any operation between a signed and an unsigned leads to a signed number - resulting numbers will be casted to a type big enough to store the expected values. It follows that it is worth starting with types that are as small as possible to hold the initial value. - - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. - - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. These shifts are basically on + - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. These are only accessible activating the `FIXMATHUNSAFE` set. + - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. More specifically on the returned types of the operations between fixed point math types: - Additions: - - UFixMath + UFixMath<_NI,_NF> returns UFixMath - - SFixMath + SFixMath<_NI,_NF> returns SFixMath - - UFixMath + SFixMath<_NI,_NF> returns SFixMath - - UFixMath + anything_else returns UFixMath - - SFixMath + anything_else returns SFixMath + - UFixMath + UFixMath<_NI,_NF> returns UFixMath at worse + - SFixMath + SFixMath<_NI,_NF> returns SFixMath at worse + - UFixMath + SFixMath<_NI,_NF> returns SFixMath at worse + - UFixMath + anything_else returns UFixMath (only available with `FIXMATHUNSAFE`) + - SFixMath + anything_else returns SFixMath (only available with `FIXMATHUNSAFE`) - Subtractions: - - UFixMath - UFixMath<_NI,_NF> returns SFixMath - - SFixMath - SFixMath<_NI,_NF> returns SFixMath - - SFixMath - UFixMath<_NI,_NF> returns SFixMath - - UFixMath - anything_else returns UFixMath - - SFixMath - anything_else returns SFixMath - - (-)SFixMath return SFixMath - - (-)UFixMath return SFixMath + - UFixMath - UFixMath<_NI,_NF> returns SFixMath at worse + - SFixMath - SFixMath<_NI,_NF> returns SFixMath at worse + - SFixMath - UFixMath<_NI,_NF> returns SFixMath at worse + - UFixMath - anything_else returns UFixMath (only available with `FIXMATHUNSAFE`) + - SFixMath - anything_else returns SFixMath (only available with `FIXMATHUNSAFE`) + - (-)SFixMath return SFixMath + - (-)UFixMath return SFixMath - Multiplications: - - UFixMath * UFixMath<_NI,_NF> returns UFixMath - - UFixMath * SFixMath<_NI,_NF> returns SFixMath - - SFixMath * SFixMath<_NI,_NF> returns SFixMath - - UFixMath * anything_else returns UFixMath - - SFixMath * anything_else returns SFixMath + - UFixMath * UFixMath<_NI,_NF> returns UFixMath at worse + - UFixMath * SFixMath<_NI,_NF> returns SFixMath at worse + - SFixMath * SFixMath<_NI,_NF> returns SFixMath at worse + - UFixMath * anything_else returns UFixMath (only available with `FIXMATHUNSAFE`) + - SFixMath * anything_else returns SFixMath (only available with `FIXMATHUNSAFE`) - Shifts: - - UFixMath .sR returns UFixMath - - UFixMath .sL returns UFixMath - - same for SFixMath. - + - UFixMath .sR returns UFixMath + - UFixMath .sL returns UFixMath + - same for SFixMath. + - Inverse: + - UFixMath.invFast() returns the inverse of the number as UFixMath + - SFixMath.invFast() returns the inverse of the number as SFixMath + - UFixMath.invAccurate() returns the inverse of the number as UFixMath + - SFixMath.invAccurate() returns the inverse of the number as SFixMath + - UFixMath.inv<_NF>() returns the inverse of the number as UFixMath + - SFixMath.inv<_NF>() returns the inverse of the number as SFixMath + - Conversion (should be preferred over casting, when possible): + - UFixMath.asSFix() returns SFixMath + - SFixMath.asUFix() returns UFixMath + - UFixMath.asFloat() returns the value as a float. + - SFixMath.asFloat() returns the value as a float. + - UFixMath.asRaw() returns the internal value. + - SFixMath.asRaw() returns the internal value. + - T.toUFraction() returns UFixMath<0,NF> with NF the number of bits of T (uint8_t leads to NF=8bits). + - T.toSFraction() returns SFixMath<0,NF> with NF the number of bits of T (int8_t leads to NF=7bits). + - T.toUInt() returns UFixMath with NI the number of bits of T (uint8_t leads to NI=8bits). + - T.toSInt() returns SFixMath with NI the number of bits of T (int8_t leads to NI=7bits). */ @@ -66,54 +91,20 @@ #include #include "IntegerType.h" - -//#define MOZZI_SHIFTR(x,bits) (bits > 0 ? (x >> (bits)) : (x << (-bits))) // shift right for positive shift numbers, and left for negative ones. - -//#define MAX(N1,N2) ((N1) > (N2) ? (N1) : (N2)) -//#define MIN(N1,N2) ((N1) > (N2) ? (N2) : (N1)) -//#define UFULLRANGE(N) ((1ULL<<(N)) - 1) // MAX value represented by an unsigned of N bits -//#define SFULLRANGE(N) ((1ULL<<(N))) // MAX value represented by a signed of N bits -//#define UFULLRANGE(N) (((1ULL<<(N-1)) - 1) + (1ULL << (N-1))) -//#define RANGEADD(NF, _NF, RANGE, _RANGE) ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF)))) // resulting range when adding -//#define NEEDEDNIEXTRA(NI, NF, RANGE) (RANGE > (UFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (UFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) // NEEDED NI TO AVOID OVERFLOW, GIVEN A RANGE -//#define NEEDEDSNIEXTRA(NI, NF, RANGE) (RANGE > (SFULLRANGE(NI+NF)) ? (NI+1) : (RANGE > (SFULLRANGE(NI+NF-1)) ? (NI) : (NI-1))) -//#define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (MOZZI_SHIFTR(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) -//#define RANGESHIFT(N,SH,RANGE) ((SH < N) ? (RANGE) : (mozzi_shiftr(RANGE,(N-SH)))) // to increase the range with shifts in case NI or NF reaches 0 (we then need to increase the range) - - -// Experiments -/*#define NBITSREAL(X,N) (abs(X) < (1<(X)) - #define UFixAuto(X) (UFixMath(X))*/ - -/* - template - constexpr int8_t nBitsReal(T x, int8_t n=0) { - if (abs(x) < ((T)1 << n)) { - return n; - } else { - return nBitsReal(x, n + 1); - } - } - - #define UFixAuto(X) (UFixMath(X)) -*/ - namespace MozziPrivate { - template constexpr T shiftR(T x, int8_t bits) {return (bits > 0 ? (x >> (bits)) : (x << (-bits)));} - constexpr int8_t sBitsToBytes(int8_t N) { return (((N)>>3)+1);} + template constexpr T shiftR(T x, int8_t bits) {return (bits > 0 ? (x >> (bits)) : (x << (-bits)));} // shift right with positive values, left with negative + constexpr int8_t sBitsToBytes(int8_t N) { return (((N)>>3)+1);} // conversion between Bits and Bytes for signed constexpr int8_t uBitsToBytes(int8_t N) { return (((N-1)>>3)+1);} template constexpr T mozziMax(T N1, T N2) { return (N1) > (N2) ? (N1) : (N2);} template constexpr T mozziMin(T N1, T N2) { return (N1) > (N2) ? (N2) : (N1);} - constexpr uint64_t sFullRange(int8_t N) { return uint64_t(1)< _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF))));} - constexpr int8_t neededNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (uFullRange(NI+NF)) ? (NI+1) : (RANGE > (uFullRange(NI+NF-1)) ? (NI) : (NI-1)));} - constexpr int8_t neededSNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (sFullRange(NI+NF)) ? (NI+1) : (RANGE > (sFullRange(NI+NF-1)) ? (NI) : (NI-1)));} - constexpr uint64_t RANGESHIFT(int8_t N, int8_t SH, uint64_t RANGE) { return ((SH < N) ? (RANGE) : (shiftR(RANGE,(N-SH))));} + constexpr uint64_t rangeAdd(byte NF, byte _NF, uint64_t RANGE, uint64_t _RANGE) { return ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF))));} // returns the RANGE following an addition + constexpr int8_t neededNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (uFullRange(NI+NF)) ? (NI+1) : (RANGE > (uFullRange(NI+NF-1)) ? (NI) : (NI-1)));} // check if RANGE can be hold in the unsigned type defined by NI and NF + constexpr int8_t neededSNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (sFullRange(NI+NF)) ? (NI+1) : (RANGE > (sFullRange(NI+NF-1)) ? (NI) : (NI-1)));} // same for signed + constexpr uint64_t RANGESHIFT(int8_t N, int8_t SH, uint64_t RANGE) { return ((SH < N) ? (RANGE) : (shiftR(RANGE,(N-SH))));} // make sure that NI or NF does not turn negative when safe shifts are used. } // Forward declaration @@ -237,7 +228,8 @@ class UFixMath } #ifdef FIXMATHUNSAFE - /** Addition with another type. Unsafe + /** Addition with another type. + @note Unsafe. Only available with `FIXMATHUNSAFE` @param op The number to be added. @return The result of the addition as a UFixMath. */ @@ -268,7 +260,8 @@ class UFixMath } #ifdef FIXMATHUNSAFE - /** Subtraction with another type. Unsafe + /** Subtraction with another type. + @note Unsafe. Only available with `FIXMATHUNSAFE` @param op The number to be subtracted. @return The result of the subtraction as a UFixMath. */ @@ -316,9 +309,10 @@ class UFixMath } #ifdef FIXMATHUNSAFE - /** Multiplication with another type. Unsafe. + /** Multiplication with another type. + @note Unsafe. Only available with `FIXMATHUNSAFE` @param op The number to be multiplied. - @return The result of the multiplication as a UFixMath. + @return The result of the multiplication as a UFixMath of identical NI and NF */ template UFixMath operator* (const T op) const @@ -386,6 +380,7 @@ class UFixMath #ifdef FIXMATHUNSAFE /** Left shift. This can overflow if you shift to a value that cannot be represented. Better to use .sL() if possible instead. + @note Unsafe. Only available with `FIXMATHUNSAFE` @param op The shift number @return The result of the shift as a UFixMath. */ @@ -417,7 +412,10 @@ class UFixMath //////// COMPARISON OVERLOADS - + /** Comparison with another UFixMath. + @param op A UFixMath + @return true if this is bigger than op, false otherwise + */ template bool operator> (const UFixMath<_NI,_NF>& op) const { @@ -428,12 +426,21 @@ class UFixMath return left.asRaw()>right.asRaw(); } + /** Comparison with another UFixMath. + @param op A UFixMath + @return true if this is smaller than op, false otherwise + */ template bool operator< (const UFixMath<_NI,_NF>& op) const { return op > *this; } + + /** Comparison with another UFixMath. + @param op A UFixMath + @return true if this equal to op, false otherwise + */ template bool operator== (const UFixMath<_NI,_NF>& op) const { @@ -444,6 +451,10 @@ class UFixMath return left.asRaw()==right.asRaw(); } + /** Comparison with another UFixMath. + @param op A UFixMath + @return true if this not equal to op, false otherwise + */ template bool operator!= (const UFixMath<_NI,_NF>& op) const { @@ -709,7 +720,8 @@ class SFixMath } #ifdef FIXMATHUNSAFE - /** Addition with another type. Unsafe + /** Addition with another type. + @note Unsafe. Only available with `FIXMATHUNSAFE` @param op The number to be added. @return The result of the addition as a UFixMath. */ @@ -757,7 +769,8 @@ class SFixMath } #ifdef FIXMATHUNSAFE - /** Subtraction with another type. Unsafe + /** Subtraction with another type. + @note Unsafe. Only available with `FIXMATHUNSAFE` @param op The number to be subtracted. @return The result of the subtraction as a SFixMath. */ @@ -792,7 +805,8 @@ class SFixMath } #ifdef FIXMATHUNSAFE - /** Multiplication with another type. Unsafe. + /** Multiplication with another type. + @note Unsafe. Only available with `FIXMATHUNSAFE` @param op The number to be multiplied. @return The result of the multiplication as a UFixMath. */ @@ -855,6 +869,7 @@ class SFixMath #ifdef FIXMATHUNSAFE /** Left shift. This can overflow if you shift to a value that cannot be represented. Better to use .sL() if possible instead. + @note Unsafe. Only available with `FIXMATHUNSAFE` @param op The shift number @return The result of the shift as a UFixMath. */ @@ -886,7 +901,11 @@ template //////// COMPARISON OVERLOADS - + + /** Comparison with another SFixMath. + @param op A UFixMath + @return true if this is bigger than op, false otherwise + */ template bool operator> (const SFixMath<_NI,_NF>& op) const { @@ -897,12 +916,21 @@ template return left.asRaw()>right.asRaw(); } + /** Comparison with another SFixMath. + @param op A UFixMath + @return true if this is smaller than op, false otherwise + */ template bool operator< (const SFixMath<_NI,_NF>& op) const { return op > *this; } + + /** Comparison with another SFixMath. + @param op A UFixMath + @return true if this is equal to op, false otherwise + */ template bool operator== (const SFixMath<_NI,_NF>& op) const { @@ -913,6 +941,10 @@ template return left.asRaw()==right.asRaw(); } + /** Comparison with another SFixMath. + @param op A UFixMath + @return true if this is not equal to op, false otherwise + */ template bool operator!= (const SFixMath<_NI,_NF>& op) const { @@ -1098,8 +1130,13 @@ inline SFixMath inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { @@ -1110,6 +1147,11 @@ inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 return left.asRaw() > right.asRaw(); } +/** Comparison between a UFixMath and an SFixMath. + @param op1 a UFixMath + @param op2 A SFixMath + @return true if op1 is bigger than op2, false otherwise +*/ template inline bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { @@ -1120,12 +1162,23 @@ inline bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 return left.asRaw() > right.asRaw(); } +/** Comparison between a UFixMath and an SFixMath. + @param op1 a UFixMath + @param op2 A SFixMath + @return true if op1 is smaller than op2, false otherwise +*/ template inline bool operator< (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2 > op1; } + +/** Comparison between a SFixMath and an UFixMath. + @param op1 a SFixMath + @param op2 A UFixMath + @return true if op1 is smaller than op2, false otherwise +*/ template inline bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { @@ -1133,7 +1186,11 @@ inline bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 } - +/** Comparison between a SFixMath and an UFixMath. + @param op1 a SFixMath + @param op2 A UFixMath + @return true if op1 is equal to op2, false otherwise +*/ template inline bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { @@ -1144,12 +1201,23 @@ inline bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 return left.asRaw() == right.asRaw(); } + +/** Comparison between a UFixMath and an SFixMath. + @param op1 a UFixMath + @param op2 A SFixMath + @return true if op1 is equal to op2, false otherwise +*/ template inline bool operator== (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { return op2 == op1; } +/** Comparison between a SFixMath and an UFixMath. + @param op1 a SFixMath + @param op2 A UFixMath + @return true if op1 is not equal to op2, false otherwise +*/ template inline bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) { @@ -1160,6 +1228,12 @@ inline bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 return left.asRaw() != right.asRaw(); } + +/** Comparison between a UFixMath and an SFixMath. + @param op1 a UFixMath + @param op2 A SFixMath + @return true if op1 is not equal to op2, false otherwise +*/ template inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) { @@ -1203,14 +1277,6 @@ inline SFixMath toSInt(T val) { -// #undef MAX -// #undef MIN -// #undef UFULLRANGE -// #undef SFULLRANGE -// #undef RANGEADD -// #undef NEEDEDNIEXTRA -// #undef NEEDEDSNIEXTRA -// #undef RANGESHIFT #endif From 7c581169cfda795ca407dd5083f1de7f6bc4ae68 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 10 Feb 2024 16:39:49 +0100 Subject: [PATCH 126/215] Documentation --- FixMath.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FixMath.h b/FixMath.h index afa84e91a..ccd5f2d36 100644 --- a/FixMath.h +++ b/FixMath.h @@ -79,6 +79,11 @@ - T.toSFraction() returns SFixMath<0,NF> with NF the number of bits of T (int8_t leads to NF=7bits). - T.toUInt() returns UFixMath with NI the number of bits of T (uint8_t leads to NI=8bits). - T.toSInt() returns SFixMath with NI the number of bits of T (int8_t leads to NI=7bits). + + Note on division: + The division is not implemented. This is a deliberate choice made for two reasons: + - in contrast with all the other fundamental operations, it is not possible to guarantee that precision will be kept (other operations returns *exact* results whenever the operands were also exactly represented. Note that this is actually not the case when using normal floating point numbers. The inverse functions can be used to fake a division, by multiplying by the inverse of a number. + - division are usually very slow operations on MCU, hence there usage is discouraged. The ideal way of doing it is to compute the inverse whenever needed and only when needed. In the context of Mozzi for instance, a good way to do it would be to compute needed inverses in updateControl(), and use them in updateAudio(). */ From 4f97ef064cd9420f0d9cb2af63f08df2ef53b7f3 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 11 Feb 2024 13:52:09 +0100 Subject: [PATCH 127/215] Added more const to FixMath, small dox fix and typos --- FixMath.h | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/FixMath.h b/FixMath.h index ccd5f2d36..d75e3059f 100644 --- a/FixMath.h +++ b/FixMath.h @@ -23,7 +23,7 @@ The operations possible with these types can be divided into two categories: - the operations between FixMath types are all safe (aka won't overflow) and are the only one included by default - - the operations between a FixMath and a native C type (int, float) are NOT safe and are not included by default. In order to activate them, you need to `#define FIXMATHUNSAFE` before including FixMath.h. + - the operations between a FixMath and a native C type (int, float) are NOT safe and are not included by default. In order to activate them, you need to `#define MOZZI_FIXMATH_UNSAFE` before including FixMath.h. Like standard C(++) types, the fixed point numbers defined here are following some rules: @@ -33,7 +33,7 @@ - only addition, subtraction and multiplication are implemented (this is a design choice, see below) - any operation between a signed and an unsigned leads to a signed number - resulting numbers will be casted to a type big enough to store the expected values. It follows that it is worth starting with types that are as small as possible to hold the initial value. - - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. These are only accessible activating the `FIXMATHUNSAFE` set. + - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. These are only accessible activating the `MOZZI_FIXMATH_UNSAFE` set. - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. More specifically on the returned types of the operations between fixed point math types: @@ -41,22 +41,22 @@ - UFixMath + UFixMath<_NI,_NF> returns UFixMath at worse - SFixMath + SFixMath<_NI,_NF> returns SFixMath at worse - UFixMath + SFixMath<_NI,_NF> returns SFixMath at worse - - UFixMath + anything_else returns UFixMath (only available with `FIXMATHUNSAFE`) - - SFixMath + anything_else returns SFixMath (only available with `FIXMATHUNSAFE`) + - UFixMath + anything_else returns UFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) + - SFixMath + anything_else returns SFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) - Subtractions: - UFixMath - UFixMath<_NI,_NF> returns SFixMath at worse - SFixMath - SFixMath<_NI,_NF> returns SFixMath at worse - SFixMath - UFixMath<_NI,_NF> returns SFixMath at worse - - UFixMath - anything_else returns UFixMath (only available with `FIXMATHUNSAFE`) - - SFixMath - anything_else returns SFixMath (only available with `FIXMATHUNSAFE`) + - UFixMath - anything_else returns UFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) + - SFixMath - anything_else returns SFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) - (-)SFixMath return SFixMath - (-)UFixMath return SFixMath - Multiplications: - UFixMath * UFixMath<_NI,_NF> returns UFixMath at worse - UFixMath * SFixMath<_NI,_NF> returns SFixMath at worse - SFixMath * SFixMath<_NI,_NF> returns SFixMath at worse - - UFixMath * anything_else returns UFixMath (only available with `FIXMATHUNSAFE`) - - SFixMath * anything_else returns SFixMath (only available with `FIXMATHUNSAFE`) + - UFixMath * anything_else returns UFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) + - SFixMath * anything_else returns SFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) - Shifts: - UFixMath .sR returns UFixMath - UFixMath .sL returns UFixMath @@ -232,9 +232,9 @@ class UFixMath return SFixMath(tt,true); } -#ifdef FIXMATHUNSAFE +#ifdef MOZZI_FIXMATH_UNSAFE /** Addition with another type. - @note Unsafe. Only available with `FIXMATHUNSAFE` + @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be added. @return The result of the addition as a UFixMath. */ @@ -264,9 +264,9 @@ class UFixMath return SFixMath(tt,true); } - #ifdef FIXMATHUNSAFE + #ifdef MOZZI_FIXMATH_UNSAFE /** Subtraction with another type. - @note Unsafe. Only available with `FIXMATHUNSAFE` + @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be subtracted. @return The result of the subtraction as a UFixMath. */ @@ -313,9 +313,9 @@ class UFixMath return SFixMath(tt,true); } - #ifdef FIXMATHUNSAFE + #ifdef MOZZI_FIXMATH_UNSAFE /** Multiplication with another type. - @note Unsafe. Only available with `FIXMATHUNSAFE` + @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be multiplied. @return The result of the multiplication as a UFixMath of identical NI and NF */ @@ -382,10 +382,10 @@ class UFixMath } - #ifdef FIXMATHUNSAFE + #ifdef MOZZI_FIXMATH_UNSAFE /** Left shift. This can overflow if you shift to a value that cannot be represented. Better to use .sL() if possible instead. - @note Unsafe. Only available with `FIXMATHUNSAFE` + @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The shift number @return The result of the shift as a UFixMath. */ @@ -504,7 +504,7 @@ class UFixMath }; -#ifdef FIXMATHUNSAFE +#ifdef MOZZI_FIXMATH_UNSAFE // Multiplication template inline UFixMath operator*(uint8_t op, const UFixMath& uf) {return uf*op;} @@ -724,9 +724,9 @@ class SFixMath return SFixMath(tt,true); } -#ifdef FIXMATHUNSAFE +#ifdef MOZZI_FIXMATH_UNSAFE /** Addition with another type. - @note Unsafe. Only available with `FIXMATHUNSAFE` + @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be added. @return The result of the addition as a UFixMath. */ @@ -773,9 +773,9 @@ class SFixMath return SFixMath(tt,true); } - #ifdef FIXMATHUNSAFE + #ifdef MOZZI_FIXMATH_UNSAFE /** Subtraction with another type. - @note Unsafe. Only available with `FIXMATHUNSAFE` + @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be subtracted. @return The result of the subtraction as a SFixMath. */ @@ -809,9 +809,9 @@ class SFixMath return SFixMath(tt,true); } - #ifdef FIXMATHUNSAFE + #ifdef MOZZI_FIXMATH_UNSAFE /** Multiplication with another type. - @note Unsafe. Only available with `FIXMATHUNSAFE` + @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be multiplied. @return The result of the multiplication as a UFixMath. */ @@ -871,10 +871,10 @@ class SFixMath return SFixMath(internal_value>>op,true); } - #ifdef FIXMATHUNSAFE + #ifdef MOZZI_FIXMATH_UNSAFE /** Left shift. This can overflow if you shift to a value that cannot be represented. Better to use .sL() if possible instead. - @note Unsafe. Only available with `FIXMATHUNSAFE` + @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The shift number @return The result of the shift as a UFixMath. */ @@ -997,7 +997,7 @@ template }; -#ifdef FIXMATHUNSAFE +#ifdef MOZZI_FIXMATH_UNSAFE /// Reverse overloadings, // Multiplication From a882cf28221c3aab9730182a19e3bfe3d077bb52 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 11 Feb 2024 14:06:29 +0100 Subject: [PATCH 128/215] U/SFixMath -> U/SFix --- FixMath.h | 746 +++++++++++++++++++++++++++--------------------------- 1 file changed, 376 insertions(+), 370 deletions(-) diff --git a/FixMath.h b/FixMath.h index d75e3059f..221b69c1f 100644 --- a/FixMath.h +++ b/FixMath.h @@ -14,10 +14,10 @@ /** This file implements two fixed point number classes. These numbers can have a fractional part but are actually standard integers under the hood which makes calculations with them efficient on platforms which do not have a FPU like most micro-controllers. These numbers can be - signed (SFixMath) or unsigned (UFixMath). + signed (SFix) or unsigned (UFix). A fixed point number has its range defined by the number of bits encoding the integer part (NI - in the following) and its precision by the number of bits encoding the fractional part (NF). For UFixMath types, the integral part can hold values in [0,2^NI-1], for SFixMath types, the integral part can hold values in [-2^NI,2^NI-1]. The number of bits encoding the fractional can be considered as the precision of the number: given NF, the number of possible values in the [0,1[ range will 2^NF. Hence, given NF, the resolution will be 1/(2^NF). + in the following) and its precision by the number of bits encoding the fractional part (NF). For UFix types, the integral part can hold values in [0,2^NI-1], for SFix types, the integral part can hold values in [-2^NI,2^NI-1]. The number of bits encoding the fractional can be considered as the precision of the number: given NF, the number of possible values in the [0,1[ range will 2^NF. Hence, given NF, the resolution will be 1/(2^NF). Under the hood, these types will keep track of the maximum possible value they might hold (this is the RANGE template parameter), and, if only *SAFE* operations (see below) are used, will automatically adjust there NI and NF to accomodate the result of a operation. It will also try not to promote there internal type when possible, assuming that you use the complete range of a given type. @@ -38,47 +38,47 @@ More specifically on the returned types of the operations between fixed point math types: - Additions: - - UFixMath + UFixMath<_NI,_NF> returns UFixMath at worse - - SFixMath + SFixMath<_NI,_NF> returns SFixMath at worse - - UFixMath + SFixMath<_NI,_NF> returns SFixMath at worse - - UFixMath + anything_else returns UFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) - - SFixMath + anything_else returns SFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) + - UFix + UFix<_NI,_NF> returns UFix at worse + - SFix + SFix<_NI,_NF> returns SFix at worse + - UFix + SFix<_NI,_NF> returns SFix at worse + - UFix + anything_else (signed or not) returns UFix (only available with `MOZZI_FIXMATH_UNSAFE`) + - SFix + anything_else (signed or not) returns SFix (only available with `MOZZI_FIXMATH_UNSAFE`) - Subtractions: - - UFixMath - UFixMath<_NI,_NF> returns SFixMath at worse - - SFixMath - SFixMath<_NI,_NF> returns SFixMath at worse - - SFixMath - UFixMath<_NI,_NF> returns SFixMath at worse - - UFixMath - anything_else returns UFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) - - SFixMath - anything_else returns SFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) - - (-)SFixMath return SFixMath - - (-)UFixMath return SFixMath + - UFix - UFix<_NI,_NF> returns SFix at worse + - SFix - SFix<_NI,_NF> returns SFix at worse + - SFix - UFix<_NI,_NF> returns SFix at worse + - UFix - anything_else (signed or not) returns UFix (only available with `MOZZI_FIXMATH_UNSAFE`) + - SFix - anything_else (signed or not) returns SFix (only available with `MOZZI_FIXMATH_UNSAFE`) + - (-)SFix return SFix + - (-)UFix return SFix - Multiplications: - - UFixMath * UFixMath<_NI,_NF> returns UFixMath at worse - - UFixMath * SFixMath<_NI,_NF> returns SFixMath at worse - - SFixMath * SFixMath<_NI,_NF> returns SFixMath at worse - - UFixMath * anything_else returns UFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) - - SFixMath * anything_else returns SFixMath (only available with `MOZZI_FIXMATH_UNSAFE`) + - UFix * UFix<_NI,_NF> returns UFix at worse + - UFix * SFix<_NI,_NF> returns SFix at worse + - SFix * SFix<_NI,_NF> returns SFix at worse + - UFix * anything_else (signed or not) returns UFix (only available with `MOZZI_FIXMATH_UNSAFE`) + - SFix * anything_else (signed or not) returns SFix (only available with `MOZZI_FIXMATH_UNSAFE`) - Shifts: - - UFixMath .sR returns UFixMath - - UFixMath .sL returns UFixMath - - same for SFixMath. + - UFix .sR returns UFix + - UFix .sL returns UFix + - same for SFix. - Inverse: - - UFixMath.invFast() returns the inverse of the number as UFixMath - - SFixMath.invFast() returns the inverse of the number as SFixMath - - UFixMath.invAccurate() returns the inverse of the number as UFixMath - - SFixMath.invAccurate() returns the inverse of the number as SFixMath - - UFixMath.inv<_NF>() returns the inverse of the number as UFixMath - - SFixMath.inv<_NF>() returns the inverse of the number as SFixMath + - UFix.invFast() returns the inverse of the number as UFix + - SFix.invFast() returns the inverse of the number as SFix + - UFix.invAccurate() returns the inverse of the number as UFix + - SFix.invAccurate() returns the inverse of the number as SFix + - UFix.inv<_NF>() returns the inverse of the number as UFix + - SFix.inv<_NF>() returns the inverse of the number as SFix - Conversion (should be preferred over casting, when possible): - - UFixMath.asSFix() returns SFixMath - - SFixMath.asUFix() returns UFixMath - - UFixMath.asFloat() returns the value as a float. - - SFixMath.asFloat() returns the value as a float. - - UFixMath.asRaw() returns the internal value. - - SFixMath.asRaw() returns the internal value. - - T.toUFraction() returns UFixMath<0,NF> with NF the number of bits of T (uint8_t leads to NF=8bits). - - T.toSFraction() returns SFixMath<0,NF> with NF the number of bits of T (int8_t leads to NF=7bits). - - T.toUInt() returns UFixMath with NI the number of bits of T (uint8_t leads to NI=8bits). - - T.toSInt() returns SFixMath with NI the number of bits of T (int8_t leads to NI=7bits). + - UFix.asSFix() returns SFix + - SFix.asUFix() returns UFix + - UFix.asFloat() returns the value as a float. + - SFix.asFloat() returns the value as a float. + - UFix.asRaw() returns the internal value. + - SFix.asRaw() returns the internal value. + - T.toUFraction() returns UFix<0,NF> with NF the number of bits of T (uint8_t leads to NF=8bits). + - T.toSFraction() returns SFix<0,NF> with NF the number of bits of T (int8_t leads to NF=7bits). + - T.toUInt() returns UFix with NI the number of bits of T (uint8_t leads to NI=8bits). + - T.toSInt() returns SFix with NI the number of bits of T (int8_t leads to NI=7bits). Note on division: The division is not implemented. This is a deliberate choice made for two reasons: @@ -93,6 +93,10 @@ #ifndef FIXMATH2_H_ #define FIXMATH2_H_ +#if FOR_DOXYGEN_ONLY +#define MOZZI_FIXMATH_UNSAFE +#endif + #include #include "IntegerType.h" @@ -109,42 +113,43 @@ namespace MozziPrivate { constexpr uint64_t rangeAdd(byte NF, byte _NF, uint64_t RANGE, uint64_t _RANGE) { return ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF))));} // returns the RANGE following an addition constexpr int8_t neededNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (uFullRange(NI+NF)) ? (NI+1) : (RANGE > (uFullRange(NI+NF-1)) ? (NI) : (NI-1)));} // check if RANGE can be hold in the unsigned type defined by NI and NF constexpr int8_t neededSNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (sFullRange(NI+NF)) ? (NI+1) : (RANGE > (sFullRange(NI+NF-1)) ? (NI) : (NI-1)));} // same for signed - constexpr uint64_t RANGESHIFT(int8_t N, int8_t SH, uint64_t RANGE) { return ((SH < N) ? (RANGE) : (shiftR(RANGE,(N-SH))));} // make sure that NI or NF does not turn negative when safe shifts are used. + constexpr uint64_t rangeShift(int8_t N, int8_t SH, uint64_t RANGE) { return ((SH < N) ? (RANGE) : (shiftR(RANGE,(N-SH))));} // make sure that NI or NF does not turn negative when safe shifts are used. } // Forward declaration template -class SFixMath; +class SFix; /** Instanciate an unsigned fixed point math number. @param NI The number of bits encoding the integer part. The integral part can range into [0, 2^NI -1] @param NF The number of bits encoding the fractional part + @param RANGE A purely internal parameter that keeps track of the range used by the type. Safer to *not* define it. */ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. -class UFixMath +class UFix { - static_assert(NI+NF<=64, "The total width of a UFixMath cannot exceed 64bits"); + static_assert(NI+NF<=64, "The total width of a UFix cannot exceed 64bits"); typedef typename IntegerType::unsigned_type internal_type ; // smallest size that fits our internal integer typedef typename IntegerType::unsigned_type next_greater_type ; // smallest size that fits 1<*/(fl * (next_greater_type(1) << NF));} + UFix(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} /** Constructor from a floating point value. @param fl Floating point value @return An unsigned fixed point number */ - UFixMath(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } + UFix(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ @@ -155,7 +160,7 @@ class UFixMath @return An unsigned fixed point number */ template - UFixMath(T value,bool as_raw=false) { + UFix(T value,bool as_raw=false) { if (as_raw) internal_value = value; else internal_value = (internal_type(value) << NF); @@ -164,201 +169,201 @@ class UFixMath /** Set the internal value of the fixed point math number. @param raw The new internal value. - @return An UFixMathx + @return An UFixx */ template - static UFixMath fromRaw(T raw){return UFixMath(raw,true);} + static UFix fromRaw(T raw){return UFix(raw,true);} - /** Constructor from another UFixMath. + /** Constructor from another UFix. @param uf An unsigned fixed type number which value can be represented in this type. @return A unsigned fixed type number */ template - UFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { + UFix(const UFix<_NI,_NF, _RANGE>& uf) { internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } - /** Constructor from a SFixMath. + /** Constructor from a SFix. @param uf An signed fixed type number which value can be represented in this type: sign is thus discarded. @return A unsigned fixed type number */ template - UFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { + UFix(const SFix<_NI,_NF, _RANGE>& uf) { internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS - /** Addition with another UFixMath. Safe. - @param op The UFixMath to be added. - @return The result of the addition as a UFixMath. + /** Addition with another UFix. Safe. + @param op The UFix to be added. + @return The result of the addition as a UFix. */ template - UFixMath operator+ (const UFixMath<_NI,_NF,_RANGE>& op) const + UFix operator+ (const UFix<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); constexpr int8_t new_NI = MozziPrivate::neededNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::unsigned_type return_type; - UFixMath left(*this); - UFixMath right(op); + UFix left(*this); + UFix right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return UFixMath(tt,true); + return UFix(tt,true); } - /** Addition with a SFixMath. Safe. - @param op The UFixMath to be added. - @return The result of the addition as a SFixMath. + /** Addition with a SFix. Safe. + @param op The UFix to be added. + @return The result of the addition as a SFix. */ template - SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const + SFix operator+ (const SFix<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; - SFixMath left(*this); - SFixMath right(op); + SFix left(*this); + SFix right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFixMath(tt,true); + return SFix(tt,true); } #ifdef MOZZI_FIXMATH_UNSAFE /** Addition with another type. @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be added. - @return The result of the addition as a UFixMath. + @return The result of the addition as a UFix. */ template - UFixMath operator+ (const T op) const + UFix operator+ (const T op) const { - return UFixMath(internal_value+((internal_type)op<(internal_value+((internal_type)op< // We do not have the +1 after MozziPrivate::mozziMax(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + SFix operator- (const UFix<_NI,_NF, _RANGE>& op) const { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; - SFixMath left(*this); - SFixMath right(op); + SFix left(*this); + SFix right(op); return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFixMath(tt,true); + return SFix(tt,true); } #ifdef MOZZI_FIXMATH_UNSAFE /** Subtraction with another type. @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be subtracted. - @return The result of the subtraction as a UFixMath. + @return The result of the subtraction as a UFix. */ template - UFixMath operator- (const T op) const + UFix operator- (const T op) const { - return UFixMath(internal_value-((internal_type)op<(internal_value-((internal_type)op< operator-() const + SFix operator-() const { - return SFixMath( -(typename IntegerType::signed_type)(internal_value),true); + return SFix( -(typename IntegerType::signed_type)(internal_value),true); } //////// MULTIPLICATION OVERLOADS - /** Multiplication with another UFixMath. Safe. - @param op The UFixMath to be multiplied. - @return The result of the multiplication as a UFixMath. + /** Multiplication with another UFix. Safe. + @param op The UFix to be multiplied. + @return The result of the multiplication as a UFix. */ template - UFixMath operator* (const UFixMath<_NI,_NF,_RANGE>& op) const + UFix operator* (const UFix<_NI,_NF,_RANGE>& op) const { constexpr int8_t NEW_NI = MozziPrivate::neededNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); typedef typename IntegerType::unsigned_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); - return UFixMath(tt,true); + return UFix(tt,true); } - /** Multiplication with a SFixMath. Safe. - @param op The SFixMath to be multiplied. - @return The result of the multiplication as a SFixMath. + /** Multiplication with a SFix. Safe. + @param op The SFix to be multiplied. + @return The result of the multiplication as a SFix. */ template - SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const + SFix operator* (const SFix<_NI,_NF,_RANGE>& op) const { constexpr int8_t NEW_NI = MozziPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); typedef typename IntegerType::signed_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); - return SFixMath(tt,true); + return SFix(tt,true); } #ifdef MOZZI_FIXMATH_UNSAFE /** Multiplication with another type. @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be multiplied. - @return The result of the multiplication as a UFixMath of identical NI and NF + @return The result of the multiplication as a UFix of identical NI and NF */ template - UFixMath operator* (const T op) const + UFix operator* (const T op) const { - return UFixMath(internal_value*op,true); + return UFix(internal_value*op,true); } #endif //////// INVERSE - /** Compute the inverse of a UFixMath, as a UFixMath (not a typo). + /** Compute the inverse of a UFix, as a UFix (not a typo). This inverse is able to represent accurately the inverse of the smallest and biggest of the initial number, but might lead to a lot of duplicates in between. Good if precision is not a premium but type conservation and speeds are. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - UFixMath invFast() const + UFix invFast() const { static_assert(NI+NF<=63, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); - return UFixMath((onesbitmask()/internal_value),true); + return UFix((onesbitmask()/internal_value),true); } - /** Compute the inverse of a UFixMath, as a UFixMath. + /** Compute the inverse of a UFix, as a UFix. _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invAccurate() (_NF=2*NI+NF) @return The inverse of the number. */ template - UFixMath inv() const + UFix inv() const { - return UFixMath<_NF,NF>(internal_value,true).invFast(); + return UFix<_NF,NF>(internal_value,true).invFast(); } - /** Compute the inverse of a UFixMath, as a UFixMath. + /** Compute the inverse of a UFix, as a UFix. This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - UFixMath invAccurate() const // The MozziPrivate::mozziMin is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) + UFix invAccurate() const // The MozziPrivate::mozziMin is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) { static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); return inv(); @@ -374,11 +379,11 @@ class UFixMath /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. Better to use .sR() if possible instead. @param op The shift number - @return The result of the shift as a UFixMath. + @return The result of the shift as a UFix. */ - UFixMath operator>> (const int8_t op) const + UFix operator>> (const int8_t op) const { - return UFixMath(internal_value>>op,true); + return UFix(internal_value>>op,true); } @@ -387,101 +392,101 @@ class UFixMath Better to use .sL() if possible instead. @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The shift number - @return The result of the shift as a UFixMath. + @return The result of the shift as a UFix. */ - UFixMath operator<< (const int8_t op) const + UFix operator<< (const int8_t op) const { - return UFixMath(internal_value<(internal_value< - UFixMath sR() + UFix sR() { - return UFixMath(internal_value,true); + return UFix(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @param op The shift number - @return The result of the shift as a UFixMath of bigger size. + @return The result of the shift as a UFix of bigger size. */ template - UFixMath sL() + UFix sL() { - return UFixMath(internal_value,true); + return UFix(internal_value,true); } //////// COMPARISON OVERLOADS - /** Comparison with another UFixMath. - @param op A UFixMath + /** Comparison with another UFix. + @param op A UFix @return true if this is bigger than op, false otherwise */ template - bool operator> (const UFixMath<_NI,_NF>& op) const + bool operator> (const UFix<_NI,_NF>& op) const { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - UFixMath left(*this); - UFixMath right(op); + UFix left(*this); + UFix right(op); return left.asRaw()>right.asRaw(); } - /** Comparison with another UFixMath. - @param op A UFixMath + /** Comparison with another UFix. + @param op A UFix @return true if this is smaller than op, false otherwise */ template - bool operator< (const UFixMath<_NI,_NF>& op) const + bool operator< (const UFix<_NI,_NF>& op) const { return op > *this; } - /** Comparison with another UFixMath. - @param op A UFixMath + /** Comparison with another UFix. + @param op A UFix @return true if this equal to op, false otherwise */ template - bool operator== (const UFixMath<_NI,_NF>& op) const + bool operator== (const UFix<_NI,_NF>& op) const { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - UFixMath left(*this); - UFixMath right(op); + UFix left(*this); + UFix right(op); return left.asRaw()==right.asRaw(); } - /** Comparison with another UFixMath. - @param op A UFixMath + /** Comparison with another UFix. + @param op A UFix @return true if this not equal to op, false otherwise */ template - bool operator!= (const UFixMath<_NI,_NF>& op) const + bool operator!= (const UFix<_NI,_NF>& op) const { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - UFixMath left(*this); - UFixMath right(op); + UFix left(*this); + UFix right(op); return left.asRaw()!=right.asRaw(); } - /** Returns the number as a SFixMath of same range and precision. This is more optimized than a cast. - @return a SFixMath + /** Returns the number as a SFix of same range and precision. This is more optimized than a cast. + @return a SFix */ - SFixMath asSFix() + SFix asSFix() const { - return SFixMath(internal_value,true); + return SFix(internal_value,true); } /** Returns the value as floating point number. @return The floating point value. */ - float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)<(internal_value)) / (next_greater_type(1)< -inline UFixMath operator*(uint8_t op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(uint8_t op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(uint16_t op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(uint16_t op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(uint32_t op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(uint32_t op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(uint64_t op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(uint64_t op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(int8_t op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(int8_t op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(int16_t op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(int16_t op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(int32_t op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(int32_t op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(int64_t op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(int64_t op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(float op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(float op, const UFix& uf) {return uf*op;} template -inline UFixMath operator*(double op, const UFixMath& uf) {return uf*op;} +inline UFix operator*(double op, const UFix& uf) {return uf*op;} // Addition template -inline UFixMath operator+(uint8_t op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(uint8_t op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(uint16_t op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(uint16_t op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(uint32_t op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(uint32_t op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(uint64_t op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(uint64_t op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(int8_t op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(int8_t op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(int16_t op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(int16_t op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(int32_t op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(int32_t op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(int64_t op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(int64_t op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(float op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(float op, const UFix& uf) {return uf+op;} template -inline UFixMath operator+(double op, const UFixMath& uf) {return uf+op;} +inline UFix operator+(double op, const UFix& uf) {return uf+op;} // Substraction template -inline SFixMath operator-(uint8_t op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(uint8_t op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(uint16_t op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(uint16_t op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(uint32_t op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(uint32_t op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(uint64_t op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(uint64_t op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(int8_t op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(int8_t op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(int16_t op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(int16_t op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(int32_t op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(int32_t op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(int64_t op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(int64_t op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(float op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(float op, const UFix& uf) {return -uf+op;} template -inline SFixMath operator-(double op, const UFixMath& uf) {return -uf+op;} +inline SFix operator-(double op, const UFix& uf) {return -uf+op;} #endif ////// Helper functions to build SFix from a normal type automatically -/** Create a *pure* fractional unsigned fixed number (UFixMath) from an unsigned integer. +/** Create a *pure* fractional unsigned fixed number (UFix) from an unsigned integer. The number of fractional bits (NF) is chosen automatically depending on the input type. Hence toUFraction(255) and toUFraction(uint8_t(255)) *do not* lead to the same thing: on an AVR, the former will lead to NF=16 - which is overkill and @@ -610,26 +615,26 @@ inline SFixMath operator-(double op, const UFixMath& uf) {return returns correct types, hence you can use this function to convert the return value of a Mozzi's function/class member into a pure fractional number. @param val The value to be converted into a pure fractional number. - @return A UFixMath<0,NF> with NF chosen according to the input type + @return A UFix<0,NF> with NF chosen according to the input type */ template -inline UFixMath<0, sizeof(T)*8> toUFraction(T val) { - return UFixMath<0, sizeof(T)*8>::fromRaw(val); +inline UFix<0, sizeof(T)*8> toUFraction(T val) { + return UFix<0, sizeof(T)*8>::fromRaw(val); } -/** Create a *pure* integer unsigned fixed number (UFixMath) from an unsigned integer. +/** Create a *pure* integer unsigned fixed number (UFix) from an unsigned integer. The number of fractional bits (NI) is chosen automatically depending on the input - type. Hence toUInt(255) and toSInt(uint8_t(255)) *do not* lead to the + type. Hence toUInt(255) and toUInt(uint8_t(255)) *do not* lead to the same thing: on an AVR, the former will lead to NI=16 - which is overkill - whereas the latter will lead to NI=8. Mozzi's objects (Oscil and the like) returns correct types, hence you can use this function to convert the return value of a Mozzi's function/class member into a pure fractional number. @param val The value to be converted into a pure unsigned integer fixed math number. - @return A UFixMath with NI chosen according to the input type + @return A UFix with NI chosen according to the input type */ template -inline UFixMath toUInt(T val) { - return UFixMath::fromRaw(val); +inline UFix toUInt(T val) { + return UFix::fromRaw(val); } @@ -637,31 +642,32 @@ inline UFixMath toUInt(T val) { /** Instanciate an signed fixed point math number. @param NI The number of bits encoding the integer part. The integral part can range into [-2^NI, 2^NI -1] @param NF The number of bits encoding the fractional part - @note The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFixMath<7,0>. + @param RANGE A purely internal parameter that keeps track of the range used by the type. Safer to *not* define it. + @note The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFix<7,0>. */ template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. -class SFixMath +class SFix { - static_assert(NI+NF<64, "The total width of a SFixMath cannot exceed 63bits"); + static_assert(NI+NF<64, "The total width of a SFix cannot exceed 63bits"); typedef typename IntegerType::signed_type internal_type ; // smallest size that fits our internal integer typedef typename IntegerType::signed_type next_greater_type ; // smallest size that fits 1<*/(fl * (next_greater_type(1) << NF));} + SFix(float fl) {internal_value = /*static_cast*/(fl * (next_greater_type(1) << NF));} /** Constructor from a floating point value. @param fl Floating point value @return An signed fixed point number */ - SFixMath(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } + SFix(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } /** Constructor from an integer value which can be interpreted as both a resulting fixed point @@ -671,7 +677,7 @@ class SFixMath @return An signed fixed point number */ template - SFixMath(T value,bool as_raw=false) + SFix(T value,bool as_raw=false) { if (as_raw) internal_value = value; else internal_value = (internal_type(value) << NF); @@ -679,181 +685,181 @@ class SFixMath /** Set the internal value of the fixed point math number. @param raw The new internal value. - @return A SFixMath. + @return A SFix. */ template - static SFixMath fromRaw(T raw){return SFixMath(raw,true);} + static SFix fromRaw(T raw){return SFix(raw,true);} - /** Constructor from another SFixMath. + /** Constructor from another SFix. @param uf A signed fixed type number which value can be represented in this type. @return A signed fixed type number */ template - SFixMath(const SFixMath<_NI,_NF, _RANGE>& uf) { + SFix(const SFix<_NI,_NF, _RANGE>& uf) { internal_value = MozziPrivate::shiftR((typename IntegerType::signed_type) uf.asRaw(),(_NF-NF)); } - /** Constructor from an UFixMath. + /** Constructor from an UFix. @param uf A unsigned fixed type number which value can be represented in this type. @return A signed fixed type number */ template - SFixMath(const UFixMath<_NI,_NF, _RANGE>& uf) { + SFix(const UFix<_NI,_NF, _RANGE>& uf) { internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); } //////// ADDITION OVERLOADS - /** Addition with another SFixMath. Safe. - @param op The SFixMath to be added. - @return The result of the addition as a SFixMath. + /** Addition with another SFix. Safe. + @param op The SFix to be added. + @return The result of the addition as a SFix. */ template - SFixMath operator+ (const SFixMath<_NI,_NF,_RANGE>& op) const + SFix operator+ (const SFix<_NI,_NF,_RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; - SFixMath left(*this); - SFixMath right(op); + SFix left(*this); + SFix right(op); return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFixMath(tt,true); + return SFix(tt,true); } #ifdef MOZZI_FIXMATH_UNSAFE /** Addition with another type. @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be added. - @return The result of the addition as a UFixMath. + @return The result of the addition as a UFix. */ template - SFixMath operator+ (const T op) const + SFix operator+ (const T op) const { - return SFixMath(internal_value+(op<(internal_value+(op< - SFixMath operator- (const SFixMath<_NI,_NF, _RANGE>& op) const + SFix operator- (const SFix<_NI,_NF, _RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; - SFixMath left(*this); - SFixMath right(op); + SFix left(*this); + SFix right(op); return_type tt = return_type(left.asRaw()) - return_type(right.asRaw()); - return SFixMath(tt,true); + return SFix(tt,true); } - /** Subtraction with a UFixMath. Safe. - @param op The SFixMath to be subtracted. - @return The result of the subtraction as a SFixMath. + /** Subtraction with a UFix. Safe. + @param op The SFix to be subtracted. + @return The result of the subtraction as a SFix. */ template - SFixMath operator- (const UFixMath<_NI,_NF, _RANGE>& op) const + SFix operator- (const UFix<_NI,_NF, _RANGE>& op) const { constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); typedef typename IntegerType::signed_type return_type; - SFixMath left(*this); - SFixMath right(op); + SFix left(*this); + SFix right(op); return_type tt = return_type(left.asRaw()) - return_type(right.asRaw()); - return SFixMath(tt,true); + return SFix(tt,true); } #ifdef MOZZI_FIXMATH_UNSAFE /** Subtraction with another type. @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be subtracted. - @return The result of the subtraction as a SFixMath. + @return The result of the subtraction as a SFix. */ template - SFixMath operator- (const T op) const + SFix operator- (const T op) const { - return SFixMath(internal_value-(op<(internal_value-(op< operator-() const + SFix operator-() const { - return SFixMath(-internal_value,true); + return SFix(-internal_value,true); } //////// MULTIPLICATION OVERLOADS - /** Multiplication with another SFixMath. Safe. - @param op The SFixMath to be multiplied. - @return The result of the multiplication as a SFixMath. + /** Multiplication with another SFix. Safe. + @param op The SFix to be multiplied. + @return The result of the multiplication as a SFix. */ template - SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op) const + SFix operator* (const SFix<_NI,_NF,_RANGE>& op) const { constexpr int8_t NEW_NI = MozziPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); typedef typename IntegerType::signed_type return_type ; return_type tt = return_type(internal_value)*op.asRaw(); - return SFixMath(tt,true); + return SFix(tt,true); } #ifdef MOZZI_FIXMATH_UNSAFE /** Multiplication with another type. @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The number to be multiplied. - @return The result of the multiplication as a UFixMath. + @return The result of the multiplication as a UFix. */ template - SFixMath operator* (const T op) const + SFix operator* (const T op) const { - return SFixMath(internal_value*op,true); + return SFix(internal_value*op,true); } #endif //////// INVERSE - /** Compute the inverse of a SFixMath, as a SFixMath (not a typo). + /** Compute the inverse of a SFix, as a SFix (not a typo). This inverse is able to represent accurately the inverse of the smallest and biggest of the initial number, but might lead to a lot of duplicates in between. Good if precision is not a premium but type conservation and speeds are. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - SFixMath invFast() const + SFix invFast() const { static_assert(NI+NF<=62, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); - return SFixMath((onesbitmask()/internal_value),true); + return SFix((onesbitmask()/internal_value),true); } - /** Compute the inverse of a SFixMath, as a SFixMath. + /** Compute the inverse of a SFix, as a SFix. _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invAccurate() (_NF=2*NI+NF) @return The inverse of the number. */ template - SFixMath inv() const + SFix inv() const { - return SFixMath<_NF,NF>(internal_value,true).invFast(); + return SFix<_NF,NF>(internal_value,true).invFast(); } - /** Compute the inverse of a SFixMath, as a SFixMath. + /** Compute the inverse of a SFix, as a SFix. This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. @return The inverse of the number. */ - SFixMath invAccurate() const + SFix invAccurate() const { return inv(); } @@ -864,11 +870,11 @@ class SFixMath /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. Better to use .sR() if possible instead. @param op The shift number - @return The result of the shift as a SFixMath. + @return The result of the shift as a SFix. */ - SFixMath operator>> (const int8_t op) const + SFix operator>> (const int8_t op) const { - return SFixMath(internal_value>>op,true); + return SFix(internal_value>>op,true); } #ifdef MOZZI_FIXMATH_UNSAFE @@ -876,119 +882,119 @@ class SFixMath Better to use .sL() if possible instead. @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` @param op The shift number - @return The result of the shift as a UFixMath. + @return The result of the shift as a UFix. */ - SFixMath operator<< (const int8_t op) const + SFix operator<< (const int8_t op) const { - return SFixMath(internal_value<(internal_value< - SFixMath sR() + SFix sR() { - return SFixMath(internal_value,true); + return SFix(internal_value,true); } /** Safe and optimal left shift. The returned type will be adjusted accordingly @param op The shift number - @return The result of the shift as a UFixMath of bigger size. + @return The result of the shift as a UFix of bigger size. */ template - SFixMath sL() + SFix sL() { - return SFixMath(internal_value,true); + return SFix(internal_value,true); } //////// COMPARISON OVERLOADS - /** Comparison with another SFixMath. - @param op A UFixMath + /** Comparison with another SFix. + @param op A UFix @return true if this is bigger than op, false otherwise */ template - bool operator> (const SFixMath<_NI,_NF>& op) const + bool operator> (const SFix<_NI,_NF>& op) const { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFixMath left(*this); - SFixMath right(op); + SFix left(*this); + SFix right(op); return left.asRaw()>right.asRaw(); } - /** Comparison with another SFixMath. - @param op A UFixMath + /** Comparison with another SFix. + @param op A UFix @return true if this is smaller than op, false otherwise */ template - bool operator< (const SFixMath<_NI,_NF>& op) const + bool operator< (const SFix<_NI,_NF>& op) const { return op > *this; } - /** Comparison with another SFixMath. - @param op A UFixMath + /** Comparison with another SFix. + @param op A UFix @return true if this is equal to op, false otherwise */ template - bool operator== (const SFixMath<_NI,_NF>& op) const + bool operator== (const SFix<_NI,_NF>& op) const { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFixMath left(*this); - SFixMath right(op); + SFix left(*this); + SFix right(op); return left.asRaw()==right.asRaw(); } - /** Comparison with another SFixMath. - @param op A UFixMath + /** Comparison with another SFix. + @param op A UFix @return true if this is not equal to op, false otherwise */ template - bool operator!= (const SFixMath<_NI,_NF>& op) const + bool operator!= (const SFix<_NI,_NF>& op) const { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFixMath left(*this); - SFixMath right(op); + SFix left(*this); + SFix right(op); return left.asRaw()!=right.asRaw(); } - /** Returns the number as a UFixMath of same (positive) range and precision. The initial value has to be positive to return something correct. This is more optimized than a cast. - @return a UFixMath + /** Returns the number as a UFix of same (positive) range and precision. The initial value has to be positive to return something correct. This is more optimized than a cast. + @return a UFix */ - UFixMath asUFix() + UFix asUFix() const { - return UFixMath(internal_value,true); + return UFix(internal_value,true); } /** Returns the value as floating point number. @return The floating point value. */ - float asFloat() { return (static_cast(internal_value)) / (next_greater_type(1)<(internal_value)) / (next_greater_type(1)< // Multiplication template -inline SFixMath operator*(uint8_t op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(uint8_t op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(uint16_t op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(uint16_t op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(uint32_t op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(uint32_t op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(uint64_t op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(uint64_t op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(int8_t op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(int8_t op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(int16_t op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(int16_t op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(int32_t op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(int32_t op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(int64_t op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(int64_t op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(float op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(float op, const SFix& uf) {return uf*op;} template -inline SFixMath operator*(double op, const SFixMath& uf) {return uf*op;} +inline SFix operator*(double op, const SFix& uf) {return uf*op;} // Addition template -inline SFixMath operator+(uint8_t op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(uint8_t op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(uint16_t op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(uint16_t op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(uint32_t op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(uint32_t op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(uint64_t op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(uint64_t op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(int8_t op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(int8_t op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(int16_t op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(int16_t op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(int32_t op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(int32_t op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(int64_t op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(int64_t op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(float op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(float op, const SFix& uf) {return uf+op;} template -inline SFixMath operator+(double op, const SFixMath& uf) {return uf+op;} +inline SFix operator+(double op, const SFix& uf) {return uf+op;} // Substraction template -inline SFixMath operator-(uint8_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(uint8_t op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(uint16_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(uint16_t op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(uint32_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(uint32_t op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(uint64_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(uint64_t op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(int8_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(int8_t op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(int16_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(int16_t op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(int32_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(int32_t op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(int64_t op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(int64_t op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(float op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(float op, const SFix& uf) {return (-uf)+op;} template -inline SFixMath operator-(double op, const SFixMath& uf) {return (-uf)+op;} +inline SFix operator-(double op, const SFix& uf) {return (-uf)+op;} #endif @@ -1100,147 +1106,147 @@ inline SFixMath operator-(double op, const SFixMath& uf) {return -/** Addition between a SFixMath and a UFixMath. Safe. - @param op1 A SFixMath - @param op2 A UFixMath - @return The result of the addition of op1 and op2. As a SFixMath +/** Addition between a SFix and a UFix. Safe. + @param op1 A SFix + @param op2 A UFix + @return The result of the addition of op1 and op2. As a SFix */ template -inline SFixMath operator+ (const SFixMath& op1, const UFixMath<_NI,_NF,_RANGE>& op2 ) +inline SFix operator+ (const SFix& op1, const UFix<_NI,_NF,_RANGE>& op2 ) { return op2+op1; } -/** Subtraction between a UFixMath and a SFixMath. Safe. - @param op1 A UFixMath - @param op2 A SFixMath - @return The result of the subtraction of op1 by op2. As a SFixMath +/** Subtraction between a UFix and a SFix. Safe. + @param op1 A UFix + @param op2 A SFix + @return The result of the subtraction of op1 by op2. As a SFix */ template -inline SFixMath operator- (const UFixMath& op1, const SFixMath<_NI,_NF, _RANGE>& op2) +inline SFix operator- (const UFix& op1, const SFix<_NI,_NF, _RANGE>& op2) { return -op2+op1; } -/** Multiplication between a SFixMath and a UFixMath. Safe. - @param op1 A SFixMath - @param op2 A UFixMath - @return The result of the multiplication of op1 and op2. As a SFixMath +/** Multiplication between a SFix and a UFix. Safe. + @param op1 A SFix + @param op2 A UFix + @return The result of the multiplication of op1 and op2. As a SFix */ template -inline SFixMath operator* (const SFixMath<_NI,_NF,_RANGE>& op1, const UFixMath& op2) +inline SFix operator* (const SFix<_NI,_NF,_RANGE>& op1, const UFix& op2) { return op2*op1; } -// Comparison between SFixMath and UFixmath +// Comparison between SFix and UFixmath -/** Comparison between a SFixMath and an UFixMath. - @param op1 a SFixMath - @param op2 A UFixMath +/** Comparison between a SFix and an UFix. + @param op1 a SFix + @param op2 A UFix @return true if op1 is bigger than op2, false otherwise */ template -inline bool operator> (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline bool operator> (const SFix& op1, const UFix<_NI,_NF>& op2 ) { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFixMath left(op1); - SFixMath right(op2); + SFix left(op1); + SFix right(op2); return left.asRaw() > right.asRaw(); } -/** Comparison between a UFixMath and an SFixMath. - @param op1 a UFixMath - @param op2 A SFixMath +/** Comparison between a UFix and an SFix. + @param op1 a UFix + @param op2 A SFix @return true if op1 is bigger than op2, false otherwise */ template -inline bool operator> (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline bool operator> (const UFix& op1, const SFix<_NI,_NF>& op2 ) { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFixMath left(op1); - SFixMath right(op2); + SFix left(op1); + SFix right(op2); return left.asRaw() > right.asRaw(); } -/** Comparison between a UFixMath and an SFixMath. - @param op1 a UFixMath - @param op2 A SFixMath +/** Comparison between a UFix and an SFix. + @param op1 a UFix + @param op2 A SFix @return true if op1 is smaller than op2, false otherwise */ template -inline bool operator< (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline bool operator< (const UFix& op1, const SFix<_NI,_NF>& op2 ) { return op2 > op1; } -/** Comparison between a SFixMath and an UFixMath. - @param op1 a SFixMath - @param op2 A UFixMath +/** Comparison between a SFix and an UFix. + @param op1 a SFix + @param op2 A UFix @return true if op1 is smaller than op2, false otherwise */ template -inline bool operator< (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline bool operator< (const SFix& op1, const UFix<_NI,_NF>& op2 ) { return op2 > op1; } -/** Comparison between a SFixMath and an UFixMath. - @param op1 a SFixMath - @param op2 A UFixMath +/** Comparison between a SFix and an UFix. + @param op1 a SFix + @param op2 A UFix @return true if op1 is equal to op2, false otherwise */ template -inline bool operator== (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline bool operator== (const SFix& op1, const UFix<_NI,_NF>& op2 ) { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFixMath left(op1); - SFixMath right(op2); + SFix left(op1); + SFix right(op2); return left.asRaw() == right.asRaw(); } -/** Comparison between a UFixMath and an SFixMath. - @param op1 a UFixMath - @param op2 A SFixMath +/** Comparison between a UFix and an SFix. + @param op1 a UFix + @param op2 A SFix @return true if op1 is equal to op2, false otherwise */ template -inline bool operator== (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline bool operator== (const UFix& op1, const SFix<_NI,_NF>& op2 ) { return op2 == op1; } -/** Comparison between a SFixMath and an UFixMath. - @param op1 a SFixMath - @param op2 A UFixMath +/** Comparison between a SFix and an UFix. + @param op1 a SFix + @param op2 A UFix @return true if op1 is not equal to op2, false otherwise */ template -inline bool operator!= (const SFixMath& op1, const UFixMath<_NI,_NF>& op2 ) +inline bool operator!= (const SFix& op1, const UFix<_NI,_NF>& op2 ) { constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFixMath left(op1); - SFixMath right(op2); + SFix left(op1); + SFix right(op2); return left.asRaw() != right.asRaw(); } -/** Comparison between a UFixMath and an SFixMath. - @param op1 a UFixMath - @param op2 A SFixMath +/** Comparison between a UFix and an SFix. + @param op1 a UFix + @param op2 A SFix @return true if op1 is not equal to op2, false otherwise */ template -inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ) +inline bool operator!= (const UFix& op1, const SFix<_NI,_NF>& op2 ) { return op2 != op1; } @@ -1248,7 +1254,7 @@ inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 ////// Helper functions to build SFix from a normal type automatically -/** Create a *pure* fractional signed fixed number (SFixMath) from a integer. +/** Create a *pure* fractional signed fixed number (SFix) from a integer. The number of fractional bits (NF) is chosen automatically depending on the input type. Hence toSFraction(127) and toSFraction(int8_t(127)) *do not* lead to the same thing: on an AVR, the former will lead to NF=15 - which is overkill and @@ -1257,14 +1263,14 @@ inline bool operator!= (const UFixMath& op1, const SFixMath<_NI,_NF>& op2 returns correct types, hence you can use this function to convert the return value of a Mozzi's function/class member into a pure fractional number. @param val The value to be converted into a pure fractional number. - @return A SFixMath<0,NF> with NF chosen according to the input type + @return A SFix<0,NF> with NF chosen according to the input type */ template -inline SFixMath<0, sizeof(T)*8-1> toSFraction(T val) { - return SFixMath<0, sizeof(T)*8-1>::fromRaw(val); +inline SFix<0, sizeof(T)*8-1> toSFraction(T val) { + return SFix<0, sizeof(T)*8-1>::fromRaw(val); } -/** Create a *pure* integer signed fixed number (SFixMath) from a integer. +/** Create a *pure* integer signed fixed number (SFix) from a integer. The number of fractional bits (NI) is chosen automatically depending on the input type. Hence toSInt(127) and toSInt(int8_t(127)) *do not* lead to the same thing: on an AVR, the former will lead to NI=15 - which is overkill - @@ -1272,11 +1278,11 @@ inline SFixMath<0, sizeof(T)*8-1> toSFraction(T val) { returns correct types, hence you can use this function to convert the return value of a Mozzi's function/class member into a pure fractional number. @param val The value to be converted into a pure integer fixed math number. - @return A SFixMath with NI chosen according to the input type + @return A SFix with NI chosen according to the input type */ template -inline SFixMath toSInt(T val) { - return SFixMath::fromRaw(val); +inline SFix toSInt(T val) { + return SFix::fromRaw(val); } From e5711b51a914fd8dd74bce4d90072221920c7ce6 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 11 Feb 2024 14:11:07 +0100 Subject: [PATCH 129/215] Adapted Oscil to FixMath (template for phmod, naming) tt --- Oscil.h | 70 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/Oscil.h b/Oscil.h index 7e0469c5b..03c1e4556 100644 --- a/Oscil.h +++ b/Oscil.h @@ -153,12 +153,27 @@ class Oscil /** Returns the next sample given a phase modulation value. @param phmod_proportion a phase modulation value given as a proportion of the wave. The - phmod_proportion parameter is a SFixMath<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in + phmod_proportion parameter is a SFix fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in + each direction. This fixed point math number is interpreted as a SFix<15,16> internally. + @return a sample from the table. + */ + template + inline + int8_t phMod(SFix phmod_proportion) + { + return phMod(SFix<15,16>(phmod_proportion).asRaw()); + } + + + + /** Returns the next sample given a phase modulation value. + @param phmod_proportion a phase modulation value given as a proportion of the wave. The + phmod_proportion parameter is a SFix<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in each direction. @return a sample from the table. */ inline - int8_t phMod(SFixMath<15,16> phmod_proportion) + int8_t phMod(SFix<15,16> phmod_proportion) { return phMod(phmod_proportion.asRaw()); } @@ -193,6 +208,21 @@ class Oscil } + /** Set the frequency using UFix fixed-point number format. This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors. + @note This should work OK with tables 2048 cells or smaller and + frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz. + @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. + @param frequency in UFix fixed-point number format. + */ + template + inline + void setFreq(UFix frequency) + { + setFreq_Q16n16(UFix<16,16>(frequency).asRaw()); + } + + + /** Set the frequency using Q24n8 fixed-point number format. This might be faster than the float version for setting low frequencies such as 1.5 Hz, or other values which may not work well with your table size. A Q24n8 @@ -217,15 +247,15 @@ class Oscil } } - /** Set the frequency using UFixMath<24,8> fixed-point number format. + /** Set the frequency using UFix<24,8> fixed-point number format. This might be faster than the float version for setting low frequencies such as - 1.5 Hz, or other values which may not work well with your table size. A UFixMath<24,8> + 1.5 Hz, or other values which may not work well with your table size. A UFix<24,8> representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE less than 64 Hz. - @param frequency in UFixMath<24,8> fixed-point number format. + @param frequency in UFix<24,8> fixed-point number format. */ inline - void setFreq(UFixMath<24,8> frequency) + void setFreq(UFix<24,8> frequency) { setFreq_Q24n8(frequency.asRaw()); } @@ -255,45 +285,33 @@ class Oscil } - /** Set the frequency using UFixMath<16,16> fixed-point number format. This is useful in - combination with Q16n16_mtof(), a fast alternative to mtof(), using UFixMath<16,16> + /** Set the frequency using UFix<16,16> fixed-point number format. This is useful in + combination with Q16n16_mtof(), a fast alternative to mtof(), using UFix<16,16> fixed-point format instead of fractional numbers. @note This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz. @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. - @param frequency in UFixMath<16,16> fixed-point number format. + @param frequency in UFix<16,16> fixed-point number format. */ inline - void setFreq(UFixMath<16,16> frequency) + void setFreq(UFix<16,16> frequency) { setFreq_Q16n16(frequency.asRaw()); } - /** Set the frequency using UFixMath fixed-point number format. This falls back to using UFixMath<16,16> internally and is provided as a fallout for other UFixMath types. If possible try to use directly UFixMath<16,16> or UFixMath<24,8> for well defined (and well tested) behaviors. - @note This should work OK with tables 2048 cells or smaller and - frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz. - @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. - @param frequency in UFixMath fixed-point number format. - */ - template - inline - void setFreq(UFixMath frequency) - { - setFreq_Q16n16(UFixMath<16,16>(frequency).asRaw()); - } - /** Set the frequency using SFixMath fixed-point number format. This falls back to using UFixMath<16,16> internally and is provided as a fallout for other UFixMath types. If possible try to use directly UFixMath<16,16> or UFixMath<24,8> for well defined (and well tested) behaviors. + /** Set the frequency using SFix fixed-point number format. This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors. @note This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz. @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. - @param frequency in SFixMath<16,16> fixed-point number format. + @param frequency in SFix<16,16> fixed-point number format. */ template inline - void setFreq(SFixMath frequency) + void setFreq(SFix frequency) { - setFreq_Q16n16(UFixMath<16,16>(frequency).asRaw()); + setFreq_Q16n16(UFix<16,16>(frequency).asRaw()); } /* From c0bed9ac776d6829837ba600948ee77ab230b848 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 11 Feb 2024 14:20:37 +0100 Subject: [PATCH 130/215] Adapted mozzi_midi to new FixMath naming --- mozzi_midi.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mozzi_midi.h b/mozzi_midi.h index 20ad01cce..9ee8bc8d1 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -113,21 +113,21 @@ inline Q16n16 Q16n16_mtof(Q16n16 midival_fractional) return (Q16n16) (freq1+ diff_fraction); }; -inline UFixMath<16,16> mtof(UFixMath<16,16> midival) +inline UFix<16,16> mtof(UFix<16,16> midival) { - return UFixMath<16,16>::fromRaw(Q16n16_mtof(midival.asRaw())); + return UFix<16,16>::fromRaw(Q16n16_mtof(midival.asRaw())); } template - inline UFixMath<16,16> mtof(UFixMath midival) + inline UFix<16,16> mtof(UFix midival) { - return UFixMath<16,16>::fromRaw(Q16n16_mtof(UFixMath<16,16>(midival).asRaw())); + return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw())); } template - inline UFixMath<16,16> mtof(SFixMath midival) + inline UFix<16,16> mtof(SFix midival) { - return UFixMath<16,16>::fromRaw(Q16n16_mtof(UFixMath<16,16>(midival).asRaw())); + return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw())); } #endif /* MOZZI_MIDI_H_ */ From 3df5bf1fa0a00b53e8c83a6387cf21a2562c4805 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 11 Feb 2024 14:33:00 +0100 Subject: [PATCH 131/215] Updated examples using FixMath --- examples/01.Basics/Vibrato/Vibrato.ino | 4 ++-- .../Vibrato_Midi_Note/Vibrato_Midi_Note.ino | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/01.Basics/Vibrato/Vibrato.ino b/examples/01.Basics/Vibrato/Vibrato.ino index d431f0e7a..a2ad583f5 100644 --- a/examples/01.Basics/Vibrato/Vibrato.ino +++ b/examples/01.Basics/Vibrato/Vibrato.ino @@ -29,7 +29,7 @@ Oscil aCos(COS2048_DATA); Oscil aVibrato(COS2048_DATA); //const byte intensity = 255; -const UFixMath<0,8> intensity = 0.5; // amplitude of the phase modulation +const UFix<0,8> intensity = 0.5; // amplitude of the phase modulation // 0.5 leads to a modulation of half the // wavetable @@ -46,7 +46,7 @@ void updateControl(){ AudioOutput_t updateAudio(){ //Q15n16 vibrato = (Q15n16) intensity * aVibrato.next(); - auto vibrato = intensity * SFixMath<0, 7>::fromRaw(aVibrato.next()); // Oscils in Mozzi are 8bits: 7bits of signal plus one bit of sign, so what they fit into a SFixMath<0,7> which is a signed fixMath type with 7 bits of value. + auto vibrato = intensity * toSFraction(aVibrato.next()); // Oscils in Mozzi are 8bits: 7bits of signal plus one bit of sign, so what they fit into a SFixMath<0,7> which is a signed fixMath type with 7 bits of value. return MonoOutput::from8Bit(aCos.phMod(vibrato)); // phase modulation to modulate frequency } diff --git a/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino b/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino index 18cddc8e2..17a20f183 100644 --- a/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino +++ b/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino @@ -27,14 +27,14 @@ Oscil aCos(COS2048_DATA); Oscil kVibrato(COS2048_DATA); -UFixMath<7, 0> midi_note = 65; -UFixMath<2, 1> mod_amplitude = 2.5; // the amplitude of the vibrato, in semi-tones. +UFix<7, 0> midi_note = 65; +UFix<2, 1> mod_amplitude = 2.5; // the amplitude of the vibrato, in semi-tones. // 2.5 can be represented with only 2 integer bits // and 1 fractionnal bit - // hence UFixMath<2,1> is good enough to represent + // hence UFix<2,1> is good enough to represent // that number. You can put numbers with decimals // or higher ones, but beware to adjust the number - // of bits NI and NF of the UFixMath accordingly. + // of bits NI and NF of the UFix accordingly. // It is always good to keep these as small as possible // for performances. @@ -42,12 +42,12 @@ UFixMath<2, 1> mod_amplitude = 2.5; // the amplitude of the vibrato, in semi-to void setup() { startMozzi(CONTROL_RATE); aCos.setFreq(mtof(midi_note)); - kVibrato.setFreq(UFixMath<16, 16>(10)); // frequency of the modulation + kVibrato.setFreq(UFix<16, 16>(10)); // frequency of the modulation } void updateControl() { - auto modulation = SFixMath<0, 7>::fromRaw(kVibrato.next()) * mod_amplitude; // Oscil in Mozzi are fundamentally 8 bits: 7bits of data and 1bit of sign. + auto modulation = toSFraction(kVibrato.next()) * mod_amplitude; // Oscil in Mozzi are fundamentally 8 bits: 7bits of data and 1bit of sign. // Here, we make it oscillate between nearly -1 and 1 (no integer bit). // The FixMath class will take care of making modulation the correct type // to preserve range and precision. From aff581994d85857a7a705ffd9c6200878fae0c0f Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 11 Feb 2024 14:33:47 +0100 Subject: [PATCH 132/215] BugFix with template argument of FixMath --- Oscil.h | 10 +++++----- mozzi_midi.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Oscil.h b/Oscil.h index 03c1e4556..0e55ec454 100644 --- a/Oscil.h +++ b/Oscil.h @@ -214,7 +214,7 @@ class Oscil @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. @param frequency in UFix fixed-point number format. */ - template + template inline void setFreq(UFix frequency) { @@ -254,11 +254,11 @@ class Oscil less than 64 Hz. @param frequency in UFix<24,8> fixed-point number format. */ - inline + inline void setFreq(UFix<24,8> frequency) { setFreq_Q24n8(frequency.asRaw()); - } + } /** Set the frequency using Q16n16 fixed-point number format. This is useful in @@ -293,11 +293,11 @@ class Oscil @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. @param frequency in UFix<16,16> fixed-point number format. */ - inline + inline void setFreq(UFix<16,16> frequency) { setFreq_Q16n16(frequency.asRaw()); - } + } diff --git a/mozzi_midi.h b/mozzi_midi.h index 9ee8bc8d1..0f51fca38 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -118,13 +118,13 @@ inline UFix<16,16> mtof(UFix<16,16> midival) return UFix<16,16>::fromRaw(Q16n16_mtof(midival.asRaw())); } -template +template inline UFix<16,16> mtof(UFix midival) { return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw())); } -template +template inline UFix<16,16> mtof(SFix midival) { return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw())); From 3ecd0ffa2f0f923c92d0d7ac11512f15d62fea9a Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 27 Jan 2024 16:46:50 +0100 Subject: [PATCH 133/215] Remove STEREO_HACK This has been deprecated for several years, now. Also, as this is a config option, projects using it will need to adjust, anyway, so it does not actually help to keep sketches working. While in the process, turn AudioOutput and AudioOutput_t into typedefs, rather than #defines to reduce the macro-mess. This required moving some bits around, however. --- AudioOutput.h | 105 +++++++++++++++------------- config/mozzi_config_documentation.h | 3 +- internal/MozziGuts.hpp | 10 --- internal/config_checks_generic.h | 5 -- 4 files changed, 57 insertions(+), 66 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index 077a32955..e85fa3f4e 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -56,13 +56,23 @@ #define SCALE_AUDIO_NEAR(x,bits) (bits > MOZZI_AUDIO_BITS_OPTIMISTIC ? (x) >> (bits - MOZZI_AUDIO_BITS_OPTIMISTIC) : (x) << (MOZZI_AUDIO_BITS_OPTIMISTIC - bits)) #define CLIP_AUDIO(x) constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) MOZZI_AUDIO_BIAS-1) +struct MonoOutput; +struct StereoOutput; + #if MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO) -#define AudioOutput StereoOutput -#if (STEREO_HACK == true) -#define AudioOutput_t void +typedef StereoOutput AudioOutput; #else -#define AudioOutput_t StereoOutput +/** Representation of an single audio output sample/frame. This typedef maps to either MonoOutput or StereoOutput, depending on what is configured + * in MOZZI_AUDIO_CHANNELS. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g. + * both have functions l() and r(), to return "two" audio channels (which will be the same in case of mono). + * + * You will not usually use or encounter this definition, unless using @ref external_audio output mode. + */ +typedef MonoOutput AudioOutput; #endif + +#if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LEVEL_2_0 +typedef int AudioOutput_t; // keep sketches using "int updateAudio()" alive #else /** Representation of an single audio output sample/frame. For mono output, this is really just a single zero-centered int, * but for stereo it's a struct containing two ints. @@ -75,50 +85,10 @@ * dummy used to make the "same" function signature work across different configurations (importantly mono/stereo). It's true value * might be subject to change, and it may even be void. Use either MonoOutput or StereoOutput to represent a piece of audio output. */ -#define AudioOutput_t AudioOutputStorage_t -/** Representation of an single audio output sample/frame. This #define maps to either MonoOutput or StereoOutput, depending on what is configured - * in MOZZI_AUDIO_CHANNELS. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g. - * both have functions l() and r(), to return "two" audio channels (which will be the same in case of mono). - * - * You will not usually use or encounter this definition, unless using @ref external_audio output mode. - */ -#define AudioOutput MonoOutput +typedef AudioOutput AudioOutput_t; // Note: Needed for pre 1.1 backwards compatibility +// TODO AudioOutput_t itself could be phased out, eventually, simply using AudioOutput, instead. #endif -/** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to two int values, but the struct provides - * useful API an top of that. For more detail see @ref MonoOutput . */ -struct StereoOutput { - /** Construct an audio frame from raw values (zero-centered) */ - StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r) : _l(l), _r(r) {}; - /** Default contstructor */ - StereoOutput() : _l(0), _r(0) {}; -#if !MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO) - /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning). - This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time - using StereoOutput in a mono config, is not intended. */ - inline AudioOutput_t portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; }; -# if GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO - inline operator AudioOutput_t() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; }; -# endif -#endif - AudioOutputStorage_t l() const { return _l; }; - AudioOutputStorage_t r() const { return _r; }; - /** See @ref MonoOutput::clip(). Clips both channels. */ - StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; }; - - /** See @ref MonoOutput::fromNBit(), stereo variant */ -template static inline StereoOutput fromNBit(uint8_t bits, T l, T r) { return StereoOutput(SCALE_AUDIO(l, bits), SCALE_AUDIO(r, bits)); } - /** See @ref MonoOutput::from8Bit(), stereo variant */ - static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); } - /** See @ref MonoOutput::from16Bit(), stereo variant */ - static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); } - /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */ - template static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); } -private: - AudioOutputStorage_t _l; - AudioOutputStorage_t _r; -}; - /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to a single int value, but the struct provides * useful API an top of that, for the following: * @@ -140,10 +110,10 @@ struct MonoOutput { /** Conversion to stereo operator: If used in a stereo config, returns identical channels (and gives a compile time warning). This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ - inline StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check MOZZI_AUDIO_CHANNELS setting."))) { return StereoOutput(_l, _l); }; -#else + StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check MOZZI_AUDIO_CHANNELS setting."))); // Note: defintion below +#elif MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LEVEL_2_0 /** Conversion to int operator. */ - inline operator AudioOutput_t() const { return _l; }; + operator AudioOutput_t() const { return _l; }; #endif AudioOutputStorage_t l() const { return _l; }; AudioOutputStorage_t r() const { return _l; }; @@ -176,6 +146,43 @@ struct MonoOutput { AudioOutputStorage_t _l; }; +/** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to two int values, but the struct provides + * useful API an top of that. For more detail see @ref MonoOutput . */ +struct StereoOutput { + /** Construct an audio frame from raw values (zero-centered) */ + StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r) : _l(l), _r(r) {}; + /** Default contstructor */ + StereoOutput() : _l(0), _r(0) {}; +#if !MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO) + /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning). + This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time + using StereoOutput in a mono config, is not intended. */ + inline AudioOutput_t portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; }; +# if GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO + inline operator AudioOutput_t() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; }; +# endif +#endif + AudioOutputStorage_t l() const { return _l; }; + AudioOutputStorage_t r() const { return _r; }; + /** See @ref MonoOutput::clip(). Clips both channels. */ + StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; }; + + /** See @ref MonoOutput::fromNBit(), stereo variant */ +template static inline StereoOutput fromNBit(uint8_t bits, T l, T r) { return StereoOutput(SCALE_AUDIO(l, bits), SCALE_AUDIO(r, bits)); } + /** See @ref MonoOutput::from8Bit(), stereo variant */ + static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); } + /** See @ref MonoOutput::from16Bit(), stereo variant */ + static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); } + /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */ + template static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); } +private: + AudioOutputStorage_t _l; + AudioOutputStorage_t _r; +}; + +#if MOZZI_AUDIO_CHANNELS > 1 +StereoOutput MonoOutput::portable() const { return StereoOutput(_l, _l); }; +#endif #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) /** When setting using one of the external output modes (@ref MOZZI_OUTPUT_EXTERNAL_TIMED or @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM) implement this function to take care of writing samples to the hardware. diff --git a/config/mozzi_config_documentation.h b/config/mozzi_config_documentation.h index 523e1508b..c7b30fe14 100644 --- a/config/mozzi_config_documentation.h +++ b/config/mozzi_config_documentation.h @@ -98,8 +98,7 @@ * config, or vice versa will continue to work, but will generate a warning a * compile time. * - * @note This option superseeds the earlier STEREO_HACK, which is still available at - * the time of this writing, but should not be used in new sketches. + * @note This option superseeds the earlier STEREO_HACK in Mozzi < 1.1 * * @note At the time of this writing, only MOZZI_MONO and MOZZI_STEREO are supported. The value of * MOZZI_MONO is 1 and the value of MOZZI_STEREO is 2, so future extensions are also expected diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index e2994d4f0..44106f44f 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -75,12 +75,7 @@ inline void bufferAudioOutput(const AudioOutput_t f) { ++samples_written_to_buffer; } #else -# if (STEREO_HACK == true) -// ring buffer for audio output -CircularBuffer output_buffer; // fixed size 256 -# else CircularBuffer output_buffer; // fixed size 256 -# endif # define canBufferAudioOutput() (!output_buffer.isFull()) # define bufferAudioOutput(f) output_buffer.write(f) static void CACHED_FUNCTION_ATTR defaultAudioOutput() { @@ -225,12 +220,7 @@ void audioHook() // 2us on AVR excluding updateAudio() // setPin13High(); if (canBufferAudioOutput()) { advanceControlLoop(); -#if (STEREO_HACK == true) - updateAudio(); // in hacked version, this returns void - bufferAudioOutput(StereoOutput(audio_out_1, audio_out_2)); -#else bufferAudioOutput(updateAudio()); -#endif #if defined(LOOP_YIELD) LOOP_YIELD diff --git a/internal/config_checks_generic.h b/internal/config_checks_generic.h index 380b596ff..020240a2b 100644 --- a/internal/config_checks_generic.h +++ b/internal/config_checks_generic.h @@ -19,13 +19,8 @@ #endif #if not defined(MOZZI_AUDIO_CHANNELS) -#if (MOZZI_COMPATIBILITY_LEVEL <= MOZZI_COMPATIBILITY_1_1) && (STEREO_HACK == true) -#warning Use of STEREO_HACK is deprecated. Use AUDIO_CHANNELS STEREO, instead. -#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO -#else #define MOZZI_AUDIO_CHANNELS MOZZI_MONO #endif -#endif //MOZZI_AUDIO_MODE -> hardware specific //MOZZI_AUDIO_RATE -> hardware specific From 74a4fd18009f7f487fb752dde5dc5e2bdd5c520e Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 27 Jan 2024 17:03:39 +0100 Subject: [PATCH 134/215] Compilation fix for ESP8266 --- internal/MozziGuts_impl_ESP8266.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/MozziGuts_impl_ESP8266.hpp b/internal/MozziGuts_impl_ESP8266.hpp index da95b723f..ce4b8aa05 100644 --- a/internal/MozziGuts_impl_ESP8266.hpp +++ b/internal/MozziGuts_impl_ESP8266.hpp @@ -83,7 +83,7 @@ void CACHED_FUNCTION_ATTR esp8266_serial_audio_output() { inline void audioOutput(const AudioOutput f) { // optimized version of: Serial1.write(...); for (uint8_t i = 0; i < MOZZI_PDM_RESOLUTION*4; ++i) { - U1F = pdmCode8(f+MOZZI_AUDIO_BIAS); + U1F = pdmCode8(f.l()+MOZZI_AUDIO_BIAS); } } # endif From 9d38f3e4617912168b1b455bdcbe973cbb3377e1 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 27 Jan 2024 17:42:16 +0100 Subject: [PATCH 135/215] Partial revert to counter flash usage increas --- AudioOutput.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index e85fa3f4e..9d40aa50d 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -71,8 +71,9 @@ typedef StereoOutput AudioOutput; typedef MonoOutput AudioOutput; #endif -#if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LEVEL_2_0 -typedef int AudioOutput_t; // keep sketches using "int updateAudio()" alive +#if MOZZI_AUDIO_CHANNELS < MOZZI_STEREO +// NOTE / TODO: Unfortunately, for reasons yet to investigate, aliasing to MonoOutput, instead, here, adds a bunch of flash usage +typedef AudioOutputStorage_t AudioOutput_t; // keep sketches using "int updateAudio()" alive #else /** Representation of an single audio output sample/frame. For mono output, this is really just a single zero-centered int, * but for stereo it's a struct containing two ints. @@ -86,7 +87,6 @@ typedef int AudioOutput_t; // keep sketches using "int updateAudio()" alive * might be subject to change, and it may even be void. Use either MonoOutput or StereoOutput to represent a piece of audio output. */ typedef AudioOutput AudioOutput_t; // Note: Needed for pre 1.1 backwards compatibility -// TODO AudioOutput_t itself could be phased out, eventually, simply using AudioOutput, instead. #endif /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to a single int value, but the struct provides @@ -111,10 +111,10 @@ struct MonoOutput { This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check MOZZI_AUDIO_CHANNELS setting."))); // Note: defintion below -#elif MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LEVEL_2_0 - /** Conversion to int operator. */ - operator AudioOutput_t() const { return _l; }; #endif + /** Conversion to int operator. */ + operator AudioOutputStorage_t() const { return _l; }; + AudioOutputStorage_t l() const { return _l; }; AudioOutputStorage_t r() const { return _l; }; /** Clip frame to supported range. This is useful when at times, but only rarely, the signal may exceed the usual range. Using this function does not avoid From 58488e350f27b22381b802905cbc93e326e44d7a Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 27 Jan 2024 17:53:58 +0100 Subject: [PATCH 136/215] Replace some defines with constexpr functions. (PR report will tell us, whether compiler is smart enough in all cases) --- AudioOutput.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index 9d40aa50d..52dee31df 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -52,9 +52,9 @@ * than 16 bits). */ #define AudioOutputStorage_t int -#define SCALE_AUDIO(x,bits) (bits > MOZZI_AUDIO_BITS ? (x) >> (bits - MOZZI_AUDIO_BITS) : (x) << (MOZZI_AUDIO_BITS - bits)) -#define SCALE_AUDIO_NEAR(x,bits) (bits > MOZZI_AUDIO_BITS_OPTIMISTIC ? (x) >> (bits - MOZZI_AUDIO_BITS_OPTIMISTIC) : (x) << (MOZZI_AUDIO_BITS_OPTIMISTIC - bits)) -#define CLIP_AUDIO(x) constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) MOZZI_AUDIO_BIAS-1) +template constexpr AudioOutputStorage_t SCALE_AUDIO(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS ? (x) >> (bits - MOZZI_AUDIO_BITS) : (x) << (MOZZI_AUDIO_BITS - bits)); } +template constexpr AudioOutputStorage_t SCALE_AUDIO_NEAR(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS_OPTIMISTIC ? (x) >> (bits - MOZZI_AUDIO_BITS_OPTIMISTIC) : (x) << (MOZZI_AUDIO_BITS_OPTIMISTIC - bits)); } +template constexpr AudioOutputStorage_t CLIP_AUDIO(T x) { return (constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) MOZZI_AUDIO_BIAS-1)); } struct MonoOutput; struct StereoOutput; From 911ee4992283670807c56082e2bad55e2b3d6bb3 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 28 Jan 2024 22:30:49 +0100 Subject: [PATCH 137/215] CONTROL_RATE -> MOZZI_CONTROL_RATE While the old name continues to work, let's be consistent in the examples. For the same reason (and to silence some legit compiler warnings; consider what happends when changing after inclusion of PDResonsant.h, for example!), move it above #include , in all examples. Change occurences of startMozzi(CONTROL_RATE) to simply startMozzi(), which does the same thing. --- ADSR.h | 16 ++++---- Ead.h | 2 +- MozziGuts.h | 4 +- Oscil.h | 4 +- PDResonant.h | 4 +- Phasor.h | 8 +--- Sample.h | 4 +- Smooth.h | 2 +- WavePacket.h | 2 +- config/mozzi_config_documentation.h | 2 +- examples/01.Basics/Sinewave/Sinewave.ino | 9 ++--- examples/01.Basics/Skeleton/Skeleton.ino | 7 ++-- .../Skeleton_Multi/Skeleton_Multi.ino | 2 +- .../Table_Resolution/Table_Resolution.ino | 7 ++-- examples/01.Basics/Vibrato/Vibrato.ino | 5 +-- .../Control_Echo_Theremin.ino | 10 ++--- .../Control_Oscil_Wash/Control_Oscil_Wash.ino | 37 +++++++++---------- .../Control_Tremelo/Control_Tremelo.ino | 9 ++--- examples/02.Control/EventDelay/EventDelay.ino | 7 ++-- examples/02.Control/Line_Gliss/Line_Gliss.ino | 7 ++-- .../Line_Gliss_Double_32k_HIFI.ino | 2 +- .../Knob_LightLevel_x2_FMsynth.ino | 2 +- .../Light_Temperature_Multi_Oscil.ino | 21 +++++------ .../Piezo_Frequency/Piezo_Frequency.ino | 7 ++-- .../Piezo_SampleScrubber.ino | 2 +- examples/03.Sensors/RCpoll/RCpoll.ino | 4 +- .../Line_vs_Smooth/Line_vs_Smooth.ino | 7 ++-- .../MIDI_portamento/MIDI_portamento.ino | 11 +++--- examples/05.Control_Filters/Smooth/Smooth.ino | 5 +-- .../Smooth_Frequency/Smooth_Frequency.ino | 9 ++--- .../Thermistor_OverSample.ino | 2 +- examples/06.Synthesis/AMsynth/AMsynth.ino | 7 ++-- .../AMsynth_HIFI/AMsynth_HIFI.ino | 4 +- .../Difference_Tone/Difference_Tone.ino | 2 +- examples/06.Synthesis/FMsynth/FMsynth.ino | 9 ++--- .../FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino | 9 ++--- .../NonAlias_MetaOscil/NonAlias_MetaOscil.ino | 8 ++-- .../06.Synthesis/PDresonant/PDresonant.ino | 2 +- .../06.Synthesis/WaveFolder/WaveFolder.ino | 8 ++-- .../06.Synthesis/Waveshaper/Waveshaper.ino | 2 +- .../ADSR_Audio_Rate_Envelope.ino | 2 +- .../ADSR_Audio_Rate_Envelope_Long.ino | 2 +- .../ADSR_Audio_Rate_Envelope_x2.ino | 6 +-- .../ADSR_Control_Rate_Envelope.ino | 9 ++--- .../Ead_Envelope/Ead_Envelope.ino | 7 ++-- .../Phasemod_Envelope/Phasemod_Envelope.ino | 9 ++--- examples/08.Samples/Sample/Sample.ino | 2 +- .../Sample_Loop_Points/Sample_Loop_Points.ino | 7 ++-- .../08.Samples/Sample_Scrub/Sample_Scrub.ino | 6 +-- examples/08.Samples/Samples/Samples.ino | 2 +- .../Samples_Tables_Arrays.ino | 4 +- .../Wavetable_Swap/Wavetable_Swap.ino | 2 +- examples/09.Delays/AudioDelay/AudioDelay.ino | 7 ++-- .../AudioDelayFeedback/AudioDelayFeedback.ino | 7 ++-- .../AudioDelayFeedbackAllpass.ino | 7 ++-- .../AudioDelayFeedbackX2.ino | 9 ++--- .../AudioDelayFeedback_HIFI.ino | 7 ++-- .../ReverbTank_HIFI/ReverbTank_HIFI.ino | 9 ++--- .../ReverbTank_STANDARD.ino | 9 ++--- .../LowPassFilterX2/LowPassFilterX2.ino | 4 +- .../MultiResonantFilter.ino | 8 ++-- .../ResonantFilter/ResonantFilter.ino | 4 +- .../ResonantFilter16/ResonantFilter16.ino | 8 ++-- .../StateVariableFilter.ino | 4 +- .../Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino | 9 ++--- .../Sinewave_PWM_leds_HIFI.ino | 6 +-- .../Teensy_USB_MIDI_Input.ino | 9 ++--- .../TwoWire_Read_ADXL345.ino | 7 ++-- .../12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino | 13 +++---- .../Risset_Beat_HIFI/Risset_Beat_HIFI.ino | 7 ++-- .../Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino | 11 +++--- examples/12.Misc/Stereo/Stereo.ino | 2 +- examples/12.Misc/Stereo_Pan/Stereo_Pan.ino | 2 +- .../FMsynth_MCP4921_mono_12bits.ino | 10 ++--- .../MCP4922_mono_24bits.ino | 8 ++-- .../PT8211_stereo_16bits.ino | 8 ++-- .../PT8211_stereo_16bits_STM32_SPI2.ino | 10 ++--- .../Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino | 4 +- .../Sinewave_R2R_DAC_74HC595.ino | 4 +- .../Stereo_Pan_MCP4922_stereo_12bits.ino | 8 ++-- keywords.txt | 8 ++-- mozzi_analog.h | 2 +- 82 files changed, 248 insertions(+), 292 deletions(-) diff --git a/ADSR.h b/ADSR.h index 17607d47c..93f395a92 100644 --- a/ADSR.h +++ b/ADSR.h @@ -27,13 +27,13 @@ The "normal" way to use this would be with update() in updateControl(), where it and then next() is in updateAudio(), called much more often, where it interpolates between the control values. This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update. @tparam CONTROL_UPDATE_RATE The frequency of control updates. -Ordinarily this will be CONTROL_RATE, but an alternative (amongst others) is +Ordinarily this will be MOZZI_CONTROL_RATE, but an alternative (amongst others) is to set this as well as the LERP_RATE parameter to AUDIO_RATE, and call both update() and next() in updateAudio(). -Such a use would allow accurate envelopes with finer resolution of the control points than CONTROL_RATE. +Such a use would allow accurate envelopes with finer resolution of the control points than MOZZI_CONTROL_RATE. @tparam LERP_RATE Sets how often next() will be called, to interpolate between updates set by CONTROL_UPDATE_RATE. This will produce the smoothest results if it's set to AUDIO_RATE, but if you need to save processor time and your envelope changes slowly or controls something like a filter where there may not be problems with glitchy or clicking transitions, -LERP_RATE could be set to CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(), +LERP_RATE could be set to MOZZI_CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(), greatly reducing the amount of processing required compared to calling next() in updateAudio(). @todo Test whether using the template parameters makes any difference to speed, and rationalise which units do and don't need them. @@ -278,7 +278,7 @@ class ADSR /** Set the attack time of the ADSR in milliseconds. - The actual time taken will be resolved within the resolution of CONTROL_RATE. + The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE. @param msec the unsigned int attack time in milliseconds. @note Beware of low values (less than 20 or so, depending on how many steps are being taken), in case internal step size gets calculated as 0, which would mean nothing happens. @@ -291,7 +291,7 @@ class ADSR /** Set the decay time of the ADSR in milliseconds. - The actual time taken will be resolved within the resolution of CONTROL_RATE. + The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE. @param msec the unsigned int decay time in milliseconds. @note Beware of low values (less than 20 or so, depending on how many steps are being taken), in case internal step size gets calculated as 0, which would mean nothing happens. @@ -304,7 +304,7 @@ class ADSR /** Set the sustain time of the ADSR in milliseconds. - The actual time taken will be resolved within the resolution of CONTROL_RATE. + The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE. The sustain phase will finish if the ADSR recieves a noteOff(). @param msec the unsigned int sustain time in milliseconds. @note Beware of low values (less than 20 or so, depending on how many steps are being taken), @@ -319,7 +319,7 @@ class ADSR /** Set the release time of the ADSR in milliseconds. - The actual time taken will be resolved within the resolution of CONTROL_RATE. + The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE. @param msec the unsigned int release time in milliseconds. @note Beware of low values (less than 20 or so, depending on how many steps are being taken), in case internal step size gets calculated as 0, which would mean nothing happens. @@ -339,7 +339,7 @@ class ADSR /** Set the attack, decay and release times of the ADSR in milliseconds. - The actual times will be resolved within the resolution of CONTROL_RATE. + The actual times will be resolved within the resolution of MOZZI_CONTROL_RATE. @param attack_ms the new attack time in milliseconds. @param decay_ms the new decay time in milliseconds. @param sustain_ms the new sustain time in milliseconds. diff --git a/Ead.h b/Ead.h index a773e922b..ec59ef1c2 100644 --- a/Ead.h +++ b/Ead.h @@ -33,7 +33,7 @@ class Ead /** Constructor @param update_rate - Usually this will be CONTROL_RATE or AUDIO_RATE, unless you + Usually this will be MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE, unless you design another scheme for updating. One such alternative scheme could take turns for various control changes in a rotating schedule to spread out calculations made in successive updateControl() routines. diff --git a/MozziGuts.h b/MozziGuts.h index 131bfe8d5..488ae14bf 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -62,7 +62,7 @@ This function intializes the timer(s) needed to move audio samples to the output configured @ref MOZZI_AUDIO_MODE . @param control_rate_hz Sets how often updateControl() is called. It must be a power of 2. -If no parameter is provided, control_rate_hz is set to CONTROL_RATE, +If no parameter is provided, control_rate_hz is set to MOZZI_CONTROL_RATE, which has a default value of 64 (you can re-\#define it in your sketch). The practical upper limit for control rate depends on how busy the processor is, and you might need to do some tests to find the best setting. @@ -72,7 +72,7 @@ which disables digital inputs on all analog input pins. All in mozzi_analog.h a They are all called automatically and hidden away because it keeps things simple for a STANDARD_PLUS set up, but if it turns out to be confusing, they might need to become visible again. */ -void startMozzi(int control_rate_hz = CONTROL_RATE); +void startMozzi(int control_rate_hz = MOZZI_CONTROL_RATE); diff --git a/Oscil.h b/Oscil.h index b6be59aea..da90bdb4d 100644 --- a/Oscil.h +++ b/Oscil.h @@ -39,8 +39,8 @@ cycling oscillator, or atIndex() for a particular sample in the table. using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Oscil to run fast enough. @tparam UPDATE_RATE This will be AUDIO_RATE if the Oscil is updated in -updateAudio(), or CONTROL_RATE if it's updated each time updateControl() is -called. It could also be a fraction of CONTROL_RATE if you are doing some kind +updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is +called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load. @todo Use conditional compilation to optimise setFreq() variations for different table sizes. diff --git a/PDResonant.h b/PDResonant.h index a28e5b9b3..6357fb4bc 100644 --- a/PDResonant.h +++ b/PDResonant.h @@ -132,7 +132,7 @@ class PDResonant Phasor aResonanceFreqCounter; Oscil aOsc; - ADSR aAmpEnv; - ADSR kResonantFreqEnv; + ADSR aAmpEnv; + ADSR kResonantFreqEnv; }; diff --git a/Phasor.h b/Phasor.h index fd4ad31b1..8a6cf9383 100644 --- a/Phasor.h +++ b/Phasor.h @@ -12,11 +12,7 @@ #ifndef PHASOR_H_ #define PHASOR_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include "Arduino.h" #include "mozzi_fixmath.h" #define PHASOR_MAX_VALUE_UL 4294967295UL @@ -25,7 +21,7 @@ The output of Phasor.next() is an unsigned number between 0 and 4294967295, the maximum that can be expressed by an unsigned 32 bit integer. @tparam UPDATE_RATE the rate at which the Phasor will be updated, -usually CONTROL_RATE or AUDIO_RATE. +usually MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE. */ template diff --git a/Sample.h b/Sample.h index 9c79c1084..3a1ed9764 100644 --- a/Sample.h +++ b/Sample.h @@ -35,8 +35,8 @@ using. The sound table can be arbitrary length for Sample. It's important that NUM_TABLE_CELLS is either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Sample to run fast enough. @tparam UPDATE_RATE This will be AUDIO_RATE if the Sample is updated in -updateAudio(), or CONTROL_RATE if it's updated each time updateControl() is -called. It could also be a fraction of CONTROL_RATE if you are doing some kind +updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is +called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load. @section int8_t2mozzi Converting soundfiles for Mozzi. diff --git a/Smooth.h b/Smooth.h index c5bc62280..0ef02593f 100644 --- a/Smooth.h +++ b/Smooth.h @@ -21,7 +21,7 @@ y[i] := y[i-1] + α * (x[i] - y[i-1]), translated as out = last_out + a * (in - last_out). It's not calibrated to any real-world update rate, so if you use it at -CONTROL_RATE and you change CONTROL_RATE, you'll need to adjust the smoothness +MOZZI_CONTROL_RATE and you change MOZZI_CONTROL_RATE, you'll need to adjust the smoothness value to suit. @tparam T the type of numbers being smoothed. Watch out for numbers overflowing the internal calculations. Some experimentation is recommended. diff --git a/WavePacket.h b/WavePacket.h index 2b5f13033..dfadb3045 100644 --- a/WavePacket.h +++ b/WavePacket.h @@ -39,7 +39,7 @@ class WavePacket /** Constructor. */ - WavePacket():AUDIO_STEPS_PER_CONTROL(AUDIO_RATE / CONTROL_RATE) + WavePacket():AUDIO_STEPS_PER_CONTROL(MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE) { aCos.setTable(COS8192_DATA); } diff --git a/config/mozzi_config_documentation.h b/config/mozzi_config_documentation.h index c7b30fe14..b97327289 100644 --- a/config/mozzi_config_documentation.h +++ b/config/mozzi_config_documentation.h @@ -143,7 +143,7 @@ * can sometimes give smoother results, avoiding the need to interpolate * sensitive variables at audio rate in updateAudio(). * - * TODO: If a definition of CONTROL_RATE is detected, apply that with a warning. + * TODO: If a definition of MOZZI_CONTROL_RATE is detected, apply that with a warning. */ #define MOZZI_CONTROL_RATE FOR_DOXYGEN_ONLY diff --git a/examples/01.Basics/Sinewave/Sinewave.ino b/examples/01.Basics/Sinewave/Sinewave.ino index 9314fa6c7..5817edfc7 100644 --- a/examples/01.Basics/Sinewave/Sinewave.ino +++ b/examples/01.Basics/Sinewave/Sinewave.ino @@ -16,19 +16,16 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable; 64 Hz is actually the default, but shown here, for clarity #include #include // oscillator template #include // sine table for oscillator // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); - -// use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - +Oscil aSin(SIN2048_DATA); void setup(){ - startMozzi(CONTROL_RATE); // :) + startMozzi(); // :) aSin.setFreq(440); // set the frequency } diff --git a/examples/01.Basics/Skeleton/Skeleton.ino b/examples/01.Basics/Skeleton/Skeleton.ino index cbc5a3d6e..4eaed0282 100644 --- a/examples/01.Basics/Skeleton/Skeleton.ino +++ b/examples/01.Basics/Skeleton/Skeleton.ino @@ -1,8 +1,9 @@ -#include // at the top of your sketch -#define CONTROL_RATE 64 +#include // only needed, if you want to change some defaults +#define MOZZI_CONTROL_RATE 64 // any options then go above the Mozzi.h include +#include // needed once in each sketch void setup() { - startMozzi(CONTROL_RATE); + startMozzi(); } void updateControl() { diff --git a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino index 3763d22b7..bc32f74f5 100644 --- a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino @@ -7,7 +7,7 @@ #include // at the top of your sketch void setup() { - startMozzi(64); + startMozzi(); } void updateControl() { diff --git a/examples/01.Basics/Table_Resolution/Table_Resolution.ino b/examples/01.Basics/Table_Resolution/Table_Resolution.ino index c9f286b33..8f8c3ec8c 100644 --- a/examples/01.Basics/Table_Resolution/Table_Resolution.ino +++ b/examples/01.Basics/Table_Resolution/Table_Resolution.ino @@ -14,6 +14,7 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 #include #include #include @@ -25,8 +26,6 @@ #include // for scheduling events #include -#define CONTROL_RATE 64 - // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aSin0(SIN256_DATA); // can hear significant aliasing noise Oscil aSin1(SIN512_DATA); // noise still there but less noticeable @@ -43,11 +42,11 @@ byte whose_turn = 0; // which oscil to listen to // Line to sweep frequency at control rate Line kSweep; const unsigned int MILLIS_PER_SWEEP = 2000; -const unsigned int MILLIS_PER_CONTROL = 1000u / CONTROL_RATE; +const unsigned int MILLIS_PER_CONTROL = 1000u / MOZZI_CONTROL_RATE; const unsigned long CONTROL_STEPS_PER_SWEEP = (unsigned long) MILLIS_PER_SWEEP / MILLIS_PER_CONTROL; void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); kWhoseTurnDelay.set(MILLIS_PER_SWEEP); kSweep.set(0.f, 8192.f, CONTROL_STEPS_PER_SWEEP); } diff --git a/examples/01.Basics/Vibrato/Vibrato.ino b/examples/01.Basics/Vibrato/Vibrato.ino index a232275f8..bc7262e63 100644 --- a/examples/01.Basics/Vibrato/Vibrato.ino +++ b/examples/01.Basics/Vibrato/Vibrato.ino @@ -16,21 +16,20 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include #include // table for Oscils to play #include // for mtof #include -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - Oscil aCos(COS2048_DATA); Oscil aVibrato(COS2048_DATA); const byte intensity = 255; void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); aCos.setFreq(mtof(84.f)); aVibrato.setFreq(15.f); } diff --git a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino index a0069f23d..fb7ff6c53 100644 --- a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino +++ b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino @@ -25,6 +25,7 @@ Tim Barrass 2013, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 #include #include // oscillator template #include // sine table for oscillator @@ -32,7 +33,6 @@ #include #define INPUT_PIN 0 // analog control input -#define CONTROL_RATE 64 unsigned int echo_cells_1 = 32; unsigned int echo_cells_2 = 60; @@ -41,10 +41,10 @@ unsigned int echo_cells_3 = 127; ControlDelay <128, int> kDelay; // 2seconds // oscils to compare bumpy to averaged control input -Oscil aSin0(SIN2048_DATA); -Oscil aSin1(SIN2048_DATA); -Oscil aSin2(SIN2048_DATA); -Oscil aSin3(SIN2048_DATA); +Oscil aSin0(SIN2048_DATA); +Oscil aSin1(SIN2048_DATA); +Oscil aSin2(SIN2048_DATA); +Oscil aSin3(SIN2048_DATA); // use: RollingAverage myThing RollingAverage kAverage; // how_many_to_average has to be power of 2 diff --git a/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino b/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino index 01482a2e2..b3411ec98 100644 --- a/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino +++ b/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino @@ -21,32 +21,31 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 128 #include #include #include #include -#define CONTROL_RATE 128 - // harmonics -Oscil aCos1(COS8192_DATA); -Oscil aCos2(COS8192_DATA); -Oscil aCos3(COS8192_DATA); -Oscil aCos4(COS8192_DATA); -Oscil aCos5(COS8192_DATA); -Oscil aCos6(COS8192_DATA); -Oscil aCos7(COS8192_DATA); -Oscil aCos8(COS8192_DATA); +Oscil aCos1(COS8192_DATA); +Oscil aCos2(COS8192_DATA); +Oscil aCos3(COS8192_DATA); +Oscil aCos4(COS8192_DATA); +Oscil aCos5(COS8192_DATA); +Oscil aCos6(COS8192_DATA); +Oscil aCos7(COS8192_DATA); +Oscil aCos8(COS8192_DATA); // volume controls -Oscil kVol1(COS8192_DATA); -Oscil kVol2(COS8192_DATA); -Oscil kVol3(COS8192_DATA); -Oscil kVol4(COS8192_DATA); -Oscil kVol5(COS8192_DATA); -Oscil kVol6(COS8192_DATA); -Oscil kVol7(COS8192_DATA); -Oscil kVol8(COS8192_DATA); +Oscil kVol1(COS8192_DATA); +Oscil kVol2(COS8192_DATA); +Oscil kVol3(COS8192_DATA); +Oscil kVol4(COS8192_DATA); +Oscil kVol5(COS8192_DATA); +Oscil kVol6(COS8192_DATA); +Oscil kVol7(COS8192_DATA); +Oscil kVol8(COS8192_DATA); // audio volumes updated each control interrupt and reused in audio till next control char v1,v2,v3,v4,v5,v6,v7,v8; @@ -75,7 +74,7 @@ void setup(){ v1=v2=v3=v4=v5=v6=v7=v8=127; - startMozzi(CONTROL_RATE); + startMozzi(); } void loop(){ diff --git a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino index 40ea37af5..44c642156 100644 --- a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino +++ b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino @@ -21,6 +21,7 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include #include @@ -28,12 +29,10 @@ #include #include -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - // audio oscillator Oscil aSig(TRIANGLE_VALVE_2048_DATA); // control oscillator for tremelo -Oscil kTremelo(SIN2048_DATA); +Oscil kTremelo(SIN2048_DATA); // a line to interpolate control tremolo at audio rate Line aGain; @@ -41,14 +40,14 @@ Line aGain; void setup(){ aSig.setFreq(mtof(65.f)); kTremelo.setFreq(5.5f); - startMozzi(CONTROL_RATE); + startMozzi(); } void updateControl(){ // gain shifted up to give enough range for line's internal steps unsigned int gain = (128u+kTremelo.next())<<8; - aGain.set(gain, AUDIO_RATE / CONTROL_RATE); // divide of literals should get optimised away + aGain.set(gain, AUDIO_RATE / MOZZI_CONTROL_RATE); // divide of literals should get optimised away } diff --git a/examples/02.Control/EventDelay/EventDelay.ino b/examples/02.Control/EventDelay/EventDelay.ino index a81661ac3..c2040fc2b 100644 --- a/examples/02.Control/EventDelay/EventDelay.ino +++ b/examples/02.Control/EventDelay/EventDelay.ino @@ -20,13 +20,12 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 #include #include // oscillator template #include // sine table for oscillator #include -#define CONTROL_RATE 64 - // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aSin(SIN8192_DATA); @@ -36,9 +35,9 @@ EventDelay kGainChangeDelay; char gain = 1; void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); aSin.setFreq(330); // set the frequency - kGainChangeDelay.set(1000); // 1 second countdown, within resolution of CONTROL_RATE + kGainChangeDelay.set(1000); // 1 second countdown, within resolution of MOZZI_CONTROL_RATE } diff --git a/examples/02.Control/Line_Gliss/Line_Gliss.ino b/examples/02.Control/Line_Gliss/Line_Gliss.ino index 7c68ea7fb..5f43ce3a7 100644 --- a/examples/02.Control/Line_Gliss/Line_Gliss.ino +++ b/examples/02.Control/Line_Gliss/Line_Gliss.ino @@ -25,14 +25,13 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include // for smooth transitions #include // oscillator template #include // saw table for oscillator #include -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aSaw(SAW8192_DATA); @@ -43,7 +42,7 @@ byte lo_note = 24; // midi note numbers byte hi_note = 36; long audio_steps_per_gliss = AUDIO_RATE / 4; // ie. 4 glisses per second -long control_steps_per_gliss = CONTROL_RATE / 4; +long control_steps_per_gliss = MOZZI_CONTROL_RATE / 4; // stuff for changing starting positions, probably just confusing really int counter = 0; @@ -53,7 +52,7 @@ byte gliss_offset_max = 36; void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino index 1120af986..c47763218 100644 --- a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino +++ b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino @@ -74,7 +74,7 @@ byte lo_note = 24; // midi note numbers byte hi_note = 46; long audio_steps_per_gliss = AUDIO_RATE / 4; // ie. 4 glisses per second -long control_steps_per_gliss = CONTROL_RATE / 4; +long control_steps_per_gliss = MOZZI_CONTROL_RATE / 4; // stuff for changing starting positions, probably just confusing really int counter = 0; diff --git a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino index 2686d8b13..fc9f2855a 100644 --- a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino @@ -64,7 +64,7 @@ const int LDR2_PIN=2; // set the analog input for mod rate to pin 2 Oscil aCarrier(COS2048_DATA); Oscil aModulator(COS2048_DATA); -Oscil kIntensityMod(COS2048_DATA); +Oscil kIntensityMod(COS2048_DATA); int mod_ratio = 5; // brightness (harmonics) long fm_intensity; // carries control info from updateControl to updateAudio diff --git a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino index 5f28a48a1..ee16a6d33 100644 --- a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino +++ b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino @@ -29,13 +29,12 @@ Tim Barrass 2013, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 256 #include #include #include #include -#define CONTROL_RATE 256 - #define THERMISTOR_PIN 1 #define LDR_PIN 2 #define NUM_VOICES 8 @@ -52,14 +51,14 @@ Oscil aCos7(COS8192_DATA); Oscil aCos0(COS8192_DATA); // volume controls -Oscil kVol1(COS8192_DATA); -Oscil kVol2(COS8192_DATA); -Oscil kVol3(COS8192_DATA); -Oscil kVol4(COS8192_DATA); -Oscil kVol5(COS8192_DATA); -Oscil kVol6(COS8192_DATA); -Oscil kVol7(COS8192_DATA); -Oscil kVol0(COS8192_DATA); +Oscil kVol1(COS8192_DATA); +Oscil kVol2(COS8192_DATA); +Oscil kVol3(COS8192_DATA); +Oscil kVol4(COS8192_DATA); +Oscil kVol5(COS8192_DATA); +Oscil kVol6(COS8192_DATA); +Oscil kVol7(COS8192_DATA); +Oscil kVol0(COS8192_DATA); // audio volumes updated each control interrupt and reused in audio till next control char v1,v2,v3,v4,v5,v6,v7,v0; @@ -73,7 +72,7 @@ float downnotes[NUM_VOICES] = { void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino index 47cdacbf5..b9c516c3e 100644 --- a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino +++ b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino @@ -26,14 +26,13 @@ Tim Barrass 2013, CC by-nc-sa. */ +// increase the rate of updateControl from the default of 64, to catch the piezo's rapid transients +#define MOZZI_CONTROL_RATE 150 #include #include // oscillator #include // table for Oscils to play #include -// increase the rate of updateControl from the default of 50, to catch the piezo's rapid transients -#define CONTROL_RATE 150 - const int PIEZO_PIN = 3; // set the analog input pin for the piezo // use: Oscil oscilName (wavetable), look in .h file of table #included above @@ -43,7 +42,7 @@ Oscil aSin(SIN2048_DATA); void setup(){ //Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches Serial.begin(115200); // set up the Serial output so we can look at the piezo values // set up the Serial output so we can look at the piezo values - startMozzi(CONTROL_RATE); // :)) use the control rate defined above + startMozzi(); // :)) use the control rate defined above } diff --git a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino index fcbdf69ed..090b0d55a 100644 --- a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino +++ b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino @@ -47,7 +47,7 @@ Sample aSample(BLAHBLAH4B_DATA Line scrub; // Q16n16 fixed point for high precision // the number of audio steps the line has to take to reach the next offset -const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / CONTROL_RATE; +const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / MOZZI_CONTROL_RATE; void setup(){ diff --git a/examples/03.Sensors/RCpoll/RCpoll.ino b/examples/03.Sensors/RCpoll/RCpoll.ino index 0cc0e54cd..fb1e32627 100644 --- a/examples/03.Sensors/RCpoll/RCpoll.ino +++ b/examples/03.Sensors/RCpoll/RCpoll.ino @@ -38,12 +38,12 @@ sPin ---\/\/\/-----. */ +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include #include // sine table for oscillator #include -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable #define SENSOR_PIN 4 // digital pin for sensor input Oscil aSin(SIN2048_DATA); @@ -53,7 +53,7 @@ RCpoll sensor; void setup(){ //Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches Serial.begin(115200); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino index aa6e14e92..5cebccd4a 100644 --- a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino +++ b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino @@ -25,6 +25,7 @@ Tim Barrass 2013, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include #include // sine table for oscillator @@ -33,8 +34,6 @@ #include #include -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - // 2 oscillators to compare linear interpolated vs smoothed control Oscil aSin0(SIN2048_DATA); Oscil aSin1(SIN2048_DATA); @@ -50,7 +49,7 @@ Oscil aSin1(SIN2048_DATA); Line aInterpolate; // the number of audio steps the line has to take to reach the next control value -const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / CONTROL_RATE; +const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / MOZZI_CONTROL_RATE; // Smoothing unit for aSin1 // This might be better with Q24n8 numbers for more precision, @@ -63,7 +62,7 @@ Smooth aSmooth(smoothness); // to smooth frequency for aSin1 void setup(){ aSin0.setFreq(660.f); aSin1.setFreq(220.f); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino index 1cecc9fc5..dcba91293 100644 --- a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino +++ b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino @@ -22,6 +22,8 @@ */ #include +// use #define for MOZZI_CONTROL_RATE, not a constant +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include // oscillator template #include // for envelope @@ -33,16 +35,13 @@ MIDI_CREATE_DEFAULT_INSTANCE(); -// use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - // audio sinewave oscillator Oscil aSin(SIN2048_DATA); // envelope generator -ADSR envelope; +ADSR envelope; -Portamento aPortamento; +Portamento aPortamento; #define LED 13 @@ -77,7 +76,7 @@ void setup() { aPortamento.setTime(300u); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/05.Control_Filters/Smooth/Smooth.ino b/examples/05.Control_Filters/Smooth/Smooth.ino index 9a8083754..8de5a4132 100644 --- a/examples/05.Control_Filters/Smooth/Smooth.ino +++ b/examples/05.Control_Filters/Smooth/Smooth.ino @@ -18,6 +18,7 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 128 #include #include // oscillator template #include // sine table for oscillator @@ -25,8 +26,6 @@ #include #include -#define CONTROL_RATE 128 - Oscil aSin(SIN2048_DATA); // for scheduling audio gain changes @@ -47,7 +46,7 @@ void setup(){ aSin.setFreq(330); // set the frequency kGainChangeDelay.set(gainChangeMsec); kSmoothOnOff.set(smoothOnOffMsec); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino index 9c964caec..4c821e46f 100644 --- a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino +++ b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino @@ -16,6 +16,8 @@ Tim Barrass 2012, CC by-nc-sa. */ +// this is a high value to avoid zipper noise +#define MOZZI_CONTROL_RATE 1280 #include #include // oscillator template #include // sine table for oscillator @@ -23,9 +25,6 @@ #include #include -// this is a high value to avoid zipper noise -#define CONTROL_RATE 1280 - // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aSin(SIN2048_DATA); @@ -39,8 +38,8 @@ int target_freq, target_freq1, target_freq2; void setup(){ target_freq1 = 441; target_freq2 = 330; - kFreqChangeDelay.set(1000); // 1000ms countdown, within resolution of CONTROL_RATE - startMozzi(CONTROL_RATE); + kFreqChangeDelay.set(1000); // 1000ms countdown, within resolution of MOZZI_CONTROL_RATE + startMozzi(); } diff --git a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino index 0459fb0f9..acd25e878 100644 --- a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino +++ b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino @@ -49,7 +49,7 @@ const byte INPUT_PIN = 1; float ENVELOPE_DURATION = 1.f; -const byte LINE_LENGTH = (byte)((float)CONTROL_RATE*ENVELOPE_DURATION*0.5); // 0.5 seconds per line +const byte LINE_LENGTH = (byte)((float)MOZZI_CONTROL_RATE*ENVELOPE_DURATION*0.5); // 0.5 seconds per line // adjustments to get tremelo in useful range from oversampled temperature input const int TREMOLO_OFFSET = 4000; diff --git a/examples/06.Synthesis/AMsynth/AMsynth.ino b/examples/06.Synthesis/AMsynth/AMsynth.ino index 8cd90761b..17b40b934 100644 --- a/examples/06.Synthesis/AMsynth/AMsynth.ino +++ b/examples/06.Synthesis/AMsynth/AMsynth.ino @@ -20,6 +20,7 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include #include // table for Oscils to play @@ -28,8 +29,6 @@ #include #include -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - // audio oscils Oscil aCarrier(COS2048_DATA); Oscil aModulator(COS2048_DATA); @@ -48,10 +47,10 @@ Q8n0 octave_start_note = 42; void setup(){ ratio = float_to_Q8n8(3.0f); // define modulation ratio in float and convert to fixed-point - kNoteChangeDelay.set(200); // note duration ms, within resolution of CONTROL_RATE + kNoteChangeDelay.set(200); // note duration ms, within resolution of MOZZI_CONTROL_RATE aModDepth.setFreq(13.f); // vary mod depth to highlight am effects randSeed(); // reseed the random generator for different results each time the sketch runs - startMozzi(CONTROL_RATE); + startMozzi(); } void updateControl(){ diff --git a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino index 91ae70b9a..3a00207a6 100644 --- a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino +++ b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino @@ -68,10 +68,10 @@ Q8n0 octave_start_note = 42; void setup(){ ratio = float_to_Q8n8(3.0f); // define modulation ratio in float and convert to fixed-point - kNoteChangeDelay.set(200); // note duration ms, within resolution of CONTROL_RATE + kNoteChangeDelay.set(200); // note duration ms, within resolution of MOZZI_CONTROL_RATE aModDepth.setFreq(13.f); // vary mod depth to highlight am effects randSeed(); // reseed the random generator for different results each time the sketch runs - startMozzi(); // use default CONTROL_RATE 64 + startMozzi(); // use default MOZZI_CONTROL_RATE 64 } diff --git a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino index 46d2efbc4..cf6afcb4b 100644 --- a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino +++ b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino @@ -40,7 +40,7 @@ void setup(){ startMozzi(); // :) aSin1.setFreq_Q16n16(freq1); // set the frequency with a Q16n16 fractional number aGain.setFreq(0.2f); // use a float for low frequencies, in setup it doesn't need to be fast - kChangeNoteDelay.set(2000); // note duration ms, within resolution of CONTROL_RATE + kChangeNoteDelay.set(2000); // note duration ms, within resolution of MOZZI_CONTROL_RATE } diff --git a/examples/06.Synthesis/FMsynth/FMsynth.ino b/examples/06.Synthesis/FMsynth/FMsynth.ino index b21c40ebf..810c27c22 100644 --- a/examples/06.Synthesis/FMsynth/FMsynth.ino +++ b/examples/06.Synthesis/FMsynth/FMsynth.ino @@ -22,6 +22,7 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include #include // table for Oscils to play @@ -30,11 +31,9 @@ #include #include -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - Oscil aCarrier(COS2048_DATA); Oscil aModulator(COS2048_DATA); -Oscil kModIndex(COS2048_DATA); +Oscil kModIndex(COS2048_DATA); // The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm ) // It will vary according to the frequency that is modulating the carrier and the amount of deviation. @@ -60,7 +59,7 @@ Q7n8 target_note, note0, note1, note_upper_limit, note_lower_limit, note_change_ Smooth kSmoothNote(0.95f); void setup(){ - kNoteChangeDelay.set(768); // ms countdown, taylored to resolution of CONTROL_RATE + kNoteChangeDelay.set(768); // ms countdown, taylored to resolution of MOZZI_CONTROL_RATE kModIndex.setFreq(.768f); // sync with kNoteChangeDelay target_note = note0; note_change_step = Q7n0_to_Q7n8(3); @@ -68,7 +67,7 @@ void setup(){ note_lower_limit = Q7n0_to_Q7n8(32); note0 = note_lower_limit; note1 = note_lower_limit + Q7n0_to_Q7n8(5); - startMozzi(CONTROL_RATE); + startMozzi(); } void setFreqs(Q8n8 midi_note){ diff --git a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino index 95bc0e8d3..54ec56186 100644 --- a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino +++ b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino @@ -45,6 +45,7 @@ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM #define MOZZI_AUDIO_RATE 32768 +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include @@ -54,11 +55,9 @@ #include #include -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - Oscil aCarrier(COS2048_DATA); Oscil aModulator(COS2048_DATA); -Oscil kModIndex(COS2048_DATA); +Oscil kModIndex(COS2048_DATA); // The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm ) // It will vary according to the frequency that is modulating the carrier and the amount of deviation. @@ -84,7 +83,7 @@ Q7n8 target_note, note0, note1, note_upper_limit, note_lower_limit, note_change_ Smooth kSmoothNote(0.95f); void setup(){ - kNoteChangeDelay.set(768); // ms countdown, taylored to resolution of CONTROL_RATE + kNoteChangeDelay.set(768); // ms countdown, taylored to resolution of MOZZI_CONTROL_RATE kModIndex.setFreq(.768f); // sync with kNoteChangeDelay target_note = note0; note_change_step = Q7n0_to_Q7n8(3); @@ -92,7 +91,7 @@ void setup(){ note_lower_limit = Q7n0_to_Q7n8(32); note0 = note_lower_limit; note1 = note_lower_limit + Q7n0_to_Q7n8(5); - startMozzi(CONTROL_RATE); + startMozzi(); } void setFreqs(Q8n8 midi_note){ diff --git a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino index 6e4ff3fa2..32920f133 100644 --- a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino +++ b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino @@ -35,6 +35,8 @@ Tim Barrass 2012, Combriat T. 2021, CC by-nc-sa. */ +// use #define for MOZZI_CONTROL_RATE, not a constant +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include // oscillator template #include @@ -81,10 +83,6 @@ Oscil aSq8192(SQUARE_MAX_81 // use: MetaOscil MetaoscilName. All oscils used should have the same table_size and **have to be put in increasing order of cutoff_frequencies**. MetaOscil BL_aSq {&aSq90, &aSq101, &aSq122, &aSq138, &aSq154, &aSq174, &aSq210, &aSq264, &aSq327, &aSq431, &aSq546, &aSq744, &aSq1170, &aSq1638, &aSq2730, &aSq8192}; - -// use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - int freq = 10; @@ -95,7 +93,7 @@ void setup() { // Cutoff frequencies can also be set or changed individually. BL_aSq.setCutoffFreq(3000, 14); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/06.Synthesis/PDresonant/PDresonant.ino b/examples/06.Synthesis/PDresonant/PDresonant.ino index 856dd7262..a00702add 100644 --- a/examples/06.Synthesis/PDresonant/PDresonant.ino +++ b/examples/06.Synthesis/PDresonant/PDresonant.ino @@ -69,7 +69,7 @@ void setup(){ //MIDI.setHandleNoteOff(HandleNoteOff); // open MOZZI (: - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/06.Synthesis/WaveFolder/WaveFolder.ino b/examples/06.Synthesis/WaveFolder/WaveFolder.ino index 54bff7aa2..a2e062815 100644 --- a/examples/06.Synthesis/WaveFolder/WaveFolder.ino +++ b/examples/06.Synthesis/WaveFolder/WaveFolder.ino @@ -24,8 +24,8 @@ #include Oscil aSin(SIN2048_DATA); // audio oscillator -Oscil kBias(SIN2048_DATA); // LFO changing the bias -Oscil kGain(SAW512_DATA); // Gain oscillator +Oscil kBias(SIN2048_DATA); // LFO changing the bias +Oscil kGain(SAW512_DATA); // Gain oscillator // Create a WaveFolder on the native audio type (int). @@ -40,8 +40,8 @@ void setup() { kBias.setFreq(0.3f); // set the frequency kGain.setFreq(0.2f); wf.setLimits(-2047, 2047); // sets the values the wavefolder will start folding (in this case, containing in 12 bits) - // can also be done at CONTROL_RATE (even maybe at AUDIO_RATE) - startMozzi(CONTROL_RATE); + // can also be done at MOZZI_CONTROL_RATE (even maybe at AUDIO_RATE) + startMozzi(); } void updateControl() { diff --git a/examples/06.Synthesis/Waveshaper/Waveshaper.ino b/examples/06.Synthesis/Waveshaper/Waveshaper.ino index 8a1d62e39..5369ffd56 100644 --- a/examples/06.Synthesis/Waveshaper/Waveshaper.ino +++ b/examples/06.Synthesis/Waveshaper/Waveshaper.ino @@ -57,7 +57,7 @@ void setup(){ aSin.setFreq(110); // set the frequency aGain1.setFreq(2.f); // use a float for low frequencies, in setup it doesn't need to be fast aGain2.setFreq(.4f); - kChangeNoteDelay.set(4000); // note duration ms, within resolution of CONTROL_RATE + kChangeNoteDelay.set(4000); // note duration ms, within resolution of MOZZI_CONTROL_RATE } byte rndPentatonic(){ diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino index 3755951e7..1a14ca2ca 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino @@ -3,7 +3,7 @@ how to use an ADSR which updates at AUDIO_RATE, in updateAudio(), and output using next() at AUDIO_RATE in updateAudio(). - Another example in this folder shows an ADSR updating at CONTROL_RATE, + Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, which is more efficient, but AUDIO_RATE updates shown in this example enable faster envelope transitions. diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino index 515a94ce7..da691c8c0 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino @@ -6,7 +6,7 @@ unsigned long as the third ADSR parameter to allow long envelopes to be updated at AUDIO_RATE. - Another example in this folder shows an ADSR updating at CONTROL_RATE, + Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, which is more efficient, but AUDIO_RATE updates shown in this example enable faster envelope transitions. diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino index 299c1c7df..92612f018 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino @@ -4,7 +4,7 @@ This shows how to use an ADSR which updates at AUDIO_RATE, in updateAudio(), and output using next() at AUDIO_RATE in updateAudio(). - Another example in this folder shows an ADSR updating at CONTROL_RATE, + Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, which is more efficient, but AUDIO_RATE updates shown in this example enable faster envelope transitions. @@ -32,8 +32,8 @@ Oscil <8192, AUDIO_RATE> aOscil1(SIN8192_DATA); EventDelay noteDelay; // ADSR update_rate, interpolation_rte -ADSR envelope0; -ADSR envelope1; +ADSR envelope0; +ADSR envelope1; boolean note_is_on = true; diff --git a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino index 64679efb3..2175140f4 100644 --- a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino @@ -1,6 +1,6 @@ /* Example applying an ADSR envelope to an audio signal with Mozzi sonification library. This shows - internal updates as well as interpolation at CONTROL_RATE, using both + internal updates as well as interpolation at MOZZI_CONTROL_RATE, using both update() and next() in updateControl(). This is less computationally intensive than doing interpolation with next() in updateAudio(), but can be less smooth, especially with fast envelopes. @@ -11,6 +11,7 @@ Tim Barrass 2013-14, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 128 // faster than usual to help smooth MOZZI_CONTROL_RATE adsr interpolation (next()) #include #include #include @@ -19,14 +20,12 @@ #include #include -#define CONTROL_RATE 128 // faster than usual to help smooth CONTROL_RATE adsr interpolation (next()) - Oscil <8192, AUDIO_RATE> aOscil(SIN8192_DATA);; // for triggering the envelope EventDelay noteDelay; -ADSR envelope; +ADSR envelope; boolean note_is_on = true; byte gain; @@ -36,7 +35,7 @@ void setup(){ Serial.begin(115200); randSeed(); // fresh random noteDelay.set(2000); // 2 second countdown - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino index a75c2bf75..a55b8fa69 100644 --- a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino +++ b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino @@ -13,6 +13,7 @@ Tim Barrass 2012, CC by-nc-sa */ +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include // oscillator template #include // recorded audio wavetable @@ -20,11 +21,9 @@ #include #include -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - Oscil aNoise(BROWNNOISE8192_DATA); EventDelay kDelay; // for triggering envelope start -Ead kEnvelope(CONTROL_RATE); // resolution will be CONTROL_RATE +Ead kEnvelope(MOZZI_CONTROL_RATE); // resolution will be MOZZI_CONTROL_RATE int gain; @@ -33,7 +32,7 @@ void setup(){ // use float to set freq because it will be small and fractional aNoise.setFreq((float)AUDIO_RATE/BROWNNOISE8192_SAMPLERATE); randSeed(); // fresh random, MUST be called before startMozzi - wierd bug - startMozzi(CONTROL_RATE); + startMozzi(); kDelay.start(1000); } diff --git a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino index 975e75980..a3b8ca3e8 100644 --- a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino +++ b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino @@ -14,24 +14,23 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth #include #include #include #include -#define CONTROL_RATE 640 // quite fast, keeps modulation smooth - // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aCarrier(COS8192_DATA); Oscil aModulator(COS8192_DATA); Oscil aModWidth(COS8192_DATA); -Oscil kModFreq1(COS8192_DATA); -Oscil kModFreq2(COS8192_DATA); +Oscil kModFreq1(COS8192_DATA); +Oscil kModFreq2(COS8192_DATA); Oscil aEnvelop(ENVELOP2048_DATA); void setup() { - startMozzi(CONTROL_RATE); + startMozzi(); aCarrier.setFreq(220); kModFreq1.setFreq(1.78f); kModFreq2.setFreq(0.1757f); diff --git a/examples/08.Samples/Sample/Sample.ino b/examples/08.Samples/Sample/Sample.ino index b5723eaea..088174bf7 100644 --- a/examples/08.Samples/Sample/Sample.ino +++ b/examples/08.Samples/Sample/Sample.ino @@ -31,7 +31,7 @@ EventDelay kTriggerDelay; void setup(){ startMozzi(); aSample.setFreq((float) BURROUGHS1_18649_SAMPLERATE / (float) BURROUGHS1_18649_NUM_CELLS); // play at the speed it was recorded - kTriggerDelay.set(1500); // 1500 msec countdown, within resolution of CONTROL_RATE + kTriggerDelay.set(1500); // 1500 msec countdown, within resolution of MOZZI_CONTROL_RATE } diff --git a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino index 599b6b555..ee1a96307 100644 --- a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino +++ b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino @@ -20,14 +20,13 @@ Tim Barrass 2012, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 128 #include #include // Sample template #include // table for Sample #include #include -#define CONTROL_RATE 128 - // use: Sample SampleName (wavetable) Sample aSample(ABOMB_DATA); @@ -39,14 +38,14 @@ const float playspeed = 1.3; float playspeedmod = 0; float speedchange = 0; -const unsigned int full = (int) (1000.f/playspeed) - 23; // adjustment approx for CONTROL_RATE difference +const unsigned int full = (int) (1000.f/playspeed) - 23; // adjustment approx for MOZZI_CONTROL_RATE difference void setup(){ randSeed(); // reseed the random generator for different results each time the sketch runs aSample.setFreq(playspeed*((float) ABOMB_SAMPLERATE / (float) ABOMB_NUM_CELLS)); kTriggerDelay.set(full); aSample.setLoopingOn(); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino index caf07de1c..edfbc4c30 100644 --- a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino +++ b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino @@ -29,7 +29,7 @@ Sample aSample(BURROUGHS Line scrub; // Q16n16 fixed point for high precision // the number of audio steps the line has to take to reach the next offset -const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / CONTROL_RATE; +const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / MOZZI_CONTROL_RATE; int offset = 0; int offset_advance = 400; // just a guess @@ -50,8 +50,8 @@ void updateControl(){ // wandering advance rate offset_advance += (int)rand(20)-rand(20); - if(!rand(CONTROL_RATE)) offset_advance = -offset_advance; // reverse sometimes - if(!rand(CONTROL_RATE)) offset_advance = 500-rand(1000); // jump speed sometimes + if(!rand(MOZZI_CONTROL_RATE)) offset_advance = -offset_advance; // reverse sometimes + if(!rand(MOZZI_CONTROL_RATE)) offset_advance = 500-rand(1000); // jump speed sometimes int smooth_offset_advance = kSmoothOffsetAdvance.next(offset_advance); diff --git a/examples/08.Samples/Samples/Samples.ino b/examples/08.Samples/Samples/Samples.ino index 4a2cb4a76..c8eab3322 100644 --- a/examples/08.Samples/Samples/Samples.ino +++ b/examples/08.Samples/Samples/Samples.ino @@ -39,7 +39,7 @@ void setup(){ aBamboo0.setFreq((float) BAMBOO_00_2048_SAMPLERATE / (float) BAMBOO_00_2048_NUM_CELLS); // play at the speed it was recorded at aBamboo1.setFreq((float) BAMBOO_01_2048_SAMPLERATE / (float) BAMBOO_01_2048_NUM_CELLS); aBamboo2.setFreq((float) BAMBOO_02_2048_SAMPLERATE / (float) BAMBOO_02_2048_NUM_CELLS); - kTriggerDelay.set(111); // countdown ms, within resolution of CONTROL_RATE + kTriggerDelay.set(111); // countdown ms, within resolution of MOZZI_CONTROL_RATE } diff --git a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino index 4a0d84983..a3f855092 100644 --- a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino +++ b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino @@ -42,7 +42,7 @@ EventDelay kTriggerDelay; EventDelay kTriggerSlowDelay; -byte ms_per_note = 111; // subject to CONTROL_RATE +byte ms_per_note = 111; // subject to MOZZI_CONTROL_RATE const byte NUM_PLAYERS = 3; // 3 seems to be enough const byte NUM_TABLES = 11; @@ -76,7 +76,7 @@ void setup(){ for (int i=0;i #include #include // wavetable @@ -23,10 +24,8 @@ #include #include // for mtof -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); -Oscil kFreq(COS2048_DATA); +Oscil kFreq(COS2048_DATA); AudioDelay <256> aDel; int del_samps; @@ -34,7 +33,7 @@ int del_samps; void setup(){ aTriangle.setFreq(mtof(60.f)); kFreq.setFreq(.63f); - startMozzi(CONTROL_RATE); + startMozzi(); } void loop(){ diff --git a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino index fe91c592d..766c9d33d 100644 --- a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino +++ b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino @@ -16,6 +16,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include #include // wavetable @@ -23,10 +24,8 @@ #include #include // for mtof -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator -Oscil kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples +Oscil kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples AudioDelayFeedback <128> aDel; @@ -34,7 +33,7 @@ AudioDelayFeedback <128> aDel; byte del_samps; void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); aTriangle.setFreq(mtof(48.f)); kDelSamps.setFreq(.163f); // set the delay time modulation frequency (ie. the sweep frequency) aDel.setFeedbackLevel(-111); // can be -128 to 127 diff --git a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino index 9178af5c3..20575168b 100644 --- a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino +++ b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino @@ -18,6 +18,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include #include @@ -26,11 +27,9 @@ #include #include -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - Oscil aNoise(WHITENOISE8192_DATA); // audio noise EventDelay kDelay; // for triggering envelope start -Ead kEnvelope(CONTROL_RATE); // resolution will be CONTROL_RATE +Ead kEnvelope(MOZZI_CONTROL_RATE); // resolution will be MOZZI_CONTROL_RATE AudioDelayFeedback <256, ALLPASS> aDel; @@ -39,7 +38,7 @@ int gain; void setup(){ //Serial.begin(9600); - startMozzi(CONTROL_RATE); + startMozzi(); randSeed(); // reseed the random generator for different results each time the sketch runs // use float to set freq because it will be small and fractional aNoise.setFreq((float)AUDIO_RATE/WHITENOISE8192_SAMPLERATE); diff --git a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino index 09b68ffae..73d1bc8f8 100644 --- a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino +++ b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino @@ -17,6 +17,7 @@ Tim Barrass 2012-13, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include #include // wavetable for audio @@ -24,13 +25,11 @@ #include #include // for mtof -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - Oscil aTriangle1(TRIANGLE_ANALOGUE512_DATA); // audio oscillator Oscil aTriangle2(TRIANGLE_ANALOGUE512_DATA); // audio oscillator -Oscil kDelSamps1(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples -Oscil kDelSamps2(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples +Oscil kDelSamps1(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples +Oscil kDelSamps2(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples AudioDelayFeedback <128> aDel1; AudioDelayFeedback <128> aDel2; @@ -49,7 +48,7 @@ void setup(){ kDelSamps2.setFreq(1.43f); // set the delay time modulation frequency (ie. the sweep frequency) aDel2.setFeedbackLevel(109); // can be -128 to 127 - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino index d5f4c59b2..84ab8dd2e 100644 --- a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino +++ b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino @@ -42,6 +42,7 @@ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM #define MOZZI_AUDIO_RATE 32768 +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include @@ -50,10 +51,8 @@ #include #include // for mtof -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator -Oscil kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples +Oscil kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples AudioDelayFeedback <128> aDel; @@ -62,7 +61,7 @@ byte del_samps; Q16n16 del_samps_fractional; void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); aTriangle.setFreq(mtof(48.f)); kDelSamps.setFreq(.163f); // set the delay time modulation frequency (ie. the sweep frequency) aDel.setFeedbackLevel(-111); // can be -128 to 127 diff --git a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino index c9fa316b1..cbaf1f8fe 100644 --- a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino +++ b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino @@ -22,6 +22,7 @@ Tim Barrass 2013, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth #include #include #include @@ -30,14 +31,12 @@ ReverbTank reverb; -#define CONTROL_RATE 640 // quite fast, keeps modulation smooth - // Synth from PhaseMod_Envelope example Oscil aCarrier(COS8192_DATA); Oscil aModulator(COS8192_DATA); Oscil aModWidth(COS8192_DATA); -Oscil kModFreq1(COS8192_DATA); -Oscil kModFreq2(COS8192_DATA); +Oscil kModFreq1(COS8192_DATA); +Oscil kModFreq2(COS8192_DATA); Oscil aEnvelop(ENVELOP2048_DATA); @@ -49,7 +48,7 @@ void setup(){ aModWidth.setFreq(2.52434f); aEnvelop.setFreq(9.0f); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino index e7eaf651e..24184f2f5 100644 --- a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino +++ b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino @@ -22,6 +22,7 @@ Tim Barrass 2013, CC by-nc-sa. */ +#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth #include #include #include @@ -30,14 +31,12 @@ ReverbTank reverb; -#define CONTROL_RATE 640 // quite fast, keeps modulation smooth - // Synth from PhaseMod_Envelope example Oscil aCarrier(COS8192_DATA); Oscil aModulator(COS8192_DATA); Oscil aModWidth(COS8192_DATA); -Oscil kModFreq1(COS8192_DATA); -Oscil kModFreq2(COS8192_DATA); +Oscil kModFreq1(COS8192_DATA); +Oscil kModFreq2(COS8192_DATA); Oscil aEnvelop(ENVELOP2048_DATA); @@ -49,7 +48,7 @@ void setup(){ aModWidth.setFreq(2.52434f); aEnvelop.setFreq(9.0f); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino index a16d122a2..9e89546e4 100644 --- a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino +++ b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino @@ -25,8 +25,8 @@ Oscil aCrunchySound1(CHUM9_DATA); //audio oscillator Oscil aCrunchySound2(CHUM9_DATA); //audio oscillator -Oscil kFilterMod1(COS512_DATA); // to modulate filter frequency -Oscil kFilterMod2(COS512_DATA); // to modulate filter frequency +Oscil kFilterMod1(COS512_DATA); // to modulate filter frequency +Oscil kFilterMod2(COS512_DATA); // to modulate filter frequency LowPassFilter lpf1; // can be changed to HighPassFilter, BandPassFilter or NotchFilter LowPassFilter lpf2; diff --git a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino index a01e1afd1..d2303b9d1 100644 --- a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino +++ b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino @@ -31,8 +31,8 @@ #include Oscil aCrunchySound(CHUM9_DATA); -Oscil kFilterMod(COS2048_DATA); -Oscil kFilterMod2(COS2048_DATA); +Oscil kFilterMod(COS2048_DATA); +Oscil kFilterMod2(COS2048_DATA); MultiResonantFilter mf; // Multifilter applied to a 8 bits signal. // MultiResonantFilter can also be used for signals with higher number of bits @@ -56,7 +56,7 @@ void loop() { } void updateControl() { - if (rand(CONTROL_RATE / 2) == 0) { // about once every half second + if (rand(MOZZI_CONTROL_RATE / 2) == 0) { // about once every half second kFilterMod.setFreq((float)rand(255) / 64); // choose a new modulation frequency filter_type = rand(4); // change the filter type, randomly } @@ -84,4 +84,4 @@ AudioOutput_t updateAudio() { break; } return MonoOutput::fromNBit(9, asig); // signal is theoretically 8 bits, but resonance push it further so we let one bit of margin -} \ No newline at end of file +} diff --git a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino index 5e4c63054..dcc791272 100644 --- a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino +++ b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino @@ -28,7 +28,7 @@ #include Oscil aCrunchySound(CHUM9_DATA); -Oscil kFilterMod(COS2048_DATA); +Oscil kFilterMod(COS2048_DATA); //Different types of filters available LowPassFilter rf; // Equivalent to ResonantFilter @@ -49,7 +49,7 @@ void loop(){ } void updateControl(){ - if (rand(CONTROL_RATE/2) == 0){ // about once every half second + if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency } // map the modulation into the filter range (0-255), corresponds with 0-AUDIO_RATE/(sqrt(2)*pi) Hz diff --git a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino index 50980fe4c..f3d67661e 100644 --- a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino +++ b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino @@ -30,8 +30,8 @@ #include Oscil aCrunchySound(CHUM9_DATA); -Oscil kFilterMod(COS2048_DATA); -Oscil kFilterMod2(COS2048_DATA); +Oscil kFilterMod(COS2048_DATA); +Oscil kFilterMod2(COS2048_DATA); //Different types of filters available LowPassFilter16 rf; // Equivalent to ResonantFilter @@ -55,7 +55,7 @@ void loop(){ } void updateControl(){ - if (rand(CONTROL_RATE/2) == 0){ // about once every half second + if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency } // map the modulation into the filter range (0-255), corresponds with 0-AUDIO_RATE/(sqrt(2)*pi) Hz @@ -66,4 +66,4 @@ void updateControl(){ AudioOutput_t updateAudio(){ AudioOutput_t asig = rf.next(aCrunchySound.next()); return MonoOutput::from8Bit(asig); -} \ No newline at end of file +} diff --git a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino index 3edd09133..cb5fd5946 100644 --- a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino +++ b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino @@ -24,7 +24,7 @@ #include // for rand() Oscil aNoise(WHITENOISE8192_DATA); // audio noise -Oscil kFilterMod(COS2048_DATA); +Oscil kFilterMod(COS2048_DATA); StateVariable svf; // can be LOWPASS, BANDPASS, HIGHPASS or NOTCH @@ -41,7 +41,7 @@ void setup(){ void updateControl(){ - if (rand(CONTROL_RATE/2) == 0){ // about once every half second + if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency } int cutoff_freq = 2200 + kFilterMod.next()*12; diff --git a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino index c563e00e5..c5d9331ca 100644 --- a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino +++ b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino @@ -20,6 +20,8 @@ */ #include +// use #define for MOZZI_CONTROL_RATE, not a constant +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include // oscillator template #include // sine table for oscillator @@ -29,14 +31,11 @@ MIDI_CREATE_DEFAULT_INSTANCE(); -// use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - // audio sinewave oscillator Oscil aSin(SIN2048_DATA); // envelope generator -ADSR envelope; +ADSR envelope; #define LED 13 // shows if MIDI is being recieved @@ -64,7 +63,7 @@ void setup() { envelope.setTimes(50,200,10000,200); // 10000 is so the note will sustain 10 seconds unless a noteOff comes aSin.setFreq(440); // default frequency - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino index 0a5cd25bc..a861d01ca 100644 --- a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino +++ b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino @@ -66,9 +66,9 @@ const byte BLUE_PIN = 5; byte red_brightness, green_brightness, blue_brightness; // control oscillators using sinewaves to modulate LED brightness -Oscil kRed(SIN2048_DATA); -Oscil kGreen(SIN2048_DATA); -Oscil kBlue(SIN2048_DATA); +Oscil kRed(SIN2048_DATA); +Oscil kGreen(SIN2048_DATA); +Oscil kBlue(SIN2048_DATA); // audio oscillator Oscil aSin(SIN2048_DATA); diff --git a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino index c5ce5cf5e..c921caaeb 100644 --- a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino +++ b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino @@ -22,6 +22,8 @@ */ #include +// use #define for MOZZI_CONTROL_RATE, not a constant +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include // oscillator template #include // sine table for oscillator @@ -29,14 +31,11 @@ #include -// use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - // audio sinewave oscillator Oscil aSin(SIN2048_DATA); // envelope generator -ADSR envelope; +ADSR envelope; #define LED 6 // 6 on Teensy++ 2.0, 11 on Teensy 2.0, to see if MIDI is being recieved @@ -63,7 +62,7 @@ void setup() { envelope.setTimes(50,200,10000,200); // 10000 is so the note will sustain 10 seconds unless a noteOff comes aSin.setFreq(440); // default frequency - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino index 1236c6c34..3dfad0aac 100644 --- a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino +++ b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino @@ -20,17 +20,16 @@ This example code is in the public domain. */ +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include #include // oscillator template #include // exponential attack decay #include // sine table for oscillator #include -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aSin(SIN2048_DATA); -Ead kEnvelope(CONTROL_RATE); // resolution will be CONTROL_RATE +Ead kEnvelope(MOZZI_CONTROL_RATE); // resolution will be MOZZI_CONTROL_RATE int gain; @@ -140,7 +139,7 @@ void acc_writeTo(byte address, byte val) { void setup(){ setup_accelero(); - startMozzi(CONTROL_RATE); + startMozzi(); aSin.setFreq(800); int attack = 30; int decay = 500; diff --git a/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino b/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino index f8de1c267..d94d66d11 100644 --- a/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino +++ b/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino @@ -32,6 +32,7 @@ */ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#define MOZZI_CONTROL_RATE 128 #include #include @@ -41,8 +42,6 @@ #include // oscillator template #include // sine table for oscillator -#define CONTROL_RATE 128 - #define F_MAX ((int) 750) #define F_MIN ((int) 150) #define F_CHANGE ((byte) 60) @@ -62,10 +61,10 @@ #define OFFSET_TIME_MAX_MS ((int) 500) #define SYNTH_PARAM_MAX_MS ((byte) 200) -Oscil kFOffsetTrem(SIN1024_DATA); -Oscil kBOffsetTrem(SIN1024_DATA); -Oscil kCFOffsetTrem(SIN1024_DATA); -Oscil kLevelOffsetTrem(SIN1024_DATA); +Oscil kFOffsetTrem(SIN1024_DATA); +Oscil kBOffsetTrem(SIN1024_DATA); +Oscil kCFOffsetTrem(SIN1024_DATA); +Oscil kLevelOffsetTrem(SIN1024_DATA); WavePacketSample wavey; @@ -116,7 +115,7 @@ void setup() { kBOffsetTime.start(rand(200)); kCFOffsetTime.start(rand(200)); kLevelOffsetTime.start(rand(200)); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino index f5116c239..d651aea0e 100644 --- a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino +++ b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino @@ -36,6 +36,7 @@ */ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#define MOZZI_CONTROL_RATE 128 #include #include // Sample template @@ -44,8 +45,6 @@ #include #include // for fixed-point fractional numbers -#define CONTROL_RATE 128 - // use: Sample SampleName (wavetable) Sample aSample0(ABOMB_DATA); Sample aSample1(ABOMB_DATA); @@ -70,13 +69,13 @@ Line kLevel1; #define SAMPLE_FREQ_FIXEDPOINT float_to_Q16n16(SAMPLE_FREQ) // so Line gliss has enough precision #define GLISS_SECONDS (0.666f*SAMPLE_LENGTH_SECONDS*NUM_LOOPS_IN_GLISS) -#define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)CONTROL_RATE * GLISS_SECONDS)) +#define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)MOZZI_CONTROL_RATE * GLISS_SECONDS)) void setup() { kTriggerDelay.start(0); // start trigger before polling in updateControl() aSample0.setLoopingOn(); aSample1.setLoopingOn(); - startMozzi(CONTROL_RATE); + startMozzi(); } byte alevel0, alevel1; diff --git a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino index 64c828aae..2e5888ae0 100644 --- a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino +++ b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino @@ -33,6 +33,7 @@ */ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#define MOZZI_CONTROL_RATE 128 #include #include @@ -43,8 +44,6 @@ #include #include // for fixed-point fractional numbers -#define CONTROL_RATE 128 - // reset and sync vol and freq controls each cycle EventDelay kTriggerDelay0; EventDelay kTriggerDelay1; @@ -56,7 +55,7 @@ EventDelay kTriggerDelay1; #define NOTE_END_FIXEDPOINT float_to_Q16n16(NOTE_CENTRE - NOTE_RANGE) // so Line gliss has enough precision #define GLISS_SECONDS 3.f -#define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)CONTROL_RATE * GLISS_SECONDS)) +#define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)MOZZI_CONTROL_RATE * GLISS_SECONDS)) // use: Line lineName // audio oscils @@ -68,8 +67,8 @@ Oscil aCos0(SIN8192_DATA); Oscil aCos1(SIN8192_DATA); // volume envelope oscils -Oscil kVol0(TRIANGLE512_DATA); -Oscil kVol1(TRIANGLE512_DATA); +Oscil kVol0(TRIANGLE512_DATA); +Oscil kVol1(TRIANGLE512_DATA); // audio volumes updated each control interrupt and reused in audio long v0, v1; @@ -87,7 +86,7 @@ void setup() { kTriggerDelay0.start(0); // start trigger before polling in updateControl() kTriggerDelay1.start((int)((GLISS_SECONDS * 1000.f) / 2.f)); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/12.Misc/Stereo/Stereo.ino b/examples/12.Misc/Stereo/Stereo.ino index 257b4c0ba..a7869dd91 100644 --- a/examples/12.Misc/Stereo/Stereo.ino +++ b/examples/12.Misc/Stereo/Stereo.ino @@ -28,7 +28,7 @@ Oscil aNoise(PINKNOISE8192_DATA); //Phasor for panning -Phasor kPan; // outputs an unsigned long 0-max 32 bit positive number +Phasor kPan; // outputs an unsigned long 0-max 32 bit positive number unsigned int pan; // convey pan from updateControl() to updateAudioStereo(); diff --git a/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino index 4f1e14ee5..cde41f188 100644 --- a/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino +++ b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino @@ -30,7 +30,7 @@ // use: Oscil oscilName (wavetable) Oscil aNoise(PINKNOISE8192_DATA); -Oscil kPan(SIN2048_DATA); +Oscil kPan(SIN2048_DATA); byte ampA, ampB; // convey amplitudes from updateControl() to updateAudioStereo(); diff --git a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino index c9734bb37..a94de3927 100644 --- a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino +++ b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino @@ -32,6 +32,7 @@ #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED // Note: For demonstration purposes, this sketch does *not* set the following (although it would make sense): //#define MOZZI_AUDIO_BITS 12 // the default value of 16 for external audio is thus used, instead +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include @@ -43,13 +44,10 @@ #include // https://github.com/tomcombriat/DAC_MCP49XX // which is an adapted fork from https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx (Thomas Backman) -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - - // Synthesis part Oscil aCarrier(COS2048_DATA); Oscil aModulator(COS2048_DATA); -Oscil kModIndex(COS2048_DATA); +Oscil kModIndex(COS2048_DATA); Q8n8 mod_index; @@ -82,7 +80,7 @@ void audioOutput(const AudioOutput f) void setup() { dac.init(); - kNoteChangeDelay.set(768); // ms countdown, taylored to resolution of CONTROL_RATE + kNoteChangeDelay.set(768); // ms countdown, taylored to resolution of MOZZI_CONTROL_RATE kModIndex.setFreq(.768f); // sync with kNoteChangeDelay target_note = note0; note_change_step = Q7n0_to_Q7n8(3); @@ -95,7 +93,7 @@ void setup() { dac.setPortWrite(true); //comment this line if you do not want to use PortWrite (for non-AVR platforms) - startMozzi(CONTROL_RATE); + startMozzi(); } void setFreqs(Q8n8 midi_note) { diff --git a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino index a590e21a2..4fba5178f 100644 --- a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino +++ b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino @@ -51,6 +51,7 @@ #include "MozziConfigValues.h" // for named option values #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED #define MOZZI_AUDIO_BITS 24 +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include @@ -59,13 +60,10 @@ #include // https://github.com/tomcombriat/DAC_MCP49XX // which is an adapted fork from https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx (Thomas Backman) -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - - // Synthesis part Oscil aCos1(COS2048_DATA); Oscil aCos2(COS2048_DATA); -Oscil kEnv1(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); @@ -101,7 +99,7 @@ void setup() { //dac.setPortWrite(true); //comment this line if you do not want to use PortWrite (for non-AVR platforms) - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino index 20664d4d1..ab5ba44da 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino @@ -30,7 +30,7 @@ #include "MozziConfigValues.h" // for named option values #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED #define MOZZI_AUDIO_CHANNELS MOZZI_STEREO -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include @@ -41,8 +41,8 @@ // Synthesis part Oscil aCos1(COS2048_DATA); Oscil aCos2(COS2048_DATA); -Oscil kEnv1(COS2048_DATA); -Oscil kEnv2(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); +Oscil kEnv2(COS2048_DATA); @@ -81,7 +81,7 @@ void setup() { aCos2.setFreq(220.f); kEnv1.setFreq(0.25f); kEnv2.setFreq(0.30f); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino index 1904cc1c7..a7752a0c9 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino @@ -27,20 +27,18 @@ #include "MozziConfigValues.h" // for named option values #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED #define MOZZI_AUDIO_CHANNELS MOZZI_STEREO +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include #include // table for Oscils to play #include -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - - // Synthesis part Oscil aCos1(COS2048_DATA); Oscil aCos2(COS2048_DATA); -Oscil kEnv1(COS2048_DATA); -Oscil kEnv2(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); +Oscil kEnv2(COS2048_DATA); @@ -78,7 +76,7 @@ void setup() { kEnv1.setFreq(0.25f); kEnv2.setFreq(0.30f); - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino index 716824085..13aaf7e74 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino @@ -42,7 +42,7 @@ #include "MozziConfigValues.h" // for named option values #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED #define MOZZI_AUDIO_BITS 6 -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include // oscillator template @@ -73,7 +73,7 @@ void audioOutput(const AudioOutput f) // f is a structure potentially containing void setup() { for (int i = 0; i < R2R_N_PIN; i++) pinMode(r2r_pin[i], OUTPUT); - startMozzi(CONTROL_RATE); // :) + startMozzi(); // :) aSin.setFreq(200); // set the frequency } diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino index 9b06cb232..71d919dd1 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino @@ -47,7 +47,7 @@ #include "MozziConfigValues.h" // for named option values #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED #define MOZZI_AUDIO_BITS 8 -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include // oscillator template @@ -74,7 +74,7 @@ void setup() { SPI.begin(); SPI.beginTransaction(SPISettings(2000000000, MSBFIRST, SPI_MODE0)); // Qa is the last so we have to set as MSBFIRST // if you reverse the DAC you should put LSBFIRST - startMozzi(CONTROL_RATE); // :) + startMozzi(); // :) aSin.setFreq(200); // set the frequency } diff --git a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino index 61e4e3c9a..b8b7030c9 100644 --- a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino +++ b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino @@ -30,7 +30,7 @@ #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED #define MOZZI_AUDIO_CHANNELS MOZZI_STEREO #define MOZZI_AUDIO_BITS 12 -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include @@ -43,8 +43,8 @@ // Synthesis part Oscil aCos1(COS2048_DATA); Oscil aCos2(COS2048_DATA); -Oscil kEnv1(COS2048_DATA); -Oscil kEnv2(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); +Oscil kEnv2(COS2048_DATA); @@ -78,7 +78,7 @@ void setup() { dac.setPortWrite(true); //comment this line if you do not want to use PortWrite (for non-AVR platforms) - startMozzi(CONTROL_RATE); + startMozzi(); } diff --git a/keywords.txt b/keywords.txt index 893127ded..c222e2050 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,10 +1,12 @@ -MozziGuts KEYWORD1 +Mozzi KEYWORD1 +MozziConfigValues KEYWORD1 +MozziHeadersOnly KEYWORD1 startMozzi KEYWORD2 audioHook KEYWORD2 updateControl KEYWORD3 updateAudio KEYWORD3 -AUDIO_RATE LITERAL1 -CONTROL_RATE LITERAL1 +MOZZI_AUDIO_RATE LITERAL1 +MOZZI_CONTROL_RATE LITERAL1 stopMozzi KEYWORD2 uint8_t KEYWORD1 diff --git a/mozzi_analog.h b/mozzi_analog.h index 943dbb798..fae9221c7 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -130,7 +130,7 @@ returning, adcStartConversion() only sets the conversion to begin, so you can us the cpu for other things and call for the result later with adcGetResult(). @param channel is the analog channel number (0 to ....), which is not necessarily the same as the pin number Use adcPinToChannelNum() to convert the pin number to its channel number. -@note Timing: about 1us when used in updateControl() with CONTROL_RATE 64. +@note Timing: about 1us when used in updateControl() with MOZZI_CONTROL_RATE 64. */ void adcStartConversion(uint8_t channel); From 424e9a146aee2d429fc9307214cd9c2d71a6e8f7 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 28 Jan 2024 22:58:40 +0100 Subject: [PATCH 138/215] Enable warnings report (sounds useful) --- .github/workflows/compile_examples.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/compile_examples.yml b/.github/workflows/compile_examples.yml index 61e5dcc1a..c9b1f9f9f 100644 --- a/.github/workflows/compile_examples.yml +++ b/.github/workflows/compile_examples.yml @@ -114,6 +114,7 @@ jobs: - name: Arduino_AdvancedAnalog enable-deltas-report: true sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + enable-warnings-report: true - name: Save sketches report as workflow artifact uses: actions/upload-artifact@v4 From 2e72b3507b276f2f7e8821d3b57a0319b0e6dbc1 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 29 Jan 2024 17:51:02 +0100 Subject: [PATCH 139/215] Add warning, when defining CONTROL_RATE --- internal/config_checks_generic.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/internal/config_checks_generic.h b/internal/config_checks_generic.h index 020240a2b..42ee55774 100644 --- a/internal/config_checks_generic.h +++ b/internal/config_checks_generic.h @@ -26,7 +26,12 @@ //MOZZI_AUDIO_RATE -> hardware specific #if not defined(MOZZI_CONTROL_RATE) -#define MOZZI_CONTROL_RATE 64 +# if defined(CONTROL_RATE) && (MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST) +# warning Please change CONTROL_RATE to MOZZI_CONTROL_RATE +# define MOZZI_CONTROL_RATE CONTROL_RATE +# else +# define MOZZI_CONTROL_RATE 64 +# endif #endif //MOZZI_ANALOG_READ -> hardware specific, but we want to insert a warning, if not supported, and user has not explicitly configured anything @@ -146,8 +151,10 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_RE /// Step 5: Patch up some backwards compatibility issues as far as config-related #if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST -#define AUDIO_RATE MOZZI_AUDIO_RATE -#define CONTROL_RATE MOZZI_CONTROL_RATE +# define AUDIO_RATE MOZZI_AUDIO_RATE +# if !defined(CONTROL_RATE) +# define CONTROL_RATE MOZZI_CONTROL_RATE +# endif #endif /// Step 6: Some more checks that need to be at the end, because of requiring end of the foodchain headers From 6fd529009d35eaefd94189cd19aff9de62284188 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 29 Jan 2024 21:30:25 +0100 Subject: [PATCH 140/215] AUDIO_RATE -> MOZZI_AUDIO_RATE --- ADSR.h | 4 +- AudioDelay.h | 4 +- AudioDelayFeedback.h | 26 ++++++------- EventDelay.h | 2 +- MozziGuts.h | 10 ++--- Oscil.h | 2 +- PDResonant.h | 8 ++-- Phasor.h | 4 +- Readme_Mozzi_2_0.md | 4 +- ResonantFilter.h | 4 +- Sample.h | 2 +- StateVariable.h | 2 +- WavePacket.h | 4 +- WavePacketSample.h | 2 +- config/mozzi_config_documentation.h | 2 +- .../01.Basics/Control_Gain/Control_Gain.ino | 2 +- .../01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino | 2 +- .../Table_Resolution/Table_Resolution.ino | 12 +++--- examples/01.Basics/Vibrato/Vibrato.ino | 4 +- .../Control_Tremelo/Control_Tremelo.ino | 4 +- examples/02.Control/EventDelay/EventDelay.ino | 2 +- examples/02.Control/Line_Gliss/Line_Gliss.ino | 4 +- .../Line_Gliss_Double_32k_HIFI.ino | 6 +-- examples/02.Control/Stop_Start/Stop_Start.ino | 2 +- .../Knob_LightLevel_FMsynth.ino | 4 +- .../Knob_LightLevel_x2_FMsynth.ino | 4 +- .../Light_Temperature_Detuned.ino | 24 ++++++------ .../Light_Temperature_Multi_Oscil.ino | 16 ++++---- .../Piezo_Frequency/Piezo_Frequency.ino | 2 +- .../Piezo_SampleScrubber.ino | 4 +- .../Piezo_SampleTrigger.ino | 2 +- .../Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino | 2 +- examples/03.Sensors/RCpoll/RCpoll.ino | 2 +- .../Sinewave_Pinchange_Interrupt.ino | 2 +- .../03.Sensors/Volume_Knob/Volume_Knob.ino | 2 +- .../Volume_Knob_LightLevel_Frequency.ino | 2 +- .../Line_vs_Smooth/Line_vs_Smooth.ino | 6 +-- .../MIDI_portamento/MIDI_portamento.ino | 4 +- .../RollingAverage/RollingAverage.ino | 4 +- examples/05.Control_Filters/Smooth/Smooth.ino | 2 +- .../Smooth_Frequency/Smooth_Frequency.ino | 2 +- .../Thermistor_OverSample.ino | 6 +-- examples/06.Synthesis/AMsynth/AMsynth.ino | 6 +-- .../AMsynth_HIFI/AMsynth_HIFI.ino | 6 +-- .../Brown_Noise_Realtime.ino | 2 +- .../Detuned_Beats_Wash/Detuned_Beats_Wash.ino | 28 +++++++------- .../Difference_Tone/Difference_Tone.ino | 6 +-- examples/06.Synthesis/FMsynth/FMsynth.ino | 4 +- .../FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino | 4 +- .../NonAlias_MetaOscil/NonAlias_MetaOscil.ino | 38 +++++++++---------- .../06.Synthesis/PWM_Phasing/PWM_Phasing.ino | 4 +- .../06.Synthesis/WaveFolder/WaveFolder.ino | 4 +- .../06.Synthesis/Waveshaper/Waveshaper.ino | 6 +-- .../ADSR_Audio_Rate_Envelope.ino | 10 ++--- .../ADSR_Audio_Rate_Envelope_Long.ino | 12 +++--- .../ADSR_Audio_Rate_Envelope_x2.ino | 14 +++---- .../ADSR_Control_Rate_Envelope.ino | 2 +- .../Ead_Envelope/Ead_Envelope.ino | 4 +- .../Phasemod_Envelope/Phasemod_Envelope.ino | 8 ++-- examples/08.Samples/Sample/Sample.ino | 2 +- .../Sample_Loop_Points/Sample_Loop_Points.ino | 2 +- .../08.Samples/Sample_Scrub/Sample_Scrub.ino | 4 +- examples/08.Samples/Samples/Samples.ino | 6 +-- .../Samples_Tables_Arrays.ino | 8 ++-- .../Wavetable_Swap/Wavetable_Swap.ino | 2 +- examples/09.Delays/AudioDelay/AudioDelay.ino | 2 +- .../AudioDelayFeedback/AudioDelayFeedback.ino | 2 +- .../AudioDelayFeedbackAllpass.ino | 4 +- .../AudioDelayFeedbackX2.ino | 4 +- .../AudioDelayFeedback_HIFI.ino | 2 +- .../ReverbTank_HIFI/ReverbTank_HIFI.ino | 8 ++-- .../ReverbTank_STANDARD.ino | 8 ++-- .../LowPassFilterX2/LowPassFilterX2.ino | 4 +- .../MultiResonantFilter.ino | 4 +- .../ResonantFilter/ResonantFilter.ino | 4 +- .../ResonantFilter16/ResonantFilter16.ino | 4 +- .../StateVariableFilter.ino | 4 +- .../StateVariableFilter_HIFI.ino | 4 +- .../Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino | 4 +- .../Mozzi_Processing_Serial.ino | 2 +- .../Sinewave_PWM_leds_HIFI.ino | 2 +- .../Teensy_USB_MIDI_Input.ino | 4 +- .../TwoWire_Read_ADXL345.ino | 2 +- .../Risset_Beat_HIFI/Risset_Beat_HIFI.ino | 4 +- .../Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino | 4 +- examples/12.Misc/Stereo/Stereo.ino | 2 +- examples/12.Misc/Stereo_Pan/Stereo_Pan.ino | 2 +- .../FMsynth_MCP4921_mono_12bits.ino | 4 +- .../MCP4922_mono_24bits.ino | 4 +- .../PT8211_stereo_16bits.ino | 4 +- .../PT8211_stereo_16bits_STM32_SPI2.ino | 4 +- .../Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino | 2 +- .../Sinewave_R2R_DAC_74HC595.ino | 2 +- .../Stereo_Pan_MCP4922_stereo_12bits.ino | 4 +- extras/NEWS.txt | 4 +- extras/python/char2mozzi.py | 2 +- internal/MozziGuts.hpp | 2 +- internal/MozziGuts_impl_AVR.hpp | 4 +- internal/MozziGuts_impl_ESP8266.hpp | 2 +- internal/MozziGuts_impl_RP2040.hpp | 2 +- internal/MozziGuts_impl_STM32.hpp | 4 +- internal/MozziGuts_impl_STM32duino.hpp | 4 +- internal/config_checks_esp32.h | 2 +- internal/config_checks_mbed.h | 2 +- internal/config_checks_renesas.h | 2 +- internal/config_checks_samd21.h | 2 +- internal/config_checks_teensy.h | 2 +- utility/FrequencyTimer2.cpp | 4 +- 108 files changed, 266 insertions(+), 266 deletions(-) diff --git a/ADSR.h b/ADSR.h index 93f395a92..0e07b82d2 100644 --- a/ADSR.h +++ b/ADSR.h @@ -28,10 +28,10 @@ and then next() is in updateAudio(), called much more often, where it interpolat This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update. @tparam CONTROL_UPDATE_RATE The frequency of control updates. Ordinarily this will be MOZZI_CONTROL_RATE, but an alternative (amongst others) is -to set this as well as the LERP_RATE parameter to AUDIO_RATE, and call both update() and next() in updateAudio(). +to set this as well as the LERP_RATE parameter to MOZZI_AUDIO_RATE, and call both update() and next() in updateAudio(). Such a use would allow accurate envelopes with finer resolution of the control points than MOZZI_CONTROL_RATE. @tparam LERP_RATE Sets how often next() will be called, to interpolate between updates set by CONTROL_UPDATE_RATE. -This will produce the smoothest results if it's set to AUDIO_RATE, but if you need to save processor time and your +This will produce the smoothest results if it's set to MOZZI_AUDIO_RATE, but if you need to save processor time and your envelope changes slowly or controls something like a filter where there may not be problems with glitchy or clicking transitions, LERP_RATE could be set to MOZZI_CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(), greatly reducing the amount of processing required compared to calling next() in updateAudio(). diff --git a/AudioDelay.h b/AudioDelay.h index 5eaa50760..695c4e0b6 100644 --- a/AudioDelay.h +++ b/AudioDelay.h @@ -43,8 +43,8 @@ class AudioDelay /** Constructor. @param delaytime_cells delay time expressed in cells. - For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms - Put another way, num_cells = delay_seconds * AUDIO_RATE. + For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms + Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE. */ AudioDelay(unsigned int delaytime_cells): _write_pos(0), _delaytime_cells(delaytime_cells) {} diff --git a/AudioDelayFeedback.h b/AudioDelayFeedback.h index 83d455c95..98945e4ec 100644 --- a/AudioDelayFeedback.h +++ b/AudioDelayFeedback.h @@ -49,8 +49,8 @@ class AudioDelayFeedback /** Constructor. @param delaytime_cells delay time expressed in cells. - For example, 128 cells delay at AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms - Put another way, num_cells = delay_seconds * AUDIO_RATE. + For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms + Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE. */ AudioDelayFeedback(uint16_t delaytime_cells): write_pos(0), _feedback_level(0), _delaytime_cells(delaytime_cells) {} @@ -58,8 +58,8 @@ class AudioDelayFeedback /** Constructor. @param delaytime_cells delay time expressed in cells. - For example, 128 cells delay at AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms - Put another way, num_cells = delay_seconds * AUDIO_RATE. + For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms + Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE. @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1). */ AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level): write_pos(0), _feedback_level(feedback_level), _delaytime_cells(delaytime_cells) @@ -200,9 +200,9 @@ class AudioDelayFeedback /** Set delay time expressed in samples. - @param delaytime_cells delay time expressed in cells, with each cell played per tick of AUDIO_RATE. - For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms - Put another way, num_cells = delay_seconds * AUDIO_RATE. + @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE. + For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms + Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE. */ inline void setDelayTimeCells(uint16_t delaytime_cells) @@ -212,9 +212,9 @@ class AudioDelayFeedback /** Set delay time expressed in samples, fractional Q16n16 for an interpolating delay. - @param delaytime_cells delay time expressed in cells, with each cell played per tick of AUDIO_RATE. - For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms - Put another way, num_cells = delay_seconds * AUDIO_RATE. + @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE. + For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms + Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE. */ inline void setDelayTimeCells(Q16n16 delaytime_cells) @@ -224,9 +224,9 @@ class AudioDelayFeedback /** Set delay time expressed in samples, fractional float for an interpolating delay. - @param delaytime_cells delay time expressed in cells, with each cell played per tick of AUDIO_RATE. - For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms - Put another way, num_cells = delay_seconds * AUDIO_RATE. + @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE. + For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms + Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE. */ inline void setDelayTimeCells(float delaytime_cells) diff --git a/EventDelay.h b/EventDelay.h index 168b31677..4c049dd31 100644 --- a/EventDelay.h +++ b/EventDelay.h @@ -26,7 +26,7 @@ class EventDelay Declare an EventDelay object. @param delay_milliseconds how long until ready() returns true, after calling start(). Defaults to 0 if no parameter is supplied. */ - EventDelay(unsigned int delay_milliseconds = 0): AUDIO_TICKS_PER_MILLISECOND((float)AUDIO_RATE/1000.0f) + EventDelay(unsigned int delay_milliseconds = 0): AUDIO_TICKS_PER_MILLISECOND((float)MOZZI_AUDIO_RATE/1000.0f) { set(delay_milliseconds); } diff --git a/MozziGuts.h b/MozziGuts.h index 488ae14bf..b0cf0f872 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -99,7 +99,7 @@ void stopMozzi(); /** @ingroup core This is where you put your audio code. updateAudio() has to keep up with the -AUDIO_RATE of 16384 Hz, so to keep things running smoothly, avoid doing any +MOZZI_AUDIO_RATE of 16384 Hz, so to keep things running smoothly, avoid doing any calculations here which could be done in setup() or updateControl(). @return an audio sample. In STANDARD modes this is between -244 and 243 inclusive. In HIFI mode, it's a 14 bit number between -16384 and 16383 inclusive. @@ -156,9 +156,9 @@ int getAudioInput(); /** @ingroup core An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(), and also it is synchronized with the currently processed audio sample (which, due to the audio -output buffer, could diverge up to 256/AUDIO_RATE seconds from the current time). +output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time). audioTicks() is updated each time an audio sample -is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when AUDIO_RATE is +is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is 16384 Hz). @return the number of audio ticks since the program began. */ @@ -169,9 +169,9 @@ unsigned long audioTicks(); /** @ingroup core An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(), and also it is synchronized with the currently processed audio sample (which, due to the audio -output buffer, could diverge up to 256/AUDIO_RATE seconds from the current time). +output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time). audioTicks() is updated each time an audio sample -is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when AUDIO_RATE is +is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is 16384 Hz). @return the approximate number of microseconds since the program began. @todo incorporate mozziMicros() in a more accurate EventDelay()? diff --git a/Oscil.h b/Oscil.h index da90bdb4d..addd53a29 100644 --- a/Oscil.h +++ b/Oscil.h @@ -38,7 +38,7 @@ cycling oscillator, or atIndex() for a particular sample in the table. @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Oscil will be using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Oscil to run fast enough. -@tparam UPDATE_RATE This will be AUDIO_RATE if the Oscil is updated in +@tparam UPDATE_RATE This will be MOZZI_AUDIO_RATE if the Oscil is updated in updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load. diff --git a/PDResonant.h b/PDResonant.h index 6357fb4bc..89e88d6d6 100644 --- a/PDResonant.h +++ b/PDResonant.h @@ -128,11 +128,11 @@ class PDResonant byte amp; int freq; - Phasor aBaseCounter; - Phasor aResonanceFreqCounter; + Phasor aBaseCounter; + Phasor aResonanceFreqCounter; - Oscil aOsc; - ADSR aAmpEnv; + Oscil aOsc; + ADSR aAmpEnv; ADSR kResonantFreqEnv; }; diff --git a/Phasor.h b/Phasor.h index 8a6cf9383..32ea15e27 100644 --- a/Phasor.h +++ b/Phasor.h @@ -32,8 +32,8 @@ class Phasor volatile uint32_t step_size; public: - /** Constructor. "Phasor myphasor;" - makes a Phasor which updates at AUDIO_RATE. + /** Constructor. "Phasor myphasor;" + makes a Phasor which updates at MOZZI_AUDIO_RATE. */ Phasor (){ ; diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md index c9b8c82af..d2667b202 100644 --- a/Readme_Mozzi_2_0.md +++ b/Readme_Mozzi_2_0.md @@ -7,8 +7,8 @@ changed config names and semantics TODO (incomplete) audio modes mapping - - STANDARD: MOZZI_OUTPUT_PWM with PWM_RATE == AUDIO_RATE - - STANDARD_PLUS: MOZZI_OUTPUT_PWM with PWM_RATE == 32768 + - STANDARD: MOZZI_OUTPUT_PWM with MOZZI_PWM_RATE == MOZZI_AUDIO_RATE + - STANDARD_PLUS: MOZZI_OUTPUT_PWM with MOZZI_PWM_RATE == 32768 - HIFI: MOZZI_OUTPUT_2PIN_PWM - EXTERNAL_AUDIO_OUTPUT (without BYPASS_MOZZI_BUFFER): MOZZI_OUTPUT_EXTERNAL_TIMED - EXTERNAL_AUDIO_OUTPUT (with BYPASS_MOZZI_BUFFER): MOZZI_OUTPUT_EXTERNAL_CUSTOM diff --git a/ResonantFilter.h b/ResonantFilter.h index 072c3e7a0..8cbe9454c 100644 --- a/ResonantFilter.h +++ b/ResonantFilter.h @@ -86,7 +86,7 @@ class ResonantFilter resonance). Set the cut off frequency, - @param cutoff use the range 0-255 to represent 0-8191 Hz (AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-AUDIO_RATE/2. + @param cutoff use the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2. Be careful of distortion at the lower end, especially with high resonance. */ void setCutoffFreq(su cutoff) @@ -108,7 +108,7 @@ class ResonantFilter /** Set the cut off frequency and resonance. Replaces setCutoffFreq() and setResonance(). (Because the internal calculations need to be done whenever either parameter changes.) - @param cutoff range 0-255 represents 0-8191 Hz (AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16 + @param cutoff range 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16 Be careful of distortion at the lower end, especially with high resonance. @param resonance range 0-255 for ResonantFilter, 0-65535 for ResonantFilter, 255/65535 is most resonant. */ diff --git a/Sample.h b/Sample.h index 3a1ed9764..ea2206d58 100644 --- a/Sample.h +++ b/Sample.h @@ -34,7 +34,7 @@ It defaults to playing once through the whole sound table, from start to finish. using. The sound table can be arbitrary length for Sample. It's important that NUM_TABLE_CELLS is either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Sample to run fast enough. -@tparam UPDATE_RATE This will be AUDIO_RATE if the Sample is updated in +@tparam UPDATE_RATE This will be MOZZI_AUDIO_RATE if the Sample is updated in updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load. diff --git a/StateVariable.h b/StateVariable.h index 3ee78f396..bfe52e77b 100644 --- a/StateVariable.h +++ b/StateVariable.h @@ -85,7 +85,7 @@ template class StateVariable { } /** Set the centre or corner frequency of the filter. - @param centre_freq 20 - 4096 Hz (AUDIO_RATE/4). + @param centre_freq 20 - 4096 Hz (MOZZI_AUDIO_RATE/4). This will be the cut-off frequency for LOWPASS and HIGHPASS, and the centre frequency to pass or reduce for BANDPASS and NOTCH. @note Timing 25-30us diff --git a/WavePacket.h b/WavePacket.h index dfadb3045..d663870cc 100644 --- a/WavePacket.h +++ b/WavePacket.h @@ -147,8 +147,8 @@ then that will be yourThing.next()>>2 for HIFI 14 bit output, or >>8 for STANDAR // the number of audio steps the line has to take to reach the next control value const unsigned int AUDIO_STEPS_PER_CONTROL; - Oscil aCos; - Phasor aPhasor; + Oscil aCos; + Phasor aPhasor; inline diff --git a/WavePacketSample.h b/WavePacketSample.h index 004528ac4..3508cf04d 100644 --- a/WavePacketSample.h +++ b/WavePacketSample.h @@ -32,7 +32,7 @@ class WavePacketSample: public WavePacket } private: - Oscil <8192, AUDIO_RATE> aWav; + Oscil <8192, MOZZI_AUDIO_RATE> aWav; }; /** @example 06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino diff --git a/config/mozzi_config_documentation.h b/config/mozzi_config_documentation.h index b97327289..fc5b1c9f0 100644 --- a/config/mozzi_config_documentation.h +++ b/config/mozzi_config_documentation.h @@ -122,7 +122,7 @@ * It is highly recommended to keep the audio rate a power of two (16384, 32678, 64536, etc.), as some internal calculations can be highly be optimised for speed, this way. * * @note - * For compatibility reasons, the option AUDIO_RATE is automatically set to the same value as this option, and you will find some uses of that in old (pre Mozzi 2.0) code examples. + * For compatibility reasons, the option MOZZI_AUDIO_RATE is automatically set to the same value as this option, and you will find some uses of that in old (pre Mozzi 2.0) code examples. * It is advised to use only MOZZI_AUDIO_RATE in new code, however. * TODO: Only do the above, for MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_2_0? */ diff --git a/examples/01.Basics/Control_Gain/Control_Gain.ino b/examples/01.Basics/Control_Gain/Control_Gain.ino index b7e32298b..022d087af 100644 --- a/examples/01.Basics/Control_Gain/Control_Gain.ino +++ b/examples/01.Basics/Control_Gain/Control_Gain.ino @@ -22,7 +22,7 @@ #include // sine table for oscillator // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // control variable, use the smallest data size you can for anything used in audio byte gain = 255; diff --git a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino index fb1769c8c..0356faa95 100644 --- a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino +++ b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino @@ -43,7 +43,7 @@ #include // sine table for oscillator // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); void setup(){ startMozzi(); // uses the default control rate of 64 diff --git a/examples/01.Basics/Table_Resolution/Table_Resolution.ino b/examples/01.Basics/Table_Resolution/Table_Resolution.ino index 8f8c3ec8c..9ce59b6be 100644 --- a/examples/01.Basics/Table_Resolution/Table_Resolution.ino +++ b/examples/01.Basics/Table_Resolution/Table_Resolution.ino @@ -27,12 +27,12 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin0(SIN256_DATA); // can hear significant aliasing noise -Oscil aSin1(SIN512_DATA); // noise still there but less noticeable -Oscil aSin2(SIN1024_DATA); // borderline, hardly there if at all -Oscil aSin3(SIN2048_DATA); // no audible improvement from here on -Oscil aSin4(SIN4096_DATA); // for 45 year old loud sound damaged ears -Oscil aSin5(SIN8192_DATA); +Oscil aSin0(SIN256_DATA); // can hear significant aliasing noise +Oscil aSin1(SIN512_DATA); // noise still there but less noticeable +Oscil aSin2(SIN1024_DATA); // borderline, hardly there if at all +Oscil aSin3(SIN2048_DATA); // no audible improvement from here on +Oscil aSin4(SIN4096_DATA); // for 45 year old loud sound damaged ears +Oscil aSin5(SIN8192_DATA); EventDelay kWhoseTurnDelay; diff --git a/examples/01.Basics/Vibrato/Vibrato.ino b/examples/01.Basics/Vibrato/Vibrato.ino index bc7262e63..9266d737c 100644 --- a/examples/01.Basics/Vibrato/Vibrato.ino +++ b/examples/01.Basics/Vibrato/Vibrato.ino @@ -23,8 +23,8 @@ #include // for mtof #include -Oscil aCos(COS2048_DATA); -Oscil aVibrato(COS2048_DATA); +Oscil aCos(COS2048_DATA); +Oscil aVibrato(COS2048_DATA); const byte intensity = 255; diff --git a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino index 44c642156..c5ee73acd 100644 --- a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino +++ b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino @@ -30,7 +30,7 @@ #include // audio oscillator -Oscil aSig(TRIANGLE_VALVE_2048_DATA); +Oscil aSig(TRIANGLE_VALVE_2048_DATA); // control oscillator for tremelo Oscil kTremelo(SIN2048_DATA); // a line to interpolate control tremolo at audio rate @@ -47,7 +47,7 @@ void setup(){ void updateControl(){ // gain shifted up to give enough range for line's internal steps unsigned int gain = (128u+kTremelo.next())<<8; - aGain.set(gain, AUDIO_RATE / MOZZI_CONTROL_RATE); // divide of literals should get optimised away + aGain.set(gain, MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE); // divide of literals should get optimised away } diff --git a/examples/02.Control/EventDelay/EventDelay.ino b/examples/02.Control/EventDelay/EventDelay.ino index c2040fc2b..efd683171 100644 --- a/examples/02.Control/EventDelay/EventDelay.ino +++ b/examples/02.Control/EventDelay/EventDelay.ino @@ -27,7 +27,7 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN8192_DATA); +Oscil aSin(SIN8192_DATA); // for scheduling audio gain changes EventDelay kGainChangeDelay; diff --git a/examples/02.Control/Line_Gliss/Line_Gliss.ino b/examples/02.Control/Line_Gliss/Line_Gliss.ino index 5f43ce3a7..03ce20304 100644 --- a/examples/02.Control/Line_Gliss/Line_Gliss.ino +++ b/examples/02.Control/Line_Gliss/Line_Gliss.ino @@ -33,7 +33,7 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSaw(SAW8192_DATA); +Oscil aSaw(SAW8192_DATA); // use: Line lineName Line aGliss; @@ -41,7 +41,7 @@ Line aGliss; byte lo_note = 24; // midi note numbers byte hi_note = 36; -long audio_steps_per_gliss = AUDIO_RATE / 4; // ie. 4 glisses per second +long audio_steps_per_gliss = MOZZI_AUDIO_RATE / 4; // ie. 4 glisses per second long control_steps_per_gliss = MOZZI_CONTROL_RATE / 4; // stuff for changing starting positions, probably just confusing really diff --git a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino index c47763218..720fc799d 100644 --- a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino +++ b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino @@ -63,8 +63,8 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSaw1(SAW8192_DATA); -Oscil aSaw2(SAW8192_DATA); +Oscil aSaw1(SAW8192_DATA); +Oscil aSaw2(SAW8192_DATA); // use: Line lineName Line aGliss1; @@ -73,7 +73,7 @@ Line aGliss2; byte lo_note = 24; // midi note numbers byte hi_note = 46; -long audio_steps_per_gliss = AUDIO_RATE / 4; // ie. 4 glisses per second +long audio_steps_per_gliss = MOZZI_AUDIO_RATE / 4; // ie. 4 glisses per second long control_steps_per_gliss = MOZZI_CONTROL_RATE / 4; // stuff for changing starting positions, probably just confusing really diff --git a/examples/02.Control/Stop_Start/Stop_Start.ino b/examples/02.Control/Stop_Start/Stop_Start.ino index 086338d2e..678874410 100644 --- a/examples/02.Control/Stop_Start/Stop_Start.ino +++ b/examples/02.Control/Stop_Start/Stop_Start.ino @@ -25,7 +25,7 @@ #include #include // sine table for oscillator -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); #define STOP_PIN 4 diff --git a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino index 39b2ba042..37464d972 100644 --- a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino @@ -52,8 +52,8 @@ AutoMap kMapIntensity(0,1023,MIN_INTENSITY,MAX_INTENSITY); const int KNOB_PIN = 0; // set the input for the knob to analog pin 0 const int LDR_PIN = 1; // set the input for the LDR to analog pin 1 -Oscil aCarrier(COS2048_DATA); -Oscil aModulator(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); int mod_ratio = 3; // harmonics long fm_intensity; // carries control info from updateControl() to updateAudio() diff --git a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino index fc9f2855a..4c334b3d4 100644 --- a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino @@ -62,8 +62,8 @@ const int KNOB_PIN = 0; // set the input for the knob to analog pin 0 const int LDR1_PIN=1; // set the analog input for fm_intensity to pin 1 const int LDR2_PIN=2; // set the analog input for mod rate to pin 2 -Oscil aCarrier(COS2048_DATA); -Oscil aModulator(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); Oscil kIntensityMod(COS2048_DATA); int mod_ratio = 5; // brightness (harmonics) diff --git a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino index 0bb8d8677..daf34d8e0 100644 --- a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino +++ b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino @@ -40,20 +40,20 @@ #define LDR_PIN 2 // harmonics -Oscil aCos1(COS8192_DATA); -Oscil aCos2(COS8192_DATA); -Oscil aCos3(COS8192_DATA); -Oscil aCos4(COS8192_DATA); -Oscil aCos5(COS8192_DATA); -Oscil aCos6(COS8192_DATA); +Oscil aCos1(COS8192_DATA); +Oscil aCos2(COS8192_DATA); +Oscil aCos3(COS8192_DATA); +Oscil aCos4(COS8192_DATA); +Oscil aCos5(COS8192_DATA); +Oscil aCos6(COS8192_DATA); // duplicates but slightly off frequency for adding to originals -Oscil aCos1b(COS8192_DATA); -Oscil aCos2b(COS8192_DATA); -Oscil aCos3b(COS8192_DATA); -Oscil aCos4b(COS8192_DATA); -Oscil aCos5b(COS8192_DATA); -Oscil aCos6b(COS8192_DATA); +Oscil aCos1b(COS8192_DATA); +Oscil aCos2b(COS8192_DATA); +Oscil aCos3b(COS8192_DATA); +Oscil aCos4b(COS8192_DATA); +Oscil aCos5b(COS8192_DATA); +Oscil aCos6b(COS8192_DATA); // base pitch frequencies float f0, f1,f2,f3,f4,f5,f6; diff --git a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino index ee16a6d33..c81a0fd3d 100644 --- a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino +++ b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino @@ -41,14 +41,14 @@ #define THRESHOLD 10 // harmonics -Oscil aCos1(COS8192_DATA); -Oscil aCos2(COS8192_DATA); -Oscil aCos3(COS8192_DATA); -Oscil aCos4(COS8192_DATA); -Oscil aCos5(COS8192_DATA); -Oscil aCos6(COS8192_DATA); -Oscil aCos7(COS8192_DATA); -Oscil aCos0(COS8192_DATA); +Oscil aCos1(COS8192_DATA); +Oscil aCos2(COS8192_DATA); +Oscil aCos3(COS8192_DATA); +Oscil aCos4(COS8192_DATA); +Oscil aCos5(COS8192_DATA); +Oscil aCos6(COS8192_DATA); +Oscil aCos7(COS8192_DATA); +Oscil aCos0(COS8192_DATA); // volume controls Oscil kVol1(COS8192_DATA); diff --git a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino index b9c516c3e..36701c674 100644 --- a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino +++ b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino @@ -36,7 +36,7 @@ const int PIEZO_PIN = 3; // set the analog input pin for the piezo // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); void setup(){ diff --git a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino index 090b0d55a..d09e6d0ff 100644 --- a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino +++ b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino @@ -41,13 +41,13 @@ Smooth kSmoothOffset(0.85f); // use: Sample SampleName (wavetable) -Sample aSample(BLAHBLAH4B_DATA); +Sample aSample(BLAHBLAH4B_DATA); //Line to scrub through sample at audio rate, Line target is set at control rate Line scrub; // Q16n16 fixed point for high precision // the number of audio steps the line has to take to reach the next offset -const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / MOZZI_CONTROL_RATE; +const unsigned int AUDIO_STEPS_PER_CONTROL = MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE; void setup(){ diff --git a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino index d5e2b99cc..1a79547a6 100644 --- a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino +++ b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino @@ -41,7 +41,7 @@ const char PIEZO_PIN = 3; // set the analog input pin for the piezo const int threshold = 80; // threshold value to decide when the detected signal is a knock or not // use: Sample SampleName (wavetable) -Sample aSample(BURROUGHS1_18649_DATA); +Sample aSample(BURROUGHS1_18649_DATA); float recorded_pitch = (float) BURROUGHS1_18649_SAMPLERATE / (float) BURROUGHS1_18649_NUM_CELLS; boolean triggered = false; diff --git a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino index ed2e24288..64efdd7e0 100644 --- a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino +++ b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino @@ -42,7 +42,7 @@ const int threshold = 80; // threshold value to decide when the detected signal const int BUTTON_PIN = 4; // set the digital input pin for the button // use: Sample SampleName (wavetable) -Sample aSample(BURROUGHS1_18649_DATA); +Sample aSample(BURROUGHS1_18649_DATA); float recorded_pitch = (float) BURROUGHS1_18649_SAMPLERATE / (float) BURROUGHS1_18649_NUM_CELLS; char button_state, previous_button_state; // variable for reading the pushbutton status diff --git a/examples/03.Sensors/RCpoll/RCpoll.ino b/examples/03.Sensors/RCpoll/RCpoll.ino index fb1e32627..ef74b3ab6 100644 --- a/examples/03.Sensors/RCpoll/RCpoll.ino +++ b/examples/03.Sensors/RCpoll/RCpoll.ino @@ -46,7 +46,7 @@ sPin ---\/\/\/-----. #define SENSOR_PIN 4 // digital pin for sensor input -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); RCpoll sensor; diff --git a/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino b/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino index 9bec01a16..00081e910 100644 --- a/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino +++ b/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino @@ -35,7 +35,7 @@ #define PIN 4 // the pin we are interested in // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); void setup(){ diff --git a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino index c87c01560..4a159a87d 100644 --- a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino +++ b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino @@ -36,7 +36,7 @@ #include // sine table for oscillator // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); const char INPUT_PIN = 0; // set the input for the knob to analog pin 0 diff --git a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino index 6b1565b6f..71d1cc1c9 100644 --- a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino +++ b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino @@ -44,7 +44,7 @@ const char KNOB_PIN = 0; // set the input for the knob to analog pin 0 const char LDR_PIN = 1; // set the input for the LDR to analog pin 1 // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); byte volume; diff --git a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino index 5cebccd4a..5f824ce25 100644 --- a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino +++ b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino @@ -35,8 +35,8 @@ #include // 2 oscillators to compare linear interpolated vs smoothed control -Oscil aSin0(SIN2048_DATA); -Oscil aSin1(SIN2048_DATA); +Oscil aSin0(SIN2048_DATA); +Oscil aSin1(SIN2048_DATA); // Line to interpolate frequency for aSin0. @@ -49,7 +49,7 @@ Oscil aSin1(SIN2048_DATA); Line aInterpolate; // the number of audio steps the line has to take to reach the next control value -const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / MOZZI_CONTROL_RATE; +const unsigned int AUDIO_STEPS_PER_CONTROL = MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE; // Smoothing unit for aSin1 // This might be better with Q24n8 numbers for more precision, diff --git a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino index dcba91293..ac9761f23 100644 --- a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino +++ b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino @@ -36,12 +36,12 @@ MIDI_CREATE_DEFAULT_INSTANCE(); // audio sinewave oscillator -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // envelope generator ADSR envelope; -Portamento aPortamento; +Portamento aPortamento; #define LED 13 diff --git a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino index 73b107306..c181384dd 100644 --- a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino +++ b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino @@ -27,8 +27,8 @@ #define INPUT_PIN 0 // analog control input // oscils to compare bumpy to averaged control input -Oscil aSin0(SIN2048_DATA); -Oscil aSin1(SIN2048_DATA); +Oscil aSin0(SIN2048_DATA); +Oscil aSin1(SIN2048_DATA); // use: RollingAverage myThing RollingAverage kAverage; // how_many_to_average has to be power of 2 diff --git a/examples/05.Control_Filters/Smooth/Smooth.ino b/examples/05.Control_Filters/Smooth/Smooth.ino index 8de5a4132..e4e63c83a 100644 --- a/examples/05.Control_Filters/Smooth/Smooth.ino +++ b/examples/05.Control_Filters/Smooth/Smooth.ino @@ -26,7 +26,7 @@ #include #include -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // for scheduling audio gain changes EventDelay kGainChangeDelay; diff --git a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino index 4c821e46f..f24d5a7e9 100644 --- a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino +++ b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino @@ -26,7 +26,7 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // for scheduling freq changes EventDelay kFreqChangeDelay; diff --git a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino index acd25e878..29ac13e35 100644 --- a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino +++ b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino @@ -37,9 +37,9 @@ #include // use: Oscil oscilName (wavetable) -Oscil aSin(SIN2048_DATA); -Oscil aTremelo(SIN2048_DATA); -Oscil aEnvelope(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); +Oscil aTremelo(SIN2048_DATA); +Oscil aEnvelope(SIN2048_DATA); Line freqLine; diff --git a/examples/06.Synthesis/AMsynth/AMsynth.ino b/examples/06.Synthesis/AMsynth/AMsynth.ino index 17b40b934..42b587a69 100644 --- a/examples/06.Synthesis/AMsynth/AMsynth.ino +++ b/examples/06.Synthesis/AMsynth/AMsynth.ino @@ -30,9 +30,9 @@ #include // audio oscils -Oscil aCarrier(COS2048_DATA); -Oscil aModulator(COS2048_DATA); -Oscil aModDepth(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); +Oscil aModDepth(COS2048_DATA); // for scheduling note changes in updateControl() EventDelay kNoteChangeDelay; diff --git a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino index 3a00207a6..49de5bd70 100644 --- a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino +++ b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino @@ -51,9 +51,9 @@ #include // audio oscils -Oscil aCarrier(COS2048_DATA); -Oscil aModulator(COS2048_DATA); -Oscil aModDepth(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); +Oscil aModDepth(COS2048_DATA); // for scheduling note changes in updateControl() EventDelay kNoteChangeDelay; diff --git a/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino b/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino index d1ad9e398..bcae5eafa 100644 --- a/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino +++ b/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino @@ -26,7 +26,7 @@ #define FILTER_SHIFT 6 // 5 or 6 work well - the spectrum of 6 looks a bit more linear, like the generated brown noise in Audacity // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); void setup() { diff --git a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino index 05eb161d1..c9f6d1b0c 100644 --- a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino +++ b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino @@ -37,22 +37,22 @@ #include // for Q16n16 fixed-point fractional number type // harmonics -Oscil aCos1(COS8192_DATA); -Oscil aCos2(COS8192_DATA); -Oscil aCos3(COS8192_DATA); -Oscil aCos4(COS8192_DATA); -Oscil aCos5(COS8192_DATA); -Oscil aCos6(COS8192_DATA); -//Oscil aCos7(COS8192_DATA); // used to work smoothly in Arduino 1.05 +Oscil aCos1(COS8192_DATA); +Oscil aCos2(COS8192_DATA); +Oscil aCos3(COS8192_DATA); +Oscil aCos4(COS8192_DATA); +Oscil aCos5(COS8192_DATA); +Oscil aCos6(COS8192_DATA); +//Oscil aCos7(COS8192_DATA); // used to work smoothly in Arduino 1.05 // duplicates but slightly off frequency for adding to originals -Oscil aCos1b(COS8192_DATA); -Oscil aCos2b(COS8192_DATA); -Oscil aCos3b(COS8192_DATA); -Oscil aCos4b(COS8192_DATA); -Oscil aCos5b(COS8192_DATA); -Oscil aCos6b(COS8192_DATA); -//Oscil aCos7b(COS8192_DATA); +Oscil aCos1b(COS8192_DATA); +Oscil aCos2b(COS8192_DATA); +Oscil aCos3b(COS8192_DATA); +Oscil aCos4b(COS8192_DATA); +Oscil aCos5b(COS8192_DATA); +Oscil aCos6b(COS8192_DATA); +//Oscil aCos7b(COS8192_DATA); // base pitch frequencies in Q16n16 fixed int format (for speed later) Q16n16 f1,f2,f3,f4,f5,f6;//,f7; diff --git a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino index cf6afcb4b..b33a8732f 100644 --- a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino +++ b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino @@ -25,9 +25,9 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin1(SIN2048_DATA); // sine wave sound source -Oscil aSin2(SIN2048_DATA); // sine wave sound source -Oscil aGain(SIN2048_DATA); // to fade audio signal in and out before waveshaping +Oscil aSin1(SIN2048_DATA); // sine wave sound source +Oscil aSin2(SIN2048_DATA); // sine wave sound source +Oscil aGain(SIN2048_DATA); // to fade audio signal in and out before waveshaping // for scheduling note changes EventDelay kChangeNoteDelay; diff --git a/examples/06.Synthesis/FMsynth/FMsynth.ino b/examples/06.Synthesis/FMsynth/FMsynth.ino index 810c27c22..c2a23d8e5 100644 --- a/examples/06.Synthesis/FMsynth/FMsynth.ino +++ b/examples/06.Synthesis/FMsynth/FMsynth.ino @@ -31,8 +31,8 @@ #include #include -Oscil aCarrier(COS2048_DATA); -Oscil aModulator(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); Oscil kModIndex(COS2048_DATA); // The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm ) diff --git a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino index 54ec56186..d7c6016da 100644 --- a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino +++ b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino @@ -55,8 +55,8 @@ #include #include -Oscil aCarrier(COS2048_DATA); -Oscil aModulator(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); Oscil kModIndex(COS2048_DATA); // The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm ) diff --git a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino index 32920f133..36e24282f 100644 --- a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino +++ b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino @@ -2,7 +2,7 @@ using Mozzi sonification library. Waveforms which are not only sines (Saw, square, triangle) are composed by a lot of harmonics which are at frequencies multiple of the fundamental frequency. - If the frequency of one of these harmonics is higher than half the sampling frequency (https://en.wikipedia.org/wiki/Nyquist_frequency) (AUDIO_RATE/2 here) + If the frequency of one of these harmonics is higher than half the sampling frequency (https://en.wikipedia.org/wiki/Nyquist_frequency) (MOZZI_AUDIO_RATE/2 here) it will create "aliases" (https://en.wikipedia.org/wiki/Aliasing) which will sound out of tune are they not harmonically related to the fundamental. The higher the pitch, the more harmonics are above the Nyquist limit and the more aliased will be present for a given waveform. @@ -62,26 +62,26 @@ // The proper Oscillators that will be managed by the MetaOscil // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSq90(SQUARE_MAX_90_AT_16384_512_DATA); -Oscil aSq101(SQUARE_MAX_101_AT_16384_512_DATA); -Oscil aSq122(SQUARE_MAX_122_AT_16384_512_DATA); -Oscil aSq138(SQUARE_MAX_138_AT_16384_512_DATA); -Oscil aSq154(SQUARE_MAX_154_AT_16384_512_DATA); -Oscil aSq174(SQUARE_MAX_174_AT_16384_512_DATA); -Oscil aSq210(SQUARE_MAX_210_AT_16384_512_DATA); -Oscil aSq264(SQUARE_MAX_264_AT_16384_512_DATA); -Oscil aSq327(SQUARE_MAX_327_AT_16384_512_DATA); -Oscil aSq431(SQUARE_MAX_431_AT_16384_512_DATA); -Oscil aSq546(SQUARE_MAX_546_AT_16384_512_DATA); -Oscil aSq744(SQUARE_MAX_744_AT_16384_512_DATA); -Oscil aSq910(SQUARE_MAX_910_AT_16384_512_DATA); -Oscil aSq1170(SQUARE_MAX_1170_AT_16384_512_DATA); -Oscil aSq1638(SQUARE_MAX_1638_AT_16384_512_DATA); -Oscil aSq2730(SQUARE_MAX_2730_AT_16384_512_DATA); -Oscil aSq8192(SQUARE_MAX_8192_AT_16384_512_DATA); +Oscil aSq90(SQUARE_MAX_90_AT_16384_512_DATA); +Oscil aSq101(SQUARE_MAX_101_AT_16384_512_DATA); +Oscil aSq122(SQUARE_MAX_122_AT_16384_512_DATA); +Oscil aSq138(SQUARE_MAX_138_AT_16384_512_DATA); +Oscil aSq154(SQUARE_MAX_154_AT_16384_512_DATA); +Oscil aSq174(SQUARE_MAX_174_AT_16384_512_DATA); +Oscil aSq210(SQUARE_MAX_210_AT_16384_512_DATA); +Oscil aSq264(SQUARE_MAX_264_AT_16384_512_DATA); +Oscil aSq327(SQUARE_MAX_327_AT_16384_512_DATA); +Oscil aSq431(SQUARE_MAX_431_AT_16384_512_DATA); +Oscil aSq546(SQUARE_MAX_546_AT_16384_512_DATA); +Oscil aSq744(SQUARE_MAX_744_AT_16384_512_DATA); +Oscil aSq910(SQUARE_MAX_910_AT_16384_512_DATA); +Oscil aSq1170(SQUARE_MAX_1170_AT_16384_512_DATA); +Oscil aSq1638(SQUARE_MAX_1638_AT_16384_512_DATA); +Oscil aSq2730(SQUARE_MAX_2730_AT_16384_512_DATA); +Oscil aSq8192(SQUARE_MAX_8192_AT_16384_512_DATA); // use: MetaOscil MetaoscilName. All oscils used should have the same table_size and **have to be put in increasing order of cutoff_frequencies**. -MetaOscil BL_aSq {&aSq90, &aSq101, &aSq122, &aSq138, &aSq154, &aSq174, &aSq210, &aSq264, &aSq327, &aSq431, &aSq546, &aSq744, &aSq1170, &aSq1638, &aSq2730, &aSq8192}; +MetaOscil BL_aSq {&aSq90, &aSq101, &aSq122, &aSq138, &aSq154, &aSq174, &aSq210, &aSq264, &aSq327, &aSq431, &aSq546, &aSq744, &aSq1170, &aSq1638, &aSq2730, &aSq8192}; int freq = 10; diff --git a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino index eafe06028..3e176a45a 100644 --- a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino +++ b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino @@ -24,8 +24,8 @@ #include #include -Phasor aPhasor1; -Phasor aPhasor2; +Phasor aPhasor1; +Phasor aPhasor2; float freq = 55.f; diff --git a/examples/06.Synthesis/WaveFolder/WaveFolder.ino b/examples/06.Synthesis/WaveFolder/WaveFolder.ino index a2e062815..fef66257d 100644 --- a/examples/06.Synthesis/WaveFolder/WaveFolder.ino +++ b/examples/06.Synthesis/WaveFolder/WaveFolder.ino @@ -23,7 +23,7 @@ #include // saw table for oscillator #include -Oscil aSin(SIN2048_DATA); // audio oscillator +Oscil aSin(SIN2048_DATA); // audio oscillator Oscil kBias(SIN2048_DATA); // LFO changing the bias Oscil kGain(SAW512_DATA); // Gain oscillator @@ -40,7 +40,7 @@ void setup() { kBias.setFreq(0.3f); // set the frequency kGain.setFreq(0.2f); wf.setLimits(-2047, 2047); // sets the values the wavefolder will start folding (in this case, containing in 12 bits) - // can also be done at MOZZI_CONTROL_RATE (even maybe at AUDIO_RATE) + // can also be done at MOZZI_CONTROL_RATE (even maybe at MOZZI_AUDIO_RATE) startMozzi(); } diff --git a/examples/06.Synthesis/Waveshaper/Waveshaper.ino b/examples/06.Synthesis/Waveshaper/Waveshaper.ino index 5369ffd56..f30d12007 100644 --- a/examples/06.Synthesis/Waveshaper/Waveshaper.ino +++ b/examples/06.Synthesis/Waveshaper/Waveshaper.ino @@ -30,9 +30,9 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); // sine wave sound source -Oscil aGain1(SIN2048_DATA); // to fade sine wave in and out before waveshaping -Oscil aGain2(SIN2048_DATA); // to fade sine wave in and out before waveshaping +Oscil aSin(SIN2048_DATA); // sine wave sound source +Oscil aGain1(SIN2048_DATA); // to fade sine wave in and out before waveshaping +Oscil aGain2(SIN2048_DATA); // to fade sine wave in and out before waveshaping // Chebyshev polynomial curves, The nth curve produces the n+2th harmonic component. WaveShaper aCheby3rd(CHEBYSHEV_3RD_256_DATA); // 5th harmonic diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino index 1a14ca2ca..df479c90b 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino @@ -1,10 +1,10 @@ /* Example applying an ADSR envelope to an audio signal with Mozzi sonification library. This shows - how to use an ADSR which updates at AUDIO_RATE, in updateAudio(), - and output using next() at AUDIO_RATE in updateAudio(). + how to use an ADSR which updates at MOZZI_AUDIO_RATE, in updateAudio(), + and output using next() at MOZZI_AUDIO_RATE in updateAudio(). Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, - which is more efficient, but AUDIO_RATE updates shown in this example + which is more efficient, but MOZZI_AUDIO_RATE updates shown in this example enable faster envelope transitions. Demonstrates a simple ADSR object being controlled with @@ -27,12 +27,12 @@ #include #include -Oscil <8192, AUDIO_RATE> aOscil(SIN8192_DATA);; +Oscil <8192, MOZZI_AUDIO_RATE> aOscil(SIN8192_DATA);; // for triggering the envelope EventDelay noteDelay; -ADSR envelope; +ADSR envelope; boolean note_is_on = true; diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino index da691c8c0..85d792f6c 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino @@ -1,13 +1,13 @@ /* Example applying an ADSR envelope to an audio signal with Mozzi sonification library. This is nearly an exact copy of ADSR_Audio_Rate_Envelope which shows - how to use an ADSR which updates at AUDIO_RATE, in updateAudio(), - output using next() at AUDIO_RATE in updateAudio(). This one uses + how to use an ADSR which updates at MOZZI_AUDIO_RATE, in updateAudio(), + output using next() at MOZZI_AUDIO_RATE in updateAudio(). This one uses unsigned long as the third ADSR parameter to allow long envelopes - to be updated at AUDIO_RATE. + to be updated at MOZZI_AUDIO_RATE. Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, - which is more efficient, but AUDIO_RATE updates shown in this example + which is more efficient, but MOZZI_AUDIO_RATE updates shown in this example enable faster envelope transitions. Demonstrates a simple ADSR object being controlled with @@ -30,12 +30,12 @@ #include #include -Oscil <8192, AUDIO_RATE> aOscil(SIN8192_DATA);; +Oscil <8192, MOZZI_AUDIO_RATE> aOscil(SIN8192_DATA);; // for triggering the envelope EventDelay noteDelay; -ADSR envelope; +ADSR envelope; boolean note_is_on = true; diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino index 92612f018..04bcf72d6 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino @@ -1,11 +1,11 @@ /* Example applying ADSR envelopes to 2 audio oscillators with Mozzi sonification library. - This shows how to use an ADSR which updates at AUDIO_RATE, - in updateAudio(), and output using next() at AUDIO_RATE in updateAudio(). + This shows how to use an ADSR which updates at MOZZI_AUDIO_RATE, + in updateAudio(), and output using next() at MOZZI_AUDIO_RATE in updateAudio(). Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, - which is more efficient, but AUDIO_RATE updates shown in this example + which is more efficient, but MOZZI_AUDIO_RATE updates shown in this example enable faster envelope transitions. Mozzi documentation/API @@ -25,15 +25,15 @@ #include #include -Oscil <8192, AUDIO_RATE> aOscil0(SIN8192_DATA); -Oscil <8192, AUDIO_RATE> aOscil1(SIN8192_DATA); +Oscil <8192, MOZZI_AUDIO_RATE> aOscil0(SIN8192_DATA); +Oscil <8192, MOZZI_AUDIO_RATE> aOscil1(SIN8192_DATA); // for triggering the envelope EventDelay noteDelay; // ADSR update_rate, interpolation_rte -ADSR envelope0; -ADSR envelope1; +ADSR envelope0; +ADSR envelope1; boolean note_is_on = true; diff --git a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino index 2175140f4..0ef779b01 100644 --- a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino @@ -20,7 +20,7 @@ #include #include -Oscil <8192, AUDIO_RATE> aOscil(SIN8192_DATA);; +Oscil <8192, MOZZI_AUDIO_RATE> aOscil(SIN8192_DATA);; // for triggering the envelope EventDelay noteDelay; diff --git a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino index a55b8fa69..c73781482 100644 --- a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino +++ b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino @@ -21,7 +21,7 @@ #include #include -Oscil aNoise(BROWNNOISE8192_DATA); +Oscil aNoise(BROWNNOISE8192_DATA); EventDelay kDelay; // for triggering envelope start Ead kEnvelope(MOZZI_CONTROL_RATE); // resolution will be MOZZI_CONTROL_RATE @@ -30,7 +30,7 @@ int gain; void setup(){ // use float to set freq because it will be small and fractional - aNoise.setFreq((float)AUDIO_RATE/BROWNNOISE8192_SAMPLERATE); + aNoise.setFreq((float)MOZZI_AUDIO_RATE/BROWNNOISE8192_SAMPLERATE); randSeed(); // fresh random, MUST be called before startMozzi - wierd bug startMozzi(); kDelay.start(1000); diff --git a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino index a3b8ca3e8..afd5b109a 100644 --- a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino +++ b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino @@ -21,12 +21,12 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aCarrier(COS8192_DATA); -Oscil aModulator(COS8192_DATA); -Oscil aModWidth(COS8192_DATA); +Oscil aCarrier(COS8192_DATA); +Oscil aModulator(COS8192_DATA); +Oscil aModWidth(COS8192_DATA); Oscil kModFreq1(COS8192_DATA); Oscil kModFreq2(COS8192_DATA); -Oscil aEnvelop(ENVELOP2048_DATA); +Oscil aEnvelop(ENVELOP2048_DATA); void setup() { diff --git a/examples/08.Samples/Sample/Sample.ino b/examples/08.Samples/Sample/Sample.ino index 088174bf7..e0693232c 100644 --- a/examples/08.Samples/Sample/Sample.ino +++ b/examples/08.Samples/Sample/Sample.ino @@ -23,7 +23,7 @@ #include // use: Sample SampleName (wavetable) -Sample aSample(BURROUGHS1_18649_DATA); +Sample aSample(BURROUGHS1_18649_DATA); // for scheduling sample start EventDelay kTriggerDelay; diff --git a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino index ee1a96307..9be5cbe51 100644 --- a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino +++ b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino @@ -28,7 +28,7 @@ #include // use: Sample SampleName (wavetable) -Sample aSample(ABOMB_DATA); +Sample aSample(ABOMB_DATA); // for scheduling changes EventDelay kTriggerDelay; diff --git a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino index edfbc4c30..fe9c4507a 100644 --- a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino +++ b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino @@ -23,13 +23,13 @@ #include // use: Sample SampleName (wavetable) -Sample aSample(BURROUGHS1_18649_DATA); +Sample aSample(BURROUGHS1_18649_DATA); //Line to scrub through sample at audio rate, Line target is set at control rate Line scrub; // Q16n16 fixed point for high precision // the number of audio steps the line has to take to reach the next offset -const unsigned int AUDIO_STEPS_PER_CONTROL = AUDIO_RATE / MOZZI_CONTROL_RATE; +const unsigned int AUDIO_STEPS_PER_CONTROL = MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE; int offset = 0; int offset_advance = 400; // just a guess diff --git a/examples/08.Samples/Samples/Samples.ino b/examples/08.Samples/Samples/Samples.ino index c8eab3322..42aca1388 100644 --- a/examples/08.Samples/Samples/Samples.ino +++ b/examples/08.Samples/Samples/Samples.ino @@ -27,9 +27,9 @@ #include // use: Sample SampleName (wavetable) -Sample aBamboo0(BAMBOO_00_2048_DATA); -Sample aBamboo1(BAMBOO_01_2048_DATA); -Sample aBamboo2(BAMBOO_02_2048_DATA); +Sample aBamboo0(BAMBOO_00_2048_DATA); +Sample aBamboo1(BAMBOO_01_2048_DATA); +Sample aBamboo2(BAMBOO_02_2048_DATA); // for scheduling audio gain changes EventDelay kTriggerDelay; diff --git a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino index a3f855092..817e73e59 100644 --- a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino +++ b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino @@ -47,10 +47,10 @@ byte ms_per_note = 111; // subject to MOZZI_CONTROL_RATE const byte NUM_PLAYERS = 3; // 3 seems to be enough const byte NUM_TABLES = 11; -Sample aSample[NUM_PLAYERS] ={ - Sample (BAMBOO_00_2048_DATA), - Sample (BAMBOO_01_2048_DATA), - Sample (BAMBOO_02_2048_DATA), +Sample aSample[NUM_PLAYERS] ={ + Sample (BAMBOO_00_2048_DATA), + Sample (BAMBOO_01_2048_DATA), + Sample (BAMBOO_02_2048_DATA), }; // watch out - tables are const (but you can choose which ones you reference) diff --git a/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino b/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino index d76875629..6e0c0a5e7 100644 --- a/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino +++ b/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino @@ -16,7 +16,7 @@ #include // declare with or without a wavetable, and use setTable() later -Oscil <512, AUDIO_RATE> aOscil; +Oscil <512, MOZZI_AUDIO_RATE> aOscil; // for scheduling table swaps EventDelay kSwapTablesDelay; diff --git a/examples/09.Delays/AudioDelay/AudioDelay.ino b/examples/09.Delays/AudioDelay/AudioDelay.ino index 13e5ff094..d08e5cd11 100644 --- a/examples/09.Delays/AudioDelay/AudioDelay.ino +++ b/examples/09.Delays/AudioDelay/AudioDelay.ino @@ -24,7 +24,7 @@ #include #include // for mtof -Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); +Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); Oscil kFreq(COS2048_DATA); AudioDelay <256> aDel; diff --git a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino index 766c9d33d..14b76d2cb 100644 --- a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino +++ b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino @@ -24,7 +24,7 @@ #include #include // for mtof -Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator +Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator Oscil kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples AudioDelayFeedback <128> aDel; diff --git a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino index 20575168b..9538b74a2 100644 --- a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino +++ b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino @@ -27,7 +27,7 @@ #include #include -Oscil aNoise(WHITENOISE8192_DATA); // audio noise +Oscil aNoise(WHITENOISE8192_DATA); // audio noise EventDelay kDelay; // for triggering envelope start Ead kEnvelope(MOZZI_CONTROL_RATE); // resolution will be MOZZI_CONTROL_RATE @@ -41,7 +41,7 @@ void setup(){ startMozzi(); randSeed(); // reseed the random generator for different results each time the sketch runs // use float to set freq because it will be small and fractional - aNoise.setFreq((float)AUDIO_RATE/WHITENOISE8192_SAMPLERATE); + aNoise.setFreq((float)MOZZI_AUDIO_RATE/WHITENOISE8192_SAMPLERATE); kDelay.start(1000); } diff --git a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino index 73d1bc8f8..bb588a394 100644 --- a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino +++ b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino @@ -25,8 +25,8 @@ #include #include // for mtof -Oscil aTriangle1(TRIANGLE_ANALOGUE512_DATA); // audio oscillator -Oscil aTriangle2(TRIANGLE_ANALOGUE512_DATA); // audio oscillator +Oscil aTriangle1(TRIANGLE_ANALOGUE512_DATA); // audio oscillator +Oscil aTriangle2(TRIANGLE_ANALOGUE512_DATA); // audio oscillator Oscil kDelSamps1(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples Oscil kDelSamps2(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples diff --git a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino index 84ab8dd2e..8b870b077 100644 --- a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino +++ b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino @@ -51,7 +51,7 @@ #include #include // for mtof -Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator +Oscil aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator Oscil kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples AudioDelayFeedback <128> aDel; diff --git a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino index cbaf1f8fe..2253f4336 100644 --- a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino +++ b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino @@ -32,12 +32,12 @@ ReverbTank reverb; // Synth from PhaseMod_Envelope example -Oscil aCarrier(COS8192_DATA); -Oscil aModulator(COS8192_DATA); -Oscil aModWidth(COS8192_DATA); +Oscil aCarrier(COS8192_DATA); +Oscil aModulator(COS8192_DATA); +Oscil aModWidth(COS8192_DATA); Oscil kModFreq1(COS8192_DATA); Oscil kModFreq2(COS8192_DATA); -Oscil aEnvelop(ENVELOP2048_DATA); +Oscil aEnvelop(ENVELOP2048_DATA); void setup(){ diff --git a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino index 24184f2f5..b3284698d 100644 --- a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino +++ b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino @@ -32,12 +32,12 @@ ReverbTank reverb; // Synth from PhaseMod_Envelope example -Oscil aCarrier(COS8192_DATA); -Oscil aModulator(COS8192_DATA); -Oscil aModWidth(COS8192_DATA); +Oscil aCarrier(COS8192_DATA); +Oscil aModulator(COS8192_DATA); +Oscil aModWidth(COS8192_DATA); Oscil kModFreq1(COS8192_DATA); Oscil kModFreq2(COS8192_DATA); -Oscil aEnvelop(ENVELOP2048_DATA); +Oscil aEnvelop(ENVELOP2048_DATA); void setup(){ diff --git a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino index 9e89546e4..a6a833e30 100644 --- a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino +++ b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino @@ -23,8 +23,8 @@ #include #include // for rand() -Oscil aCrunchySound1(CHUM9_DATA); //audio oscillator -Oscil aCrunchySound2(CHUM9_DATA); //audio oscillator +Oscil aCrunchySound1(CHUM9_DATA); //audio oscillator +Oscil aCrunchySound2(CHUM9_DATA); //audio oscillator Oscil kFilterMod1(COS512_DATA); // to modulate filter frequency Oscil kFilterMod2(COS512_DATA); // to modulate filter frequency diff --git a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino index d2303b9d1..0a61cc58a 100644 --- a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino +++ b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino @@ -30,7 +30,7 @@ #include #include -Oscil aCrunchySound(CHUM9_DATA); +Oscil aCrunchySound(CHUM9_DATA); Oscil kFilterMod(COS2048_DATA); Oscil kFilterMod2(COS2048_DATA); @@ -60,7 +60,7 @@ void updateControl() { kFilterMod.setFreq((float)rand(255) / 64); // choose a new modulation frequency filter_type = rand(4); // change the filter type, randomly } - // map the modulation into the filter range (0-255), corresponds with 0-AUDIO_RATE/(sqrt(2)*pi) Hz + // map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz uint8_t cutoff_freq = (100 + kFilterMod.next() / 2) ; mf.setCutoffFreqAndResonance(cutoff_freq, resonance); } diff --git a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino index dcc791272..3f61f30a8 100644 --- a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino +++ b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino @@ -27,7 +27,7 @@ #include #include -Oscil aCrunchySound(CHUM9_DATA); +Oscil aCrunchySound(CHUM9_DATA); Oscil kFilterMod(COS2048_DATA); //Different types of filters available @@ -52,7 +52,7 @@ void updateControl(){ if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency } - // map the modulation into the filter range (0-255), corresponds with 0-AUDIO_RATE/(sqrt(2)*pi) Hz + // map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz byte cutoff_freq = 100 + kFilterMod.next()/2; rf.setCutoffFreqAndResonance(cutoff_freq, resonance); } diff --git a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino index f3d67661e..fc571a1d5 100644 --- a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino +++ b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino @@ -29,7 +29,7 @@ #include #include -Oscil aCrunchySound(CHUM9_DATA); +Oscil aCrunchySound(CHUM9_DATA); Oscil kFilterMod(COS2048_DATA); Oscil kFilterMod2(COS2048_DATA); @@ -58,7 +58,7 @@ void updateControl(){ if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency } - // map the modulation into the filter range (0-255), corresponds with 0-AUDIO_RATE/(sqrt(2)*pi) Hz + // map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz uint16_t cutoff_freq = (100 + kFilterMod.next()/2) * (170+kFilterMod2.next()); rf.setCutoffFreqAndResonance(cutoff_freq, resonance); } diff --git a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino index cb5fd5946..acc5226f7 100644 --- a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino +++ b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino @@ -23,7 +23,7 @@ #include #include // for rand() -Oscil aNoise(WHITENOISE8192_DATA); // audio noise +Oscil aNoise(WHITENOISE8192_DATA); // audio noise Oscil kFilterMod(COS2048_DATA); StateVariable svf; // can be LOWPASS, BANDPASS, HIGHPASS or NOTCH @@ -32,7 +32,7 @@ StateVariable svf; // can be LOWPASS, BANDPASS, HIGHPASS or NOTCH void setup(){ startMozzi(); // cast to float because the resulting freq will be small and fractional - aNoise.setFreq((float)AUDIO_RATE/WHITENOISE8192_SAMPLERATE); + aNoise.setFreq((float)MOZZI_AUDIO_RATE/WHITENOISE8192_SAMPLERATE); kFilterMod.setFreq(1.3f); svf.setResonance(25); svf.setCentreFreq(1200); diff --git a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino index 5b0681aad..b780566e8 100644 --- a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino +++ b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino @@ -45,13 +45,13 @@ #include #include -Oscil aNoise(WHITENOISE8192_DATA); // audio noise +Oscil aNoise(WHITENOISE8192_DATA); // audio noise StateVariable svf; // can be LOWPASS, BANDPASS, HIGHPASS or NOTCH void setup(){ startMozzi(); - aNoise.setFreq(1.27f*(float)AUDIO_RATE/WHITENOISE8192_SAMPLERATE); // * by an oddish number (1.27) to avoid exact repeating of noise oscil + aNoise.setFreq(1.27f*(float)MOZZI_AUDIO_RATE/WHITENOISE8192_SAMPLERATE); // * by an oddish number (1.27) to avoid exact repeating of noise oscil svf.setResonance(1); // 0 to 255, 0 is the "sharp" end svf.setCentreFreq(3500); } diff --git a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino index c5d9331ca..127719c4b 100644 --- a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino +++ b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino @@ -32,10 +32,10 @@ MIDI_CREATE_DEFAULT_INSTANCE(); // audio sinewave oscillator -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // envelope generator -ADSR envelope; +ADSR envelope; #define LED 13 // shows if MIDI is being recieved diff --git a/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino b/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino index 904960bbf..bc6f62806 100644 --- a/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino +++ b/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino @@ -24,7 +24,7 @@ #include // sine table for oscillator // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); void setup(){ //Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches diff --git a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino index a861d01ca..ed4bd2fae 100644 --- a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino +++ b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino @@ -71,7 +71,7 @@ Oscil kGreen(SIN2048_DATA); Oscil kBlue(SIN2048_DATA); // audio oscillator -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); void updateRGB(byte r, byte g, byte b){ diff --git a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino index c921caaeb..66356d589 100644 --- a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino +++ b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino @@ -32,10 +32,10 @@ // audio sinewave oscillator -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // envelope generator -ADSR envelope; +ADSR envelope; #define LED 6 // 6 on Teensy++ 2.0, 11 on Teensy 2.0, to see if MIDI is being recieved diff --git a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino index 3dfad0aac..2b4364431 100644 --- a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino +++ b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino @@ -28,7 +28,7 @@ #include // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); Ead kEnvelope(MOZZI_CONTROL_RATE); // resolution will be MOZZI_CONTROL_RATE int gain; diff --git a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino index d651aea0e..82c2d9448 100644 --- a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino +++ b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino @@ -46,8 +46,8 @@ #include // for fixed-point fractional numbers // use: Sample SampleName (wavetable) -Sample aSample0(ABOMB_DATA); -Sample aSample1(ABOMB_DATA); +Sample aSample0(ABOMB_DATA); +Sample aSample1(ABOMB_DATA); // for scheduling changes EventDelay kTriggerDelay; diff --git a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino index 2e5888ae0..512c44383 100644 --- a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino +++ b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino @@ -63,8 +63,8 @@ Line kGliss0; // Line to slide frequency Line kGliss1; // Line to slide frequency // harmonics -Oscil aCos0(SIN8192_DATA); -Oscil aCos1(SIN8192_DATA); +Oscil aCos0(SIN8192_DATA); +Oscil aCos1(SIN8192_DATA); // volume envelope oscils Oscil kVol0(TRIANGLE512_DATA); diff --git a/examples/12.Misc/Stereo/Stereo.ino b/examples/12.Misc/Stereo/Stereo.ino index a7869dd91..6452b55c2 100644 --- a/examples/12.Misc/Stereo/Stereo.ino +++ b/examples/12.Misc/Stereo/Stereo.ino @@ -25,7 +25,7 @@ #include // table for oscillator // use: Oscil oscilName (wavetable) -Oscil aNoise(PINKNOISE8192_DATA); +Oscil aNoise(PINKNOISE8192_DATA); //Phasor for panning Phasor kPan; // outputs an unsigned long 0-max 32 bit positive number diff --git a/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino index cde41f188..92cfa8ff8 100644 --- a/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino +++ b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino @@ -28,7 +28,7 @@ #include // sine table for pan oscillator // use: Oscil oscilName (wavetable) -Oscil aNoise(PINKNOISE8192_DATA); +Oscil aNoise(PINKNOISE8192_DATA); Oscil kPan(SIN2048_DATA); diff --git a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino index a94de3927..4fa2cbd5a 100644 --- a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino +++ b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino @@ -45,8 +45,8 @@ // which is an adapted fork from https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx (Thomas Backman) // Synthesis part -Oscil aCarrier(COS2048_DATA); -Oscil aModulator(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); Oscil kModIndex(COS2048_DATA); diff --git a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino index 4fba5178f..33ca3e5e7 100644 --- a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino +++ b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino @@ -61,8 +61,8 @@ // which is an adapted fork from https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx (Thomas Backman) // Synthesis part -Oscil aCos1(COS2048_DATA); -Oscil aCos2(COS2048_DATA); +Oscil aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); Oscil kEnv1(COS2048_DATA); diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino index ab5ba44da..25a5c4277 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino @@ -39,8 +39,8 @@ // Synthesis part -Oscil aCos1(COS2048_DATA); -Oscil aCos2(COS2048_DATA); +Oscil aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); Oscil kEnv1(COS2048_DATA); Oscil kEnv2(COS2048_DATA); diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino index a7752a0c9..a65a9b788 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino @@ -35,8 +35,8 @@ #include // Synthesis part -Oscil aCos1(COS2048_DATA); -Oscil aCos2(COS2048_DATA); +Oscil aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); Oscil kEnv1(COS2048_DATA); Oscil kEnv2(COS2048_DATA); diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino index 13aaf7e74..a1b0553ab 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino @@ -49,7 +49,7 @@ #include // sine table for oscillator // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // External output parameters for this example #define R2R_N_PIN MOZZI_AUDIO_BITS // Number of stage of the resistance ladder = number of digits of the DAC, can be defined through MOZZI_AUDIO_BITS diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino index 71d919dd1..f728e31d8 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino @@ -55,7 +55,7 @@ #include // needed for the shift register // use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // External output parameters for this example #define LATCH_PIN 31 // Number of stage of the resistance ladder = number of digits of the DAC diff --git a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino index b8b7030c9..e24ab2d81 100644 --- a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino +++ b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino @@ -41,8 +41,8 @@ // Synthesis part -Oscil aCos1(COS2048_DATA); -Oscil aCos2(COS2048_DATA); +Oscil aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); Oscil kEnv1(COS2048_DATA); Oscil kEnv2(COS2048_DATA); diff --git a/extras/NEWS.txt b/extras/NEWS.txt index 6cc2ec4b5..47bf201fa 100644 --- a/extras/NEWS.txt +++ b/extras/NEWS.txt @@ -243,7 +243,7 @@ version_2013-08-25-18:38 - examples/envelopes/ADSR_Envelope - now plays random envelopes as a more thorough test/demo. - add examples/envelopes/ADSR_Envelope_x2 - shows an additive sound combining 2 oscillators with individual envelopes. - Sample.h - added linear interpolation as optional template parameter, eg.: - Sample aSample(SAMPLE_DATA); + Sample aSample(SAMPLE_DATA); The default parameter is INTERP_NONE. - removed examples/08.Samples/Sample_Offset too horrible - added examples/08.Samples/Sample_Scrub...uses interpolation/smoothing at different scales @@ -386,7 +386,7 @@ Version_0.01.1z This will re-enable the Arduino time functions delay() and delayMicroseconds() while paused. - Added unPauseMozzi(), allowing Mozzi to continue again after being paused. - added mozziMicros(), a replacement for Arduino micros(). -- mozzi_config.h - AUDIO_RATE is now a configuration option which can be defined as 16384 (default) or 32768. +- mozzi_config.h - MOZZI_AUDIO_RATE is now a configuration option which can be defined as 16384 (default) or 32768. 16384 obviously allows more time for each sample to be calculated, but the higher rate may be useful in some situations (experimental). - AudioDelayFeedback.h diff --git a/extras/python/char2mozzi.py b/extras/python/char2mozzi.py index c85ecd7ef..7c3b3777b 100644 --- a/extras/python/char2mozzi.py +++ b/extras/python/char2mozzi.py @@ -22,7 +22,7 @@ # length. # # For a recorded audio sample, set the project rate to the -# Mozzi AUDIO_RATE (16384 in the current version). +# MOZZI_AUDIO_RATE (16384 in the current version). # Samples can be any length, as long as they fit in your Arduino. # # Save by exporting with the format set to "Other uncompressed formats", diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 44106f44f..08ee5534f 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -142,7 +142,7 @@ AudioOutputStorage_t getAudioInput() { return audio_input; } CircularBuffer input_buffer; // fixed size 256 #define audioInputAvailable() (!input_buffer.isEmpty()) #define readAudioInput() (input_buffer.read()) -/** NOTE: Triggered at AUDIO_RATE via defaultAudioOutput(). In addition to the AUDIO_INPUT_PIN, at most one reading is taken for mozziAnalogRead(). */ +/** NOTE: Triggered at MOZZI_AUDIO_RATE via defaultAudioOutput(). In addition to the AUDIO_INPUT_PIN, at most one reading is taken for mozziAnalogRead(). */ inline void advanceADCStep() { switch (adc_count) { case 0: diff --git a/internal/MozziGuts_impl_AVR.hpp b/internal/MozziGuts_impl_AVR.hpp index 54853880e..a217f6b08 100644 --- a/internal/MozziGuts_impl_AVR.hpp +++ b/internal/MozziGuts_impl_AVR.hpp @@ -181,7 +181,7 @@ static uint8_t mozzi_TCCR4A, mozzi_TCCR4B, mozzi_TCCR4C, mozzi_TCCR4D, static void startAudio() { backupPreMozziTimer1(); Timer1.initializeCPUCycles( - (F_CPU/AUDIO_RATE)-1, // the -1 here is a result of empirical tests + (F_CPU/MOZZI_AUDIO_RATE)-1, // the -1 here is a result of empirical tests // that showed that it brings the resulting frequency // closer to what is expected. // see: https://github.com/sensorium/Mozzi/pull/202 @@ -240,7 +240,7 @@ static void startAudio() { } // namespace MozziPrivate /* Interrupt service routine moves sound data from the output buffer to the -Arduino output register, running at AUDIO_RATE. */ +Arduino output register, running at MOZZI_AUDIO_RATE. */ ISR(TIMER1_OVF_vect, ISR_BLOCK) { # if (MOZZI_AUDIO_RATE < MOZZI_PWM_RATE) // only update every second ISR, if lower audio rate static_assert(2l*MOZZI_AUDIO_RATE == MOZZI_PWM_RATE, "audio rate must the same, or exactly half of the pwm rate!"); diff --git a/internal/MozziGuts_impl_ESP8266.hpp b/internal/MozziGuts_impl_ESP8266.hpp index ce4b8aa05..573dea1ef 100644 --- a/internal/MozziGuts_impl_ESP8266.hpp +++ b/internal/MozziGuts_impl_ESP8266.hpp @@ -71,7 +71,7 @@ inline void audioOutput(const AudioOutput f) { } # else MOZZI_ASSERT_EQUAL(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL) -// NOTE: This intermediate step is needed because the output timer is running at a rate higher than AUDIO_RATE, and we need to rely on the (tiny) +// NOTE: This intermediate step is needed because the output timer is running at a rate higher than MOZZI_AUDIO_RATE, and we need to rely on the (tiny) // serial buffer itself to achieve appropriate rate control void CACHED_FUNCTION_ATTR esp8266_serial_audio_output() { // Note: That unreadble mess is an optimized version of Serial1.availableForWrite() diff --git a/internal/MozziGuts_impl_RP2040.hpp b/internal/MozziGuts_impl_RP2040.hpp index 94a9d52e4..edae67ffe 100644 --- a/internal/MozziGuts_impl_RP2040.hpp +++ b/internal/MozziGuts_impl_RP2040.hpp @@ -148,7 +148,7 @@ inline void audioOutput(const AudioOutput f) { #include namespace MozziPrivate { /** Implementation notes: - * - For the time being this port uses a very crude approach to audio output: PWM updated by a hardware timer running at AUDIO_RATE + * - For the time being this port uses a very crude approach to audio output: PWM updated by a hardware timer running at MOZZI_AUDIO_RATE * - Hardware timer isn't fixed, but rather we claim the first unclaimed one * - Quite pleasently, the RP2040 latches PWM duty cycle, so we do not have to worry about updating whilst in the middle of the previous PWM cycle. * - The more simple add_repeating_timer_us has appers to have far too much jitter diff --git a/internal/MozziGuts_impl_STM32.hpp b/internal/MozziGuts_impl_STM32.hpp index 2542016f8..15d48b77d 100644 --- a/internal/MozziGuts_impl_STM32.hpp +++ b/internal/MozziGuts_impl_STM32.hpp @@ -90,9 +90,9 @@ inline void audioOutput(const AudioOutput f) { static void startAudio() { #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) audio_update_timer.pause(); - //audio_update_timer.setPeriod(1000000UL / AUDIO_RATE); + //audio_update_timer.setPeriod(1000000UL / MOZZI_AUDIO_RATE); // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors - uint32_t period_cyc = F_CPU / AUDIO_RATE; + uint32_t period_cyc = F_CPU / MOZZI_AUDIO_RATE; uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1); uint16_t overflow = (uint16_t)((period_cyc + (prescaler / 2)) / prescaler); audio_update_timer.setPrescaleFactor(prescaler); diff --git a/internal/MozziGuts_impl_STM32duino.hpp b/internal/MozziGuts_impl_STM32duino.hpp index 90452ae21..57a9f9ac2 100644 --- a/internal/MozziGuts_impl_STM32duino.hpp +++ b/internal/MozziGuts_impl_STM32duino.hpp @@ -119,7 +119,7 @@ inline void audioOutput(const AudioOutput f) { static void startAudio() { #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED) audio_update_timer.pause(); - //audio_update_timer.setPeriod(1000000UL / AUDIO_RATE); + //audio_update_timer.setPeriod(1000000UL / MOZZI_AUDIO_RATE); // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors uint32_t period_cyc = F_CPU / MOZZI_AUDIO_RATE; uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1); @@ -142,7 +142,7 @@ static void startAudio() { # endif # define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL)) - // static_assert(MAX_CARRIER_FREQ >= AUDIO_RATE); // Unfortunately, we cannot test this at compile time. F_CPU expands to a runtime variable + // static_assert(MAX_CARRIER_FREQ >= MOZZI_AUDIO_RATE); // Unfortunately, we cannot test this at compile time. F_CPU expands to a runtime variable TIM_TypeDef *pwm_timer_tim = (TIM_TypeDef *) pinmap_peripheral(output_pin_1, PinMap_TIM); pwm_timer_ht = new HardwareTimer(pwm_timer_tim); pwm_timer_ht->setMode(pwm_timer_channel_1, TIMER_OUTPUT_COMPARE_PWM1, output_pin_1); diff --git a/internal/config_checks_esp32.h b/internal/config_checks_esp32.h index e7024ce1a..2108bde9c 100644 --- a/internal/config_checks_esp32.h +++ b/internal/config_checks_esp32.h @@ -81,7 +81,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU #endif #if defined(MOZZI_PWM_RATE) -#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE) #endif #if !defined(MOZZI_ANALOG_READ) diff --git a/internal/config_checks_mbed.h b/internal/config_checks_mbed.h index ea2e84dfc..46c26a288 100644 --- a/internal/config_checks_mbed.h +++ b/internal/config_checks_mbed.h @@ -67,7 +67,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU #endif #if defined(MOZZI_PWM_RATE) -#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE) #endif #if !defined(MOZZI_ANALOG_READ) diff --git a/internal/config_checks_renesas.h b/internal/config_checks_renesas.h index a006c5be5..59f88f94e 100644 --- a/internal/config_checks_renesas.h +++ b/internal/config_checks_renesas.h @@ -46,7 +46,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU #endif #if defined(MOZZI_PWM_RATE) -#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE) #endif #if !defined(MOZZI_ANALOG_READ) diff --git a/internal/config_checks_samd21.h b/internal/config_checks_samd21.h index 1176fb75a..225771ead 100644 --- a/internal/config_checks_samd21.h +++ b/internal/config_checks_samd21.h @@ -46,7 +46,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU #endif #if defined(MOZZI_PWM_RATE) -#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE) #endif #if !defined(MOZZI_ANALOG_READ) diff --git a/internal/config_checks_teensy.h b/internal/config_checks_teensy.h index 875addc18..3358363f5 100644 --- a/internal/config_checks_teensy.h +++ b/internal/config_checks_teensy.h @@ -102,7 +102,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPU #endif #if defined(MOZZI_PWM_RATE) -#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as AUDIO_RATE) +#error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE) #endif #if !defined(MOZZI_ANALOG_READ) diff --git a/utility/FrequencyTimer2.cpp b/utility/FrequencyTimer2.cpp index 6ea71846d..bb29cc9c0 100644 --- a/utility/FrequencyTimer2.cpp +++ b/utility/FrequencyTimer2.cpp @@ -99,7 +99,7 @@ void FrequencyTimer2::setPeriodCPUCycles(unsigned long period){ if ( period <= 256) { pre = 1; top = period-1; - } else if ( period <= 256L*8) { // this for AUDIO_RATE 16384, pre=2 is a bitfield 010 which means prescaler = 8 + } else if ( period <= 256L*8) { // this for MOZZI_AUDIO_RATE 16384, pre=2 is a bitfield 010 which means prescaler = 8 pre = 2; top = period/8-1; } else if ( period <= 256L*32) { @@ -132,7 +132,7 @@ void FrequencyTimer2::setPeriodCPUCycles(unsigned long period){ prescaler *= 2; } - //pre = 4; // this for AUDIO_RATE 16384, pre=4 is a bitfield 100 which means prescaler = 8 + //pre = 4; // this for MOZZI_AUDIO_RATE 16384, pre=4 is a bitfield 100 which means prescaler = 8 //top = period/8-1; #endif From 0f314194a392a1f15451f2c04e7ad8bc7c9a9a1f Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 3 Feb 2024 11:59:51 +0100 Subject: [PATCH 141/215] Fix overflow warning See https://github.com/sensorium/Mozzi/issues/231#issuecomment-1916456675 --- AudioOutput.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioOutput.h b/AudioOutput.h index 52dee31df..88a20e706 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -54,7 +54,7 @@ template constexpr AudioOutputStorage_t SCALE_AUDIO(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS ? (x) >> (bits - MOZZI_AUDIO_BITS) : (x) << (MOZZI_AUDIO_BITS - bits)); } template constexpr AudioOutputStorage_t SCALE_AUDIO_NEAR(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS_OPTIMISTIC ? (x) >> (bits - MOZZI_AUDIO_BITS_OPTIMISTIC) : (x) << (MOZZI_AUDIO_BITS_OPTIMISTIC - bits)); } -template constexpr AudioOutputStorage_t CLIP_AUDIO(T x) { return (constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) MOZZI_AUDIO_BIAS-1)); } +template constexpr AudioOutputStorage_t CLIP_AUDIO(T x) { return (constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) (MOZZI_AUDIO_BIAS-1))); } struct MonoOutput; struct StereoOutput; From 9bbddafcef8b9dc4d5c8fd2b2c21ab36180d160d Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 3 Feb 2024 13:40:55 +0100 Subject: [PATCH 142/215] De-duplicate some info --- internal/config_checks_avr.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index 424eb96fa..a5033c760 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -12,14 +12,17 @@ * flash, RAM, and CPU power. * * @section avr_output Output modes - * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware. In all cases, Timer 1 is claimed, and - * is not available for any other purpose: + * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware: * - MOZZI_OUTPUT_PWM * - MOZZI_OUTPUT_2PIN_PWM * - MOZZI_OUTPUT_EXTERNAL_TIMED * - MOZZI_OUTPUT_EXTERNAL_CUSTOM * - * In all cases, except MOZZI_OUTPUT_EXTERNAL_CUSTOM, Timer 1 is claimed, and is not available for any other purpose. + * In all modes, except MOZZI_OUTPUT_EXTERNAL_CUSTOM, Timer 1 is claimed, and is not available for any other purpose. + * This means, among other things, that pins 9 and 10 cannot be used for analogWrite(), while pins 3 and 11 should still be available + * @em except in MOZZI_OUTPUT_2PIN_PWM mode (as Timer2 is also claimed, then; for definite info on which pin is connected to which timer, + * check a suitable reference, as your board may differ). See *Mozzi>examples>11.Communication>Sinewave_PWM_pins_HIFI*. for an example + * of emulating analogWrite() on any digital pin, without the need for a hardware timer. * * @section avr_pwm MOZZI_OUTPUT_PWM * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured @@ -42,13 +45,7 @@ * * On the downside, this mode requires an extra hardware timer (Timer2 in addition to Timer1), which may increase compatibility * problems with other Arduino libraries that also require a timer. Further, a more elaborate hardware setup is needed, making it less convenient - * for rapid prototyping: - * - * TODO: Move this bit to a dedicated page on output circuits? - * In hardware, add the two signals through a 3.9k resistor on the "high" pin and 499k resistor on "low" pin. - * Use 0.5% resistors or select the most accurate from a batch. It is further recommended to place a 4.7nF capacitor between the summing junction - * of the resistors and ground. This is discussed in much more detail on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ - * Also, there are higher quality output circuits are on the site. + * for rapid prototyping. For circuit details, see https://sensorium.github.io/Mozzi/learn/output/ . * * On the classic Arduino Uno, the default pinout in this mode is: * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW From c403489cd04bdf419a73a567f041cd72341ecd90 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 4 Feb 2024 15:13:52 +0100 Subject: [PATCH 143/215] Next step in decomissioning plain int return values for updateAudio(). This obsoletes AudioOutput_t in new sketches (still supported, with a warning) --- AudioOutput.h | 35 ++++++++----------- MozziGuts.h | 16 +++++---- .../01.Basics/Control_Gain/Control_Gain.ino | 2 +- examples/01.Basics/Sinewave/Sinewave.ino | 2 +- .../01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino | 2 +- examples/01.Basics/Skeleton/Skeleton.ino | 2 +- .../Table_Resolution/Table_Resolution.ino | 2 +- examples/01.Basics/Vibrato/Vibrato.ino | 2 +- .../Control_Echo_Theremin.ino | 2 +- .../Control_Oscil_Wash/Control_Oscil_Wash.ino | 2 +- .../Control_Tremelo/Control_Tremelo.ino | 2 +- examples/02.Control/EventDelay/EventDelay.ino | 2 +- examples/02.Control/Line_Gliss/Line_Gliss.ino | 2 +- .../Line_Gliss_Double_32k_HIFI.ino | 2 +- .../Metronome_SampleHuffman.ino | 2 +- examples/02.Control/Stop_Start/Stop_Start.ino | 2 +- .../Knob_LDR_x2_WavePacket.ino | 2 +- .../Knob_LightLevel_FMsynth.ino | 2 +- .../Knob_LightLevel_x2_FMsynth.ino | 2 +- .../Light_Temperature_Detuned.ino | 2 +- .../Light_Temperature_Multi_Oscil.ino | 2 +- .../Piezo_Frequency/Piezo_Frequency.ino | 2 +- .../Piezo_SampleScrubber.ino | 2 +- .../Piezo_SampleTrigger.ino | 2 +- .../Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino | 2 +- examples/03.Sensors/RCpoll/RCpoll.ino | 2 +- .../Sinewave_Pinchange_Interrupt.ino | 2 +- .../03.Sensors/Volume_Knob/Volume_Knob.ino | 2 +- .../Volume_Knob_LightLevel_Frequency.ino | 2 +- .../Audio_Input/Audio_Input.ino | 2 +- .../Audio_Input_with_Knob_Filter.ino | 2 +- .../Audio_and_Control_Input.ino | 2 +- .../05.Control_Filters/DCfilter/DCfilter.ino | 2 +- .../Line_vs_Smooth/Line_vs_Smooth.ino | 2 +- .../MIDI_portamento/MIDI_portamento.ino | 2 +- .../RollingAverage/RollingAverage.ino | 2 +- examples/05.Control_Filters/Smooth/Smooth.ino | 2 +- .../Smooth_Frequency/Smooth_Frequency.ino | 2 +- .../Thermistor_OverSample.ino | 2 +- examples/06.Synthesis/AMsynth/AMsynth.ino | 2 +- .../AMsynth_HIFI/AMsynth_HIFI.ino | 2 +- .../Brown_Noise_Realtime.ino | 2 +- .../Detuned_Beats_Wash/Detuned_Beats_Wash.ino | 2 +- .../Difference_Tone/Difference_Tone.ino | 2 +- examples/06.Synthesis/FMsynth/FMsynth.ino | 2 +- .../FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino | 2 +- .../NonAlias_MetaOscil/NonAlias_MetaOscil.ino | 2 +- .../06.Synthesis/PDresonant/PDresonant.ino | 2 +- .../06.Synthesis/PWM_Phasing/PWM_Phasing.ino | 2 +- .../06.Synthesis/WaveFolder/WaveFolder.ino | 2 +- .../WavePacket_Double/WavePacket_Double.ino | 2 +- .../WavePacket_Sample/WavePacket_Sample.ino | 2 +- .../WavePacket_Single/WavePacket_Single.ino | 2 +- .../06.Synthesis/Waveshaper/Waveshaper.ino | 2 +- .../ADSR_Audio_Rate_Envelope.ino | 2 +- .../ADSR_Audio_Rate_Envelope_Long.ino | 2 +- .../ADSR_Audio_Rate_Envelope_x2.ino | 2 +- .../ADSR_Control_Rate_Envelope.ino | 2 +- .../Ead_Envelope/Ead_Envelope.ino | 2 +- .../Phasemod_Envelope/Phasemod_Envelope.ino | 2 +- examples/08.Samples/Sample/Sample.ino | 2 +- .../SampleHuffman_Umpah.ino | 2 +- .../Sample_Loop_Points/Sample_Loop_Points.ino | 2 +- .../08.Samples/Sample_Scrub/Sample_Scrub.ino | 2 +- examples/08.Samples/Samples/Samples.ino | 2 +- .../Samples_Tables_Arrays.ino | 2 +- .../Wavetable_Swap/Wavetable_Swap.ino | 2 +- examples/09.Delays/AudioDelay/AudioDelay.ino | 2 +- .../AudioDelayFeedback/AudioDelayFeedback.ino | 2 +- .../AudioDelayFeedbackAllpass.ino | 2 +- .../AudioDelayFeedbackX2.ino | 2 +- .../AudioDelayFeedback_HIFI.ino | 2 +- .../ReverbTank_HIFI/ReverbTank_HIFI.ino | 2 +- .../ReverbTank_STANDARD.ino | 2 +- .../LowPassFilterX2/LowPassFilterX2.ino | 2 +- .../MultiResonantFilter.ino | 4 +-- .../ResonantFilter/ResonantFilter.ino | 2 +- .../ResonantFilter16/ResonantFilter16.ino | 4 +-- .../StateVariableFilter.ino | 2 +- .../StateVariableFilter_HIFI.ino | 2 +- .../Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino | 2 +- .../Mozzi_Processing_Serial.ino | 2 +- .../Sinewave_PWM_leds_HIFI.ino | 2 +- .../Teensy_USB_MIDI_Input.ino | 2 +- .../TwoWire_Read_ADXL345.ino | 2 +- .../12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino | 2 +- .../Risset_Beat_HIFI/Risset_Beat_HIFI.ino | 2 +- .../Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino | 2 +- examples/12.Misc/Stereo/Stereo.ino | 2 +- examples/12.Misc/Stereo_Pan/Stereo_Pan.ino | 2 +- .../FMsynth_MCP4921_mono_12bits.ino | 2 +- .../MCP4922_mono_24bits.ino | 2 +- .../PT8211_stereo_16bits.ino | 2 +- .../PT8211_stereo_16bits_STM32_SPI2.ino | 2 +- .../Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino | 2 +- .../Sinewave_R2R_DAC_74HC595.ino | 2 +- .../Stereo_Pan_MCP4922_stereo_12bits.ino | 2 +- internal/MozziGuts.hpp | 2 +- 98 files changed, 123 insertions(+), 124 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index 88a20e706..252a3076c 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -71,22 +71,15 @@ typedef StereoOutput AudioOutput; typedef MonoOutput AudioOutput; #endif -#if MOZZI_AUDIO_CHANNELS < MOZZI_STEREO -// NOTE / TODO: Unfortunately, for reasons yet to investigate, aliasing to MonoOutput, instead, here, adds a bunch of flash usage -typedef AudioOutputStorage_t AudioOutput_t; // keep sketches using "int updateAudio()" alive +#if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST +#if (MOZZI_COMPATIBILITY_LEVEL <= MOZZI_COMPATIBILITY_1_1) && MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_MONO) +typedef int AudioOutput_t; // Note: Needed for pre 1.1 backwards compatibility #else -/** Representation of an single audio output sample/frame. For mono output, this is really just a single zero-centered int, - * but for stereo it's a struct containing two ints. - * - * While it may be tempting (and is possible) to use an int, directly, using AudioOutput_t and the functions AudioOutput::from8Bit(), - * AudioOutput::fromNBit(), or AudioOutput::fromAlmostNBit() will allow you to write code that will work across different platforms, even - * when those use a different output resolution. - * - * @note The only place where you should be using AudioOutput_t, directly, is in your updateAudio() function signature. It's really just a - * dummy used to make the "same" function signature work across different configurations (importantly mono/stereo). It's true value - * might be subject to change, and it may even be void. Use either MonoOutput or StereoOutput to represent a piece of audio output. - */ -typedef AudioOutput AudioOutput_t; // Note: Needed for pre 1.1 backwards compatibility +/** Transitory alias to AudioOutput. The only point of this typedef is to keep old code working. In new code, + * use AudioOutput, directly, instead. +*/ +MOZZI_DEPRECATED("2.0", "Replace AudioOutput_t with simple AudioOutput") typedef AudioOutput AudioOutput_t; +#endif #endif /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to a single int value, but the struct provides @@ -104,8 +97,10 @@ typedef AudioOutput AudioOutput_t; // Note: Needed for pre 1.1 backwards compat * different configurations. */ struct MonoOutput { + /** Default constructor. Does not initialize the sample! */ + MonoOutput() {}; /** Construct an audio frame from raw values (zero-centered) */ - MonoOutput(AudioOutputStorage_t l=0) : _l(l) {}; + MonoOutput(AudioOutputStorage_t l) : _l(l) {}; #if (MOZZI_AUDIO_CHANNELS > 1) /** Conversion to stereo operator: If used in a stereo config, returns identical channels (and gives a compile time warning). This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time @@ -151,15 +146,15 @@ struct MonoOutput { struct StereoOutput { /** Construct an audio frame from raw values (zero-centered) */ StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r) : _l(l), _r(r) {}; - /** Default contstructor */ - StereoOutput() : _l(0), _r(0) {}; + /** Default constructor. Does not initialize the sample! */ + StereoOutput() {}; #if !MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO) /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning). This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time using StereoOutput in a mono config, is not intended. */ - inline AudioOutput_t portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; }; + inline AudioOutput portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; }; # if GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO - inline operator AudioOutput_t() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; }; + inline operator AudioOutput() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; }; # endif #endif AudioOutputStorage_t l() const { return _l; }; diff --git a/MozziGuts.h b/MozziGuts.h index b0cf0f872..4453ab6fe 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -96,17 +96,21 @@ on which one(s) are required for other tasks. void stopMozzi(); - +#if (MOZZI_COMPATIBILITY_LEVEL <= MOZZI_COMPATIBILITY_1_1) && MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_MONO) +AudioOutput_t updateAudio(); +#else /** @ingroup core This is where you put your audio code. updateAudio() has to keep up with the -MOZZI_AUDIO_RATE of 16384 Hz, so to keep things running smoothly, avoid doing any +MOZZI_AUDIO_RATE of 16384 or 32768 Hz, so to keep things running smoothly, avoid doing any calculations here which could be done in setup() or updateControl(). -@return an audio sample. In STANDARD modes this is between -244 and 243 inclusive. -In HIFI mode, it's a 14 bit number between -16384 and 16383 inclusive. +@return an audio sample. -TODO: Update documentation +While is possible (in mono sketches) to return a plain unscaled int, it is generally best to return +auto-scaled samples using MonoOutput::from8Bit(), MonoOutput::from16Bit(), MonoOutput::fromNbit(), or +their StereoOutput equivalents. */ -AudioOutput_t updateAudio(); +AudioOutput updateAudio(); +#endif /** @ingroup core This is where you put your control code. You need updateControl() somewhere in diff --git a/examples/01.Basics/Control_Gain/Control_Gain.ino b/examples/01.Basics/Control_Gain/Control_Gain.ino index 022d087af..7cf5d5236 100644 --- a/examples/01.Basics/Control_Gain/Control_Gain.ino +++ b/examples/01.Basics/Control_Gain/Control_Gain.ino @@ -40,7 +40,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(aSin.next() * gain); // 8 bits waveform * 8 bits gain makes 16 bits } diff --git a/examples/01.Basics/Sinewave/Sinewave.ino b/examples/01.Basics/Sinewave/Sinewave.ino index 5817edfc7..1f9ada35b 100644 --- a/examples/01.Basics/Sinewave/Sinewave.ino +++ b/examples/01.Basics/Sinewave/Sinewave.ino @@ -35,7 +35,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSin.next()); // return an int signal centred around 0 } diff --git a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino index 0356faa95..945fddf3c 100644 --- a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino +++ b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino @@ -54,7 +54,7 @@ void setup(){ void updateControl(){} -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ // this would make more sense with a higher resolution signal // MonoOutput::from8Bit() (and it friends from16Bit() and fromNBit()) take care of scaling the output signal // as appropiate for the platform (to 14 bits on AVR with AUDIO_MODE HIFI). diff --git a/examples/01.Basics/Skeleton/Skeleton.ino b/examples/01.Basics/Skeleton/Skeleton.ino index 4eaed0282..6a13ee446 100644 --- a/examples/01.Basics/Skeleton/Skeleton.ino +++ b/examples/01.Basics/Skeleton/Skeleton.ino @@ -10,7 +10,7 @@ void updateControl() { // your control code } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { // For mono output, the return value of this function is really just a signed integer. // However, for best portability of your sketch to different boards and configurations, // pick one of the variants below, depending on the "natural" range of the audio values diff --git a/examples/01.Basics/Table_Resolution/Table_Resolution.ino b/examples/01.Basics/Table_Resolution/Table_Resolution.ino index 9ce59b6be..4c6e0804e 100644 --- a/examples/01.Basics/Table_Resolution/Table_Resolution.ino +++ b/examples/01.Basics/Table_Resolution/Table_Resolution.ino @@ -85,7 +85,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig; switch (whose_turn) { case 0: diff --git a/examples/01.Basics/Vibrato/Vibrato.ino b/examples/01.Basics/Vibrato/Vibrato.ino index 9266d737c..d57807644 100644 --- a/examples/01.Basics/Vibrato/Vibrato.ino +++ b/examples/01.Basics/Vibrato/Vibrato.ino @@ -39,7 +39,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ Q15n16 vibrato = (Q15n16) intensity * aVibrato.next(); return MonoOutput::from8Bit(aCos.phMod(vibrato)); // phase modulation to modulate frequency } diff --git a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino index fb7ff6c53..47d1626e6 100644 --- a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino +++ b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino @@ -66,7 +66,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::fromAlmostNBit(12, 3*((int)aSin0.next()+aSin1.next()+(aSin2.next()>>1) +(aSin3.next()>>2)) diff --git a/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino b/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino index b3411ec98..a5e8c5f0e 100644 --- a/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino +++ b/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino @@ -93,7 +93,7 @@ void updateControl(){ v8 = kVol8.next(); } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ long asig = (long) aCos1.next()*v1 + aCos2.next()*v2 + diff --git a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino index c5ee73acd..aa2576107 100644 --- a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino +++ b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino @@ -51,7 +51,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ // cast to long before multiply to give room for intermediate result, // and also before shift, // to give consistent results for both 8 and 32 bit processors. diff --git a/examples/02.Control/EventDelay/EventDelay.ino b/examples/02.Control/EventDelay/EventDelay.ino index efd683171..f3c3dc74a 100644 --- a/examples/02.Control/EventDelay/EventDelay.ino +++ b/examples/02.Control/EventDelay/EventDelay.ino @@ -49,7 +49,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return AudioOutput::from8Bit(aSin.next()*gain); } diff --git a/examples/02.Control/Line_Gliss/Line_Gliss.ino b/examples/02.Control/Line_Gliss/Line_Gliss.ino index 03ce20304..6914a5d85 100644 --- a/examples/02.Control/Line_Gliss/Line_Gliss.ino +++ b/examples/02.Control/Line_Gliss/Line_Gliss.ino @@ -85,7 +85,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ aSaw.setPhaseInc(aGliss.next()); return MonoOutput::from8Bit(aSaw.next()); } diff --git a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino index 720fc799d..198f3276e 100644 --- a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino +++ b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino @@ -134,7 +134,7 @@ void updateControl(){ // 900 us floats vs 160 fixed } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ aSaw1.setPhaseInc(aGliss1.next()); aSaw2.setPhaseInc(aGliss2.next()); return MonoOutput::fromNBit(9, (int)aSaw1.next()+aSaw2.next()); diff --git a/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino b/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino index 8be25c49c..a3664d628 100644 --- a/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino +++ b/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino @@ -74,7 +74,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig = (int) thumb0.next() + thumb1.next() + diff --git a/examples/02.Control/Stop_Start/Stop_Start.ino b/examples/02.Control/Stop_Start/Stop_Start.ino index 678874410..6fe0b2af6 100644 --- a/examples/02.Control/Stop_Start/Stop_Start.ino +++ b/examples/02.Control/Stop_Start/Stop_Start.ino @@ -48,7 +48,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return MonoOutput::from8Bit(aSin.next()); } diff --git a/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino b/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino index 8f8b2e235..4be6ea6b8 100644 --- a/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino +++ b/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino @@ -103,7 +103,7 @@ void updateControl(){ -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(wavey.next()); } diff --git a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino index 37464d972..0ac2b9ab0 100644 --- a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino @@ -97,7 +97,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ long modulation = fm_intensity * aModulator.next(); return MonoOutput::from8Bit(aCarrier.phMod(modulation)); // phMod does the FM } diff --git a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino index 4c334b3d4..6aba9b6cf 100644 --- a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino @@ -129,7 +129,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next(); return MonoOutput::from8Bit(aCarrier.phMod(modulation)); } diff --git a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino index daf34d8e0..5d051071b 100644 --- a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino +++ b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino @@ -152,7 +152,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig = aCos1.next() + aCos1b.next() + diff --git a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino index c81a0fd3d..48b84aafb 100644 --- a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino +++ b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino @@ -160,7 +160,7 @@ void updateControl(){ -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ long asig = (long) aCos0.next()*v0 + aCos1.next()*v1 + diff --git a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino index 36701c674..1ff0e0e48 100644 --- a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino +++ b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino @@ -68,7 +68,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSin.next()); } diff --git a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino index d09e6d0ff..bcbfddc4c 100644 --- a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino +++ b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino @@ -70,7 +70,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSample.atIndex(Q16n16_to_Q16n0(scrub.next()))); } diff --git a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino index 1a79547a6..2adffe0ef 100644 --- a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino +++ b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino @@ -84,7 +84,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSample.next()); } diff --git a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino index 64efdd7e0..4dded0b8f 100644 --- a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino +++ b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino @@ -104,7 +104,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSample.next()); } diff --git a/examples/03.Sensors/RCpoll/RCpoll.ino b/examples/03.Sensors/RCpoll/RCpoll.ino index ef74b3ab6..9ed0741b6 100644 --- a/examples/03.Sensors/RCpoll/RCpoll.ino +++ b/examples/03.Sensors/RCpoll/RCpoll.ino @@ -65,7 +65,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSin.next()); } diff --git a/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino b/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino index 00081e910..fb75a7f74 100644 --- a/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino +++ b/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino @@ -70,7 +70,7 @@ void changeFreq() -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSin.next()); // return an int signal centred around 0 } diff --git a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino index 4a159a87d..fd21e715f 100644 --- a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino +++ b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino @@ -65,7 +65,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit((int)aSin.next() * volume); // 8 bit * 8 bit gives 16 bits value } diff --git a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino index 71d1cc1c9..98a9d7bd2 100644 --- a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino +++ b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino @@ -82,7 +82,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ // cast char output from aSin.next() to int to make room for multiplication return MonoOutput::from16Bit((int)aSin.next() * volume); // 8 bit * 8 bit gives 16 bits value } diff --git a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino index 5ca020913..a0dba9cce 100644 --- a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino +++ b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino @@ -32,7 +32,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig = getAudioInput(); // range 0-1023 asig = asig - 512; // now range is -512 to 511 // output range in STANDARD mode is -244 to 243, diff --git a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino index d8a991925..8c87b88ef 100644 --- a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino +++ b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino @@ -50,7 +50,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ // subtracting 512 moves the unsigned audio data into 0-centred, // signed range required by all Mozzi units int asig = getAudioInput()-512; diff --git a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino index ed7493616..a7bf65823 100644 --- a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino +++ b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino @@ -51,7 +51,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig = getAudioInput(); // range 0-1023 asig = asig - 512; // now range is -512 to 511 return MonoOutput::fromAlmostNBit(9, asig).clip(); diff --git a/examples/05.Control_Filters/DCfilter/DCfilter.ino b/examples/05.Control_Filters/DCfilter/DCfilter.ino index b1df39c9a..7569cfd6b 100644 --- a/examples/05.Control_Filters/DCfilter/DCfilter.ino +++ b/examples/05.Control_Filters/DCfilter/DCfilter.ino @@ -40,7 +40,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return 0; } diff --git a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino index 5f824ce25..4d88d3c3e 100644 --- a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino +++ b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino @@ -75,7 +75,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ Q16n16 interpolatedFreq = aInterpolate.next(); // get the next linear interpolated freq aSin0.setFreq_Q16n16(interpolatedFreq); diff --git a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino index ac9761f23..d7eefb57b 100644 --- a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino +++ b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino @@ -87,7 +87,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit((int) (envelope.next() * aSin.next())); } diff --git a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino index c181384dd..a9d58d7f0 100644 --- a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino +++ b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino @@ -55,7 +55,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::fromAlmostNBit(10, 3*(aSin0.next()+aSin1.next())); } diff --git a/examples/05.Control_Filters/Smooth/Smooth.ino b/examples/05.Control_Filters/Smooth/Smooth.ino index e4e63c83a..118f11960 100644 --- a/examples/05.Control_Filters/Smooth/Smooth.ino +++ b/examples/05.Control_Filters/Smooth/Smooth.ino @@ -73,7 +73,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(aSmoothGain.next(target_gain) * aSin.next()); } diff --git a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino index f24d5a7e9..31b1a5293 100644 --- a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino +++ b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino @@ -59,7 +59,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSin.next()); } diff --git a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino index 29ac13e35..8ca4aa52f 100644 --- a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino +++ b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino @@ -108,7 +108,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit((((int)aSin.next()*(128+aTremelo.next()))>>8)*aEnvelope.next()); } diff --git a/examples/06.Synthesis/AMsynth/AMsynth.ino b/examples/06.Synthesis/AMsynth/AMsynth.ino index 42b587a69..b98892600 100644 --- a/examples/06.Synthesis/AMsynth/AMsynth.ino +++ b/examples/06.Synthesis/AMsynth/AMsynth.ino @@ -99,7 +99,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ long mod = (128u+ aModulator.next()) * ((byte)128+ aModDepth.next()); return MonoOutput::fromNBit(24, mod * aCarrier.next()); } diff --git a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino index 49de5bd70..0ccc9139b 100644 --- a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino +++ b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino @@ -120,7 +120,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ unsigned int mod = (128u+ aModulator.next()) * ((byte)128+ aModDepth.next()); return MonoOutput::fromNBit(24, (long)mod * aCarrier.next()); // 16 bit * 8 bit = 24 bit } diff --git a/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino b/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino index bcae5eafa..d8d61e210 100644 --- a/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino +++ b/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino @@ -41,7 +41,7 @@ void updateControl() } -AudioOutput_t updateAudio() +AudioOutput updateAudio() { static int filtered; diff --git a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino index c9f6d1b0c..e2691238a 100644 --- a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino +++ b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino @@ -141,7 +141,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig = aCos1.next() + aCos1b.next() + diff --git a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino index b33a8732f..c9d53c769 100644 --- a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino +++ b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino @@ -59,7 +59,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig = (int)((((uint32_t)aSin1.next()+ aSin2.next())*(200u+aGain.next()))>>3); return MonoOutput::fromAlmostNBit(9, asig).clip(); } diff --git a/examples/06.Synthesis/FMsynth/FMsynth.ino b/examples/06.Synthesis/FMsynth/FMsynth.ino index c2a23d8e5..c3425186b 100644 --- a/examples/06.Synthesis/FMsynth/FMsynth.ino +++ b/examples/06.Synthesis/FMsynth/FMsynth.ino @@ -108,7 +108,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ Q15n16 modulation = deviation * aModulator.next() >> 8; return MonoOutput::from8Bit(aCarrier.phMod(modulation)); } diff --git a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino index d7c6016da..ee7a9bc50 100644 --- a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino +++ b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino @@ -132,7 +132,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ Q15n16 modulation = deviation * aModulator.next() >> 8; return MonoOutput::from8Bit(aCarrier.phMod(modulation)); // Internally still only 8 bits, will be shifted up to 14 bits in HIFI mode } diff --git a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino index 36e24282f..f352e1869 100644 --- a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino +++ b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino @@ -107,7 +107,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { //return MonoOutput::from8Bit(aSq90.next()); // try to use this line instead to hear the non-band limited version, sounds a bit like a radio return MonoOutput::from8Bit(BL_aSq.next()); // return a sample of the correct oscil to acheive no alias diff --git a/examples/06.Synthesis/PDresonant/PDresonant.ino b/examples/06.Synthesis/PDresonant/PDresonant.ino index a00702add..3b78b47d8 100644 --- a/examples/06.Synthesis/PDresonant/PDresonant.ino +++ b/examples/06.Synthesis/PDresonant/PDresonant.ino @@ -132,7 +132,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(voice.next()); } diff --git a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino index 3e176a45a..ebfeac61a 100644 --- a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino +++ b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino @@ -40,7 +40,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ char asig1 = (char)(aPhasor1.next()>>24); char asig2 = (char)(aPhasor2.next()>>24); return MonoOutput::fromNBit(9, ((int)asig1-asig2)); diff --git a/examples/06.Synthesis/WaveFolder/WaveFolder.ino b/examples/06.Synthesis/WaveFolder/WaveFolder.ino index fef66257d..4846a0987 100644 --- a/examples/06.Synthesis/WaveFolder/WaveFolder.ino +++ b/examples/06.Synthesis/WaveFolder/WaveFolder.ino @@ -49,7 +49,7 @@ void updateControl() { gain = (kGain.next()>>1)+64; } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { int sample = (gain * aSin.next() >> 1) + (bias<<4); // this is 8 + 7 - 1 + 1 = 15bits maximum. // the wavefolder, set on an output of 12 bits will fold the exceeding values. return MonoOutput::fromNBit(12, wf.next(sample)); // return an int signal centred around 0 diff --git a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino index 1c8d0be93..4d1638599 100644 --- a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino +++ b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino @@ -59,7 +59,7 @@ void updateControl(){ -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(wavey.next()); } diff --git a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino index 116e69593..d85114b07 100644 --- a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino +++ b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino @@ -67,7 +67,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(wavey.next()); } diff --git a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino index ad8eed2d1..6e58e4d7b 100644 --- a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino +++ b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino @@ -60,7 +60,7 @@ void updateControl(){ -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(wavey.next()); } diff --git a/examples/06.Synthesis/Waveshaper/Waveshaper.ino b/examples/06.Synthesis/Waveshaper/Waveshaper.ino index f30d12007..dfff9408b 100644 --- a/examples/06.Synthesis/Waveshaper/Waveshaper.ino +++ b/examples/06.Synthesis/Waveshaper/Waveshaper.ino @@ -97,7 +97,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ char asig0 = aSin.next(); // sine wave source // make 2 signals fading in and out to show effect of amplitude when waveshaping with Chebyshev polynomial curves // offset the signals by 128 to fit in the 0-255 range for the waveshaping table lookups diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino index df479c90b..aa6399814 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino @@ -98,7 +98,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ envelope.update(); return MonoOutput::from16Bit((int) (envelope.next() * aOscil.next())); } diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino index 85d792f6c..25a99fc98 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino @@ -101,7 +101,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ envelope.update(); return MonoOutput::from16Bit((int) (envelope.next() * aOscil.next())); } diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino index 04bcf72d6..c2ddb70dc 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino @@ -171,7 +171,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::fromNBit(17, ((long)envelope0.next() * aOscil0.next()) + ((int)envelope1.next() * aOscil1.next()) diff --git a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino index 0ef779b01..23d4d239f 100644 --- a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino @@ -96,7 +96,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit((int) (gain * aOscil.next())); } diff --git a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino index c73781482..2fa6c7282 100644 --- a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino +++ b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino @@ -53,7 +53,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(gain*aNoise.next()); } diff --git a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino index afd5b109a..91112482a 100644 --- a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino +++ b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino @@ -44,7 +44,7 @@ void updateControl() { } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig = aCarrier.phMod((int)aModulator.next()*(260u+aModWidth.next())); return MonoOutput::from16Bit(asig*(byte)aEnvelop.next()); } diff --git a/examples/08.Samples/Sample/Sample.ino b/examples/08.Samples/Sample/Sample.ino index e0693232c..f173846d8 100644 --- a/examples/08.Samples/Sample/Sample.ino +++ b/examples/08.Samples/Sample/Sample.ino @@ -43,7 +43,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit((int) aSample.next()); } diff --git a/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino b/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino index 9958e7584..eb2606e43 100644 --- a/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino +++ b/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino @@ -57,7 +57,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(umpah.next()); } diff --git a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino index 9be5cbe51..f765bd863 100644 --- a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino +++ b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino @@ -98,7 +98,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSample.next()); } diff --git a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino index fe9c4507a..5f04f8060 100644 --- a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino +++ b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino @@ -67,7 +67,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ unsigned int index = Q16n16_to_Q16n0(scrub.next()); return MonoOutput::from8Bit(aSample.atIndex(index)); } diff --git a/examples/08.Samples/Samples/Samples.ino b/examples/08.Samples/Samples/Samples.ino index 42aca1388..832de43ea 100644 --- a/examples/08.Samples/Samples/Samples.ino +++ b/examples/08.Samples/Samples/Samples.ino @@ -79,7 +79,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig= (int) ((long) aBamboo0.next()*gains.gain0 + aBamboo1.next()*gains.gain1 + diff --git a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino index 817e73e59..e5083a68c 100644 --- a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino +++ b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino @@ -111,7 +111,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ long asig=0; for (byte i=0;i>8)); } diff --git a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino index bb588a394..902a2e861 100644 --- a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino +++ b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino @@ -61,7 +61,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ char asig1 = aTriangle1.next(); // get this so it can be used twice without calling next() again int aflange1 = (asig1>>3) + aDel1.next(asig1, del_samps1); // mix some straignt signal with the delayed signal diff --git a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino index 8b870b077..04244e36b 100644 --- a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino +++ b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino @@ -80,7 +80,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ char asig = aTriangle.next(); // get this so it can be used twice without calling next() again //return asig/8 + aDel.next(asig, del_samps); // mix some straight signal with the delayed signal //return aDel.next(aTriangle.next(), del_samps); // instead of the previous 2 lines for only the delayed signal diff --git a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino index 2253f4336..b623f6aed 100644 --- a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino +++ b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino @@ -58,7 +58,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int synth = aCarrier.phMod((int)aModulator.next()*(150u+aModWidth.next())); synth *= (byte)aEnvelop.next(); // here's the reverb diff --git a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino index b3284698d..8b30f6f10 100644 --- a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino +++ b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino @@ -58,7 +58,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int synth = aCarrier.phMod((int)aModulator.next()*(150u+aModWidth.next())); synth *= (byte)aEnvelop.next(); synth >>= 8; diff --git a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino index a6a833e30..4cf2cfa6d 100644 --- a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino +++ b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino @@ -53,7 +53,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::fromAlmostNBit(9, (((char)lpf1.next(aCrunchySound1.next()))>>1) + (char)lpf2.next(aCrunchySound2.next())); } diff --git a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino index 0a61cc58a..93cf0f698 100644 --- a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino +++ b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino @@ -65,8 +65,8 @@ void updateControl() { mf.setCutoffFreqAndResonance(cutoff_freq, resonance); } -AudioOutput_t updateAudio() { - AudioOutput_t asig; +AudioOutput updateAudio() { + AudioOutput asig; mf.next(aCrunchySound.next()); // this send the current sample to the filter, does not return anything switch (filter_type) // recover the output from the current selected filter type. { diff --git a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino index 3f61f30a8..c0e6299f8 100644 --- a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino +++ b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino @@ -57,7 +57,7 @@ void updateControl(){ rf.setCutoffFreqAndResonance(cutoff_freq, resonance); } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ char asig = rf.next(aCrunchySound.next()); return MonoOutput::from8Bit(asig); } diff --git a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino index fc571a1d5..63baff038 100644 --- a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino +++ b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino @@ -63,7 +63,7 @@ void updateControl(){ rf.setCutoffFreqAndResonance(cutoff_freq, resonance); } -AudioOutput_t updateAudio(){ - AudioOutput_t asig = rf.next(aCrunchySound.next()); +AudioOutput updateAudio(){ + AudioOutput asig = rf.next(aCrunchySound.next()); return MonoOutput::from8Bit(asig); } diff --git a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino index acc5226f7..d34746d1d 100644 --- a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino +++ b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino @@ -49,7 +49,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ // watch output levels, they can distort if too high // also, at very resonant settings, the input signal may need attenuating return MonoOutput::fromAlmostNBit(12, svf.next(aNoise.next())); diff --git a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino index b780566e8..a498c45ad 100644 --- a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino +++ b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino @@ -61,7 +61,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int input = aNoise.next()>>1; // shift down (ie. fast /) to avoid distortion with extreme resonant filter setting int output = svf.next(input); return MonoOutput::fromNBit(10, output); diff --git a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino index 127719c4b..92839b042 100644 --- a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino +++ b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino @@ -73,7 +73,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(envelope.next() * aSin.next()); } diff --git a/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino b/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino index bc6f62806..30de4e825 100644 --- a/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino +++ b/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino @@ -43,7 +43,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aSin.next()); } diff --git a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino index ed4bd2fae..225fe286c 100644 --- a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino +++ b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino @@ -108,7 +108,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ updateRGB(red_brightness, green_brightness, blue_brightness); // this would make more sense with a higher resolution signal // but still benefits from using HIFI to avoid the 16kHz pwm noise diff --git a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino index 66356d589..2a5069416 100644 --- a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino +++ b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino @@ -72,7 +72,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(envelope.next() * aSin.next()); } diff --git a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino index 2b4364431..48b293610 100644 --- a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino +++ b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino @@ -192,7 +192,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(aSin.next()*gain); } diff --git a/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino b/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino index d94d66d11..561f50676 100644 --- a/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino +++ b/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino @@ -219,7 +219,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { int32_t asig = aSmoothLevel.next(k_leveltarget) * wavey.next(); return MonoOutput::fromNBit(23, asig); // avoid distortion } diff --git a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino index 82c2d9448..2079be8cc 100644 --- a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino +++ b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino @@ -100,7 +100,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return MonoOutput::fromNBit(17, ((long)aSample0.next() * alevel0) + ((long)aSample1.next() * alevel1)); } diff --git a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino index 512c44383..2500ea881 100644 --- a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino +++ b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino @@ -125,7 +125,7 @@ void updateControl() { v1 *= v1; } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { long asig = ((v0 * aCos0.next()) >> 8) + ((v1 * aCos1.next()) >> 8); return AudioOutput::fromNBit(17, asig); diff --git a/examples/12.Misc/Stereo/Stereo.ino b/examples/12.Misc/Stereo/Stereo.ino index 6452b55c2..14cfcd562 100644 --- a/examples/12.Misc/Stereo/Stereo.ino +++ b/examples/12.Misc/Stereo/Stereo.ino @@ -45,7 +45,7 @@ void updateControl(){ Serial.println(pan); } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ int asig = aNoise.next(); return StereoOutput::fromNBit(24, (long)pan*asig, (long)(65535-pan)*asig); } diff --git a/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino index 92cfa8ff8..42f454d1d 100644 --- a/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino +++ b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino @@ -56,7 +56,7 @@ void updateControl() } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { int asig = aNoise.next(); return StereoOutput::from16Bit(asig*ampA, asig*ampB); } diff --git a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino index 4fa2cbd5a..5d16b2c52 100644 --- a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino +++ b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino @@ -134,7 +134,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { Q15n16 modulation = deviation * aModulator.next() >> 8; return MonoOutput::from8Bit(aCarrier.phMod(modulation)); diff --git a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino index 33ca3e5e7..d49ed5bed 100644 --- a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino +++ b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino @@ -114,7 +114,7 @@ void updateControl() { -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return MonoOutput::fromNBit(24, (int32_t)aCos1.next() * aCos2.next() * env1) ; // specify that the audio we are sending here is 24 bits. } diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino index 25a5c4277..b481cd5c7 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino @@ -95,7 +95,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return StereoOutput::from16Bit(aCos1.next() * env1, aCos2.next() * env2); } diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino index a65a9b788..2a901d90e 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino @@ -90,7 +90,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return StereoOutput::from16Bit(aCos1.next() * env1, aCos2.next() * env2); } diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino index a1b0553ab..b438cb57f 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino @@ -83,7 +83,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return MonoOutput::from8Bit(aSin.next()); // return an int signal centred around 0, 8bits wide } diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino index f728e31d8..9fdb979ab 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino @@ -84,7 +84,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return MonoOutput::from8Bit(aSin.next()); // return an int signal centred around 0, 8bits wide } diff --git a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino index e24ab2d81..f6fb405b9 100644 --- a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino +++ b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino @@ -92,7 +92,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return StereoOutput::fromNBit(12, aCos1.next() * env1, aCos2.next() * env2); } diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 08ee5534f..53b7251ae 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -75,7 +75,7 @@ inline void bufferAudioOutput(const AudioOutput_t f) { ++samples_written_to_buffer; } #else -CircularBuffer output_buffer; // fixed size 256 +CircularBuffer output_buffer; // fixed size 256 # define canBufferAudioOutput() (!output_buffer.isFull()) # define bufferAudioOutput(f) output_buffer.write(f) static void CACHED_FUNCTION_ATTR defaultAudioOutput() { From a3cb043fcf9bdc92e5b2c32c6850cdb8afa3ed72 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 8 Feb 2024 21:53:18 +0100 Subject: [PATCH 144/215] Do not encourage non-power-of-two MOZZI_CONTROL_RATE settings in examples. --- examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino index 1ff0e0e48..8a0aed82d 100644 --- a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino +++ b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino @@ -27,7 +27,7 @@ */ // increase the rate of updateControl from the default of 64, to catch the piezo's rapid transients -#define MOZZI_CONTROL_RATE 150 +#define MOZZI_CONTROL_RATE 128 #include #include // oscillator #include // table for Oscils to play @@ -41,8 +41,8 @@ Oscil aSin(SIN2048_DATA); void setup(){ //Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches - Serial.begin(115200); // set up the Serial output so we can look at the piezo values // set up the Serial output so we can look at the piezo values - startMozzi(); // :)) use the control rate defined above + Serial.begin(115200); // set up the Serial output so we can look at the piezo values + startMozzi(); // :)) uses the control rate defined above } From 7cad50ddd20ee4c8053fae22794ca5ad595f4c15 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Tue, 13 Feb 2024 16:43:48 +0100 Subject: [PATCH 145/215] Mass remove legacy inclusion of WProgram.h --- ADSR.h | 6 +----- AudioDelayFeedback.h | 6 +----- AutoMap.h | 6 +----- Line.h | 6 +----- MetaOscil.h | 6 +----- examples/03.Sensors/Piezo_SampleScrubber/blahblah4b_int8.h | 6 +----- examples/08.Samples/SampleHuffman_Umpah/umpah_huff.h | 6 +----- examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h | 6 +----- extras/python/audio2huff.py | 5 +---- extras/python/char2mozzi.py | 6 +----- extras/python/chebyshev_int8.py | 6 +----- extras/python/float2mozzi.py | 6 +----- extras/python/float2mozzi_uint8.py | 6 +----- extras/python/sin1024_int8.py | 6 +----- extras/python/sin8192_uint8.py | 6 +----- extras/python/sin_multi_levels_int8.py | 6 +----- extras/python/table_generator_template.py | 6 +----- extras/python/triangle.py | 6 +----- mozzi_fixmath.h | 6 +----- mozzi_utils.h | 6 +----- samples/abomb16384_int8.h | 6 +----- samples/bamboo/bamboo_00_2048_int8.h | 6 +----- samples/bamboo/bamboo_00_4096_int8.h | 6 +----- samples/bamboo/bamboo_01_2048_int8.h | 6 +----- samples/bamboo/bamboo_01_4096_int8.h | 6 +----- samples/bamboo/bamboo_02_2048_int8.h | 6 +----- samples/bamboo/bamboo_02_4096_int8.h | 6 +----- samples/bamboo/bamboo_03_2048_int8.h | 6 +----- samples/bamboo/bamboo_03_4096_int8.h | 6 +----- samples/bamboo/bamboo_04_2048_int8.h | 6 +----- samples/bamboo/bamboo_04_4096_int8.h | 6 +----- samples/bamboo/bamboo_05_2048_int8.h | 6 +----- samples/bamboo/bamboo_05_4096_int8.h | 6 +----- samples/bamboo/bamboo_06_2048_int8.h | 6 +----- samples/bamboo/bamboo_07_2048_int8.h | 6 +----- samples/bamboo/bamboo_08_2048_int8.h | 6 +----- samples/bamboo/bamboo_09_2048_int8.h | 6 +----- samples/bamboo/bamboo_10_2048_int8.h | 6 +----- samples/burroughs1_18649_int8.h | 6 +----- samples/empty_0_int8.h | 6 +----- samples/raven_arh_int8.h | 6 +----- samples/thumbpiano_huffman/thumbpiano0.h | 6 +----- samples/thumbpiano_huffman/thumbpiano1.h | 6 +----- samples/thumbpiano_huffman/thumbpiano2.h | 6 +----- samples/thumbpiano_huffman/thumbpiano3.h | 6 +----- samples/thumbpiano_huffman/thumbpiano4.h | 6 +----- .../BandLimited_SAW/1024/saw_max_1024_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_1170_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_1365_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_136_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_138_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_141_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_143_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_146_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_148_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_151_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_154_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_157_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_160_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_1638_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_163_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_167_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_170_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_174_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_178_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_182_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_186_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_190_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_195_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_199_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_2048_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_204_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_210_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_215_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_221_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_227_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_234_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_240_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_248_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_256_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_264_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_2730_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_273_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_282_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_292_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_303_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_315_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_327_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_341_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_356_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_372_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_390_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_4096_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_409_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_431_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_455_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_481_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_512_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_546_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_585_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_630_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_682_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_744_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_8192_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_819_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/1024/saw_max_910_at_16384_1024_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_1024_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_1170_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_1365_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_136_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_138_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_141_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_143_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_146_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_148_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_151_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_154_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_157_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_160_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_1638_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_163_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_167_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_170_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_174_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_178_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_182_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_186_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_190_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_195_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_199_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_2048_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_204_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_210_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_215_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_221_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_227_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_234_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_240_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_248_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_256_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_264_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_2730_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_273_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_282_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_292_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_303_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_315_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_327_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_341_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_356_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_372_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_390_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_4096_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_409_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_431_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_455_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_481_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_512_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_546_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_585_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_630_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_682_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_744_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_8192_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_819_at_16384_2048_int8.h | 6 +----- .../BandLimited_SAW/2048/saw_max_910_at_16384_2048_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_1024_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_1170_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_1365_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_136_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_138_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_141_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_143_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_146_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_148_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_151_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_154_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_157_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_160_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_1638_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_163_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_167_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_170_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_174_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_178_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_182_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_186_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_190_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_195_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_199_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_2048_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_204_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_210_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_215_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_221_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_227_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_234_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_240_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_248_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_256_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_264_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_2730_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_273_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_282_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_292_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_303_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_315_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_327_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_341_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_356_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_372_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_390_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_4096_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_409_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_431_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_455_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_481_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_512_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_546_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_585_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_630_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_682_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_744_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_8192_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_819_at_16384_512_int8.h | 6 +----- tables/BandLimited_SAW/512/saw_max_910_at_16384_512_int8.h | 6 +----- .../1024/square_max_101_at_16384_1024_int8.h | 6 +----- .../1024/square_max_103_at_16384_1024_int8.h | 6 +----- .../1024/square_max_106_at_16384_1024_int8.h | 6 +----- .../1024/square_max_109_at_16384_1024_int8.h | 6 +----- .../1024/square_max_112_at_16384_1024_int8.h | 6 +----- .../1024/square_max_115_at_16384_1024_int8.h | 6 +----- .../1024/square_max_1170_at_16384_1024_int8.h | 6 +----- .../1024/square_max_118_at_16384_1024_int8.h | 6 +----- .../1024/square_max_122_at_16384_1024_int8.h | 6 +----- .../1024/square_max_126_at_16384_1024_int8.h | 6 +----- .../1024/square_max_130_at_16384_1024_int8.h | 6 +----- .../1024/square_max_134_at_16384_1024_int8.h | 6 +----- .../1024/square_max_138_at_16384_1024_int8.h | 6 +----- .../1024/square_max_143_at_16384_1024_int8.h | 6 +----- .../1024/square_max_148_at_16384_1024_int8.h | 6 +----- .../1024/square_max_154_at_16384_1024_int8.h | 6 +----- .../1024/square_max_160_at_16384_1024_int8.h | 6 +----- .../1024/square_max_1638_at_16384_1024_int8.h | 6 +----- .../1024/square_max_167_at_16384_1024_int8.h | 6 +----- .../1024/square_max_174_at_16384_1024_int8.h | 6 +----- .../1024/square_max_182_at_16384_1024_int8.h | 6 +----- .../1024/square_max_190_at_16384_1024_int8.h | 6 +----- .../1024/square_max_199_at_16384_1024_int8.h | 6 +----- .../1024/square_max_210_at_16384_1024_int8.h | 6 +----- .../1024/square_max_221_at_16384_1024_int8.h | 6 +----- .../1024/square_max_234_at_16384_1024_int8.h | 6 +----- .../1024/square_max_248_at_16384_1024_int8.h | 6 +----- .../1024/square_max_264_at_16384_1024_int8.h | 6 +----- .../1024/square_max_2730_at_16384_1024_int8.h | 6 +----- .../1024/square_max_282_at_16384_1024_int8.h | 6 +----- .../1024/square_max_303_at_16384_1024_int8.h | 6 +----- .../1024/square_max_327_at_16384_1024_int8.h | 6 +----- .../1024/square_max_356_at_16384_1024_int8.h | 6 +----- .../1024/square_max_390_at_16384_1024_int8.h | 6 +----- .../1024/square_max_431_at_16384_1024_int8.h | 6 +----- .../1024/square_max_481_at_16384_1024_int8.h | 6 +----- .../1024/square_max_546_at_16384_1024_int8.h | 6 +----- .../1024/square_max_630_at_16384_1024_int8.h | 6 +----- .../1024/square_max_68_at_16384_1024_int8.h | 6 +----- .../1024/square_max_70_at_16384_1024_int8.h | 6 +----- .../1024/square_max_71_at_16384_1024_int8.h | 6 +----- .../1024/square_max_72_at_16384_1024_int8.h | 6 +----- .../1024/square_max_73_at_16384_1024_int8.h | 6 +----- .../1024/square_max_744_at_16384_1024_int8.h | 6 +----- .../1024/square_max_75_at_16384_1024_int8.h | 6 +----- .../1024/square_max_76_at_16384_1024_int8.h | 6 +----- .../1024/square_max_78_at_16384_1024_int8.h | 6 +----- .../1024/square_max_79_at_16384_1024_int8.h | 6 +----- .../1024/square_max_8192_at_16384_1024_int8.h | 6 +----- .../1024/square_max_81_at_16384_1024_int8.h | 6 +----- .../1024/square_max_82_at_16384_1024_int8.h | 6 +----- .../1024/square_max_84_at_16384_1024_int8.h | 6 +----- .../1024/square_max_86_at_16384_1024_int8.h | 6 +----- .../1024/square_max_88_at_16384_1024_int8.h | 6 +----- .../1024/square_max_90_at_16384_1024_int8.h | 6 +----- .../1024/square_max_910_at_16384_1024_int8.h | 6 +----- .../1024/square_max_92_at_16384_1024_int8.h | 6 +----- .../1024/square_max_94_at_16384_1024_int8.h | 6 +----- .../1024/square_max_96_at_16384_1024_int8.h | 6 +----- .../1024/square_max_98_at_16384_1024_int8.h | 6 +----- .../2048/square_max_101_at_16384_2048_int8.h | 6 +----- .../2048/square_max_103_at_16384_2048_int8.h | 6 +----- .../2048/square_max_106_at_16384_2048_int8.h | 6 +----- .../2048/square_max_109_at_16384_2048_int8.h | 6 +----- .../2048/square_max_112_at_16384_2048_int8.h | 6 +----- .../2048/square_max_115_at_16384_2048_int8.h | 6 +----- .../2048/square_max_1170_at_16384_2048_int8.h | 6 +----- .../2048/square_max_118_at_16384_2048_int8.h | 6 +----- .../2048/square_max_122_at_16384_2048_int8.h | 6 +----- .../2048/square_max_126_at_16384_2048_int8.h | 6 +----- .../2048/square_max_130_at_16384_2048_int8.h | 6 +----- .../2048/square_max_134_at_16384_2048_int8.h | 6 +----- .../2048/square_max_138_at_16384_2048_int8.h | 6 +----- .../2048/square_max_143_at_16384_2048_int8.h | 6 +----- .../2048/square_max_148_at_16384_2048_int8.h | 6 +----- .../2048/square_max_154_at_16384_2048_int8.h | 6 +----- .../2048/square_max_160_at_16384_2048_int8.h | 6 +----- .../2048/square_max_1638_at_16384_2048_int8.h | 6 +----- .../2048/square_max_167_at_16384_2048_int8.h | 6 +----- .../2048/square_max_174_at_16384_2048_int8.h | 6 +----- .../2048/square_max_182_at_16384_2048_int8.h | 6 +----- .../2048/square_max_190_at_16384_2048_int8.h | 6 +----- .../2048/square_max_199_at_16384_2048_int8.h | 6 +----- .../2048/square_max_210_at_16384_2048_int8.h | 6 +----- .../2048/square_max_221_at_16384_2048_int8.h | 6 +----- .../2048/square_max_234_at_16384_2048_int8.h | 6 +----- .../2048/square_max_248_at_16384_2048_int8.h | 6 +----- .../2048/square_max_264_at_16384_2048_int8.h | 6 +----- .../2048/square_max_2730_at_16384_2048_int8.h | 6 +----- .../2048/square_max_282_at_16384_2048_int8.h | 6 +----- .../2048/square_max_303_at_16384_2048_int8.h | 6 +----- .../2048/square_max_327_at_16384_2048_int8.h | 6 +----- .../2048/square_max_356_at_16384_2048_int8.h | 6 +----- .../2048/square_max_390_at_16384_2048_int8.h | 6 +----- .../2048/square_max_431_at_16384_2048_int8.h | 6 +----- .../2048/square_max_481_at_16384_2048_int8.h | 6 +----- .../2048/square_max_546_at_16384_2048_int8.h | 6 +----- .../2048/square_max_630_at_16384_2048_int8.h | 6 +----- .../2048/square_max_68_at_16384_2048_int8.h | 6 +----- .../2048/square_max_70_at_16384_2048_int8.h | 6 +----- .../2048/square_max_71_at_16384_2048_int8.h | 6 +----- .../2048/square_max_72_at_16384_2048_int8.h | 6 +----- .../2048/square_max_73_at_16384_2048_int8.h | 6 +----- .../2048/square_max_744_at_16384_2048_int8.h | 6 +----- .../2048/square_max_75_at_16384_2048_int8.h | 6 +----- .../2048/square_max_76_at_16384_2048_int8.h | 6 +----- .../2048/square_max_78_at_16384_2048_int8.h | 6 +----- .../2048/square_max_79_at_16384_2048_int8.h | 6 +----- .../2048/square_max_8192_at_16384_2048_int8.h | 6 +----- .../2048/square_max_81_at_16384_2048_int8.h | 6 +----- .../2048/square_max_82_at_16384_2048_int8.h | 6 +----- .../2048/square_max_84_at_16384_2048_int8.h | 6 +----- .../2048/square_max_86_at_16384_2048_int8.h | 6 +----- .../2048/square_max_88_at_16384_2048_int8.h | 6 +----- .../2048/square_max_90_at_16384_2048_int8.h | 6 +----- .../2048/square_max_910_at_16384_2048_int8.h | 6 +----- .../2048/square_max_92_at_16384_2048_int8.h | 6 +----- .../2048/square_max_94_at_16384_2048_int8.h | 6 +----- .../2048/square_max_96_at_16384_2048_int8.h | 6 +----- .../2048/square_max_98_at_16384_2048_int8.h | 6 +----- .../512/square_max_101_at_16384_512_int8.h | 6 +----- .../512/square_max_103_at_16384_512_int8.h | 6 +----- .../512/square_max_106_at_16384_512_int8.h | 6 +----- .../512/square_max_109_at_16384_512_int8.h | 6 +----- .../512/square_max_112_at_16384_512_int8.h | 6 +----- .../512/square_max_115_at_16384_512_int8.h | 6 +----- .../512/square_max_1170_at_16384_512_int8.h | 6 +----- .../512/square_max_118_at_16384_512_int8.h | 6 +----- .../512/square_max_122_at_16384_512_int8.h | 6 +----- .../512/square_max_126_at_16384_512_int8.h | 6 +----- .../512/square_max_130_at_16384_512_int8.h | 6 +----- .../512/square_max_134_at_16384_512_int8.h | 6 +----- .../512/square_max_138_at_16384_512_int8.h | 6 +----- .../512/square_max_143_at_16384_512_int8.h | 6 +----- .../512/square_max_148_at_16384_512_int8.h | 6 +----- .../512/square_max_154_at_16384_512_int8.h | 6 +----- .../512/square_max_160_at_16384_512_int8.h | 6 +----- .../512/square_max_1638_at_16384_512_int8.h | 6 +----- .../512/square_max_167_at_16384_512_int8.h | 6 +----- .../512/square_max_174_at_16384_512_int8.h | 6 +----- .../512/square_max_182_at_16384_512_int8.h | 6 +----- .../512/square_max_190_at_16384_512_int8.h | 6 +----- .../512/square_max_199_at_16384_512_int8.h | 6 +----- .../512/square_max_210_at_16384_512_int8.h | 6 +----- .../512/square_max_221_at_16384_512_int8.h | 6 +----- .../512/square_max_234_at_16384_512_int8.h | 6 +----- .../512/square_max_248_at_16384_512_int8.h | 6 +----- .../512/square_max_264_at_16384_512_int8.h | 6 +----- .../512/square_max_2730_at_16384_512_int8.h | 6 +----- .../512/square_max_282_at_16384_512_int8.h | 6 +----- .../512/square_max_303_at_16384_512_int8.h | 6 +----- .../512/square_max_327_at_16384_512_int8.h | 6 +----- .../512/square_max_356_at_16384_512_int8.h | 6 +----- .../512/square_max_390_at_16384_512_int8.h | 6 +----- .../512/square_max_431_at_16384_512_int8.h | 6 +----- .../512/square_max_481_at_16384_512_int8.h | 6 +----- .../512/square_max_546_at_16384_512_int8.h | 6 +----- .../512/square_max_630_at_16384_512_int8.h | 6 +----- .../512/square_max_68_at_16384_512_int8.h | 6 +----- .../512/square_max_70_at_16384_512_int8.h | 6 +----- .../512/square_max_71_at_16384_512_int8.h | 6 +----- .../512/square_max_72_at_16384_512_int8.h | 6 +----- .../512/square_max_73_at_16384_512_int8.h | 6 +----- .../512/square_max_744_at_16384_512_int8.h | 6 +----- .../512/square_max_75_at_16384_512_int8.h | 6 +----- .../512/square_max_76_at_16384_512_int8.h | 6 +----- .../512/square_max_78_at_16384_512_int8.h | 6 +----- .../512/square_max_79_at_16384_512_int8.h | 6 +----- .../512/square_max_8192_at_16384_512_int8.h | 6 +----- .../512/square_max_81_at_16384_512_int8.h | 6 +----- .../512/square_max_82_at_16384_512_int8.h | 6 +----- .../512/square_max_84_at_16384_512_int8.h | 6 +----- .../512/square_max_86_at_16384_512_int8.h | 6 +----- .../512/square_max_88_at_16384_512_int8.h | 6 +----- .../512/square_max_90_at_16384_512_int8.h | 6 +----- .../512/square_max_910_at_16384_512_int8.h | 6 +----- .../512/square_max_92_at_16384_512_int8.h | 6 +----- .../512/square_max_94_at_16384_512_int8.h | 6 +----- .../512/square_max_96_at_16384_512_int8.h | 6 +----- .../512/square_max_98_at_16384_512_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_103_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_106_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_109_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_112_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_115_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_1170_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_118_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_122_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_126_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_130_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_134_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_138_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_143_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_148_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_154_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_160_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_1638_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_167_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_174_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_182_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_190_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_199_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_210_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_221_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_234_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_248_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_264_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_2730_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_282_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_303_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_327_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_356_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_390_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_431_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_481_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_546_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_630_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_744_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_8192_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/1024/tri_max_910_at_16384_1024_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_103_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_106_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_109_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_112_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_115_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_1170_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_118_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_122_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_126_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_130_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_134_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_138_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_143_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_148_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_154_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_160_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_1638_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_167_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_174_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_182_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_190_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_199_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_210_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_221_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_234_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_248_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_264_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_2730_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_282_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_303_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_327_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_356_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_390_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_431_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_481_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_546_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_630_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_744_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_8192_at_16384_2048_int8.h | 6 +----- .../BandLimited_TRI/2048/tri_max_910_at_16384_2048_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_103_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_106_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_109_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_112_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_115_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_1170_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_118_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_122_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_126_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_130_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_134_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_138_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_143_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_148_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_154_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_160_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_1638_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_167_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_174_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_182_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_190_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_199_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_210_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_221_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_234_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_248_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_264_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_2730_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_282_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_303_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_327_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_356_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_390_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_431_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_481_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_546_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_630_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_744_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_8192_at_16384_512_int8.h | 6 +----- tables/BandLimited_TRI/512/tri_max_910_at_16384_512_int8.h | 6 +----- tables/brownnoise8192_int8.h | 6 +----- tables/chum78_int8.h | 6 +----- tables/chum9_int8.h | 6 +----- tables/cos1024_int8.h | 6 +----- tables/cos2048_int8.h | 6 +----- tables/cos256_int8.h | 6 +----- tables/cos4096_int16.h | 6 +----- tables/cos4096_int8.h | 6 +----- tables/cos512_int8.h | 6 +----- tables/cos8192_int8.h | 6 +----- tables/cosphase2048_int8.h | 6 +----- tables/cosphase256_int8.h | 6 +----- tables/cosphase8192_int8.h | 6 +----- tables/envelop2048_uint8.h | 6 +----- tables/halfsin256_uint8.h | 6 +----- tables/halfsinwindow512_uint8.h | 6 +----- tables/noise_static_1_16384_int8.h | 6 +----- tables/phasor256_int8.h | 6 +----- tables/pinknoise8192_int8.h | 6 +----- tables/saw1024_int8.h | 6 +----- tables/saw2048_int8.h | 6 +----- tables/saw256_int8.h | 6 +----- tables/saw4096_int8.h | 6 +----- tables/saw512_int8.h | 6 +----- tables/saw8192_int8.h | 6 +----- tables/saw_analogue512_int8.h | 6 +----- tables/sin1024_int8.h | 6 +----- tables/sin1024_uint8.h | 6 +----- tables/sin2048_int8.h | 6 +----- tables/sin256_int8.h | 6 +----- tables/sin4096_int8.h | 6 +----- tables/sin512_int8.h | 6 +----- tables/sin8192_int8.h | 6 +----- tables/sin8192_uint8.h | 6 +----- tables/sintest_int8.h | 6 +----- tables/smoothsquare8192_int8.h | 6 +----- tables/square_analogue512_int8.h | 6 +----- tables/square_no_alias512_int8.h | 6 +----- tables/square_no_alias_2048_int8.h | 6 +----- tables/triangle1024_int8.h | 6 +----- tables/triangle2048_int8.h | 6 +----- tables/triangle512_int8.h | 6 +----- tables/triangle_analogue512_int8.h | 6 +----- tables/triangle_dist_cubed_2048_int8.h | 6 +----- tables/triangle_dist_squared_2048_int8.h | 6 +----- tables/triangle_hermes_2048_int8.h | 6 +----- tables/triangle_valve_2048_int8.h | 6 +----- tables/triangle_valve_2_2048_int8.h | 6 +----- tables/triangle_warm8192_int8.h | 6 +----- tables/uphasor256_uint8.h | 6 +----- tables/waveshape1_softclip_int8.h | 6 +----- tables/waveshape2_softerclip_int8.h | 6 +----- tables/waveshape_chebyshev_3rd_256_int8.h | 6 +----- tables/waveshape_chebyshev_4th_256_int8.h | 6 +----- tables/waveshape_chebyshev_5th_256_int8.h | 6 +----- tables/waveshape_chebyshev_6th_256_int8.h | 6 +----- tables/waveshape_compress_512_to_488_int16.h | 6 +----- tables/waveshape_sigmoid_int8.h | 6 +----- tables/waveshape_tanh_int8.h | 6 +----- tables/whitenoise8192_int8.h | 6 +----- utility/FrequencyTimer2.h | 6 +----- 587 files changed, 587 insertions(+), 2934 deletions(-) diff --git a/ADSR.h b/ADSR.h index 0e07b82d2..2e38a3548 100644 --- a/ADSR.h +++ b/ADSR.h @@ -12,11 +12,7 @@ #ifndef ADSR_H_ #define ADSR_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "Line.h" #include "mozzi_fixmath.h" diff --git a/AudioDelayFeedback.h b/AudioDelayFeedback.h index 98945e4ec..a5f3a01b0 100644 --- a/AudioDelayFeedback.h +++ b/AudioDelayFeedback.h @@ -12,11 +12,7 @@ #ifndef AUDIODELAY_FEEDBACK_H_ #define AUDIODELAY_FEEDBACK_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_utils.h" #include "meta.h" diff --git a/AutoMap.h b/AutoMap.h index 9e2bec1c3..c58e19989 100644 --- a/AutoMap.h +++ b/AutoMap.h @@ -13,11 +13,7 @@ #define AUTOMAP_H_ // for map - maybe rewrite my own templated map for better efficiency -#if ARDUINO >= 100 - #include "Arduino.h" // for map -#else - #include "WProgram.h" -#endif +#include // for map #include "AutoRange.h" diff --git a/Line.h b/Line.h index f433907d3..e330b73df 100644 --- a/Line.h +++ b/Line.h @@ -12,11 +12,7 @@ #ifndef LINE_H_ #define LINE_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include /** For linear changes with a minimum of calculation at each step. For instance, you can use Line to make an oscillator glide from one frequency to another, diff --git a/MetaOscil.h b/MetaOscil.h index 702441e32..dfd7deaf3 100644 --- a/MetaOscil.h +++ b/MetaOscil.h @@ -10,11 +10,7 @@ #define META_OSCIL_H -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "Oscil.h" #include "mozzi_fixmath.h" diff --git a/examples/03.Sensors/Piezo_SampleScrubber/blahblah4b_int8.h b/examples/03.Sensors/Piezo_SampleScrubber/blahblah4b_int8.h index a0bf4f0a1..264bd2f7d 100644 --- a/examples/03.Sensors/Piezo_SampleScrubber/blahblah4b_int8.h +++ b/examples/03.Sensors/Piezo_SampleScrubber/blahblah4b_int8.h @@ -1,11 +1,7 @@ #ifndef BLAHBLAH4B_H_ #define BLAHBLAH4B_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BLAHBLAH4B_NUM_CELLS 22569 diff --git a/examples/08.Samples/SampleHuffman_Umpah/umpah_huff.h b/examples/08.Samples/SampleHuffman_Umpah/umpah_huff.h index 9fd4cd24a..266884c83 100644 --- a/examples/08.Samples/SampleHuffman_Umpah/umpah_huff.h +++ b/examples/08.Samples/SampleHuffman_Umpah/umpah_huff.h @@ -3,11 +3,7 @@ #ifndef UMPAH_H_ #define UMPAH_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h b/examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h index 8812bb118..bd3d3e7c4 100644 --- a/examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h +++ b/examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE512_H_ #define TRIANGLE512_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define TRIANGLE512_NUM_CELLS 512 diff --git a/extras/python/audio2huff.py b/extras/python/audio2huff.py index 40a865d67..3eb55cd49 100644 --- a/extras/python/audio2huff.py +++ b/extras/python/audio2huff.py @@ -124,10 +124,7 @@ def arrayformatter(seq,perline=40): print >>hdrf,"#ifndef " + options.name + "_H_" print >>hdrf,"#define " + options.name + "_H_\n" print >>hdrf,'#if ARDUINO >= 100' - print >>hdrf,'#include "Arduino.h"' - print >>hdrf,'#else' - print >>hdrf,'#include "WProgram.h"' - print >>hdrf,'#endif \n' + print >>hdrf,'#include \n' print >>hdrf,'#include "mozzi_pgmspace.h"\n \n' print >>hdrf,"#define " + options.name + "_SAMPLERATE %i"%fs print >>hdrf,"#define " + options.name + "_SAMPLE_BITS %i"%options.bits diff --git a/extras/python/char2mozzi.py b/extras/python/char2mozzi.py index 7c3b3777b..d3a3ba838 100644 --- a/extras/python/char2mozzi.py +++ b/extras/python/char2mozzi.py @@ -56,11 +56,7 @@ def char2mozzi(infile, outfile, tablename, samplerate): fout = open(os.path.expanduser(outfile), "w") fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n') fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n') diff --git a/extras/python/chebyshev_int8.py b/extras/python/chebyshev_int8.py index 8f1a92737..5c758996f 100644 --- a/extras/python/chebyshev_int8.py +++ b/extras/python/chebyshev_int8.py @@ -37,11 +37,7 @@ def chebyTable(outfile, tablename, tablelength, curvenum): fout = open(os.path.expanduser(outfile), "w") fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength) +'\n') outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {' diff --git a/extras/python/float2mozzi.py b/extras/python/float2mozzi.py index 1fcc4564e..23dae650e 100644 --- a/extras/python/float2mozzi.py +++ b/extras/python/float2mozzi.py @@ -27,11 +27,7 @@ def float2mozzi(infile, outfile, tablename,samplerate): fout = open(os.path.expanduser(outfile), "w") fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n') fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n') diff --git a/extras/python/float2mozzi_uint8.py b/extras/python/float2mozzi_uint8.py index 7b899c0fb..060b88ac0 100644 --- a/extras/python/float2mozzi_uint8.py +++ b/extras/python/float2mozzi_uint8.py @@ -21,11 +21,7 @@ def float2mozzi_uint8(infile, outfile, tablename,samplerate): fout = open(os.path.expanduser(outfile), "w") fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n') fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n') diff --git a/extras/python/sin1024_int8.py b/extras/python/sin1024_int8.py index 0246a9642..aa263d856 100644 --- a/extras/python/sin1024_int8.py +++ b/extras/python/sin1024_int8.py @@ -10,11 +10,7 @@ def generate(outfile, tablename, tablelength, samplerate): fout = open(os.path.expanduser(outfile), "w") fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n') fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n') diff --git a/extras/python/sin8192_uint8.py b/extras/python/sin8192_uint8.py index 08784813a..863a6e9ee 100644 --- a/extras/python/sin8192_uint8.py +++ b/extras/python/sin8192_uint8.py @@ -10,11 +10,7 @@ def generate(outfile, tablename, tablelength, samplerate): fout = open(os.path.expanduser(outfile), "w") fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n') fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n') diff --git a/extras/python/sin_multi_levels_int8.py b/extras/python/sin_multi_levels_int8.py index 20b8b7939..93c1c1162 100644 --- a/extras/python/sin_multi_levels_int8.py +++ b/extras/python/sin_multi_levels_int8.py @@ -12,11 +12,7 @@ def generate(outfile, tablename, tablelength, numtables): fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength) +'\n') fout.write('CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = { \n') diff --git a/extras/python/table_generator_template.py b/extras/python/table_generator_template.py index e90423fc8..ae3b74db6 100644 --- a/extras/python/table_generator_template.py +++ b/extras/python/table_generator_template.py @@ -7,11 +7,7 @@ def generate(outfile, tablename, tablelength, samplerate): fout = open(os.path.expanduser(outfile), "w") fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n') fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n') diff --git a/extras/python/triangle.py b/extras/python/triangle.py index 5013e5af1..b1efb5014 100644 --- a/extras/python/triangle.py +++ b/extras/python/triangle.py @@ -7,11 +7,7 @@ def generate(outfile, tablename, tablelength, samplerate): fout = open(os.path.expanduser(outfile), "w") fout.write('#ifndef ' + tablename + '_H_' + '\n') fout.write('#define ' + tablename + '_H_' + '\n \n') - fout.write('#if ARDUINO >= 100'+'\n') - fout.write('#include "Arduino.h"'+'\n') - fout.write('#else'+'\n') - fout.write('#include "WProgram.h"'+'\n') - fout.write('#endif'+'\n') + fout.write('#include '+'\n') fout.write('#include "mozzi_pgmspace.h"'+'\n \n') fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n') fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n') diff --git a/mozzi_fixmath.h b/mozzi_fixmath.h index b2f1574ed..b6c6da905 100644 --- a/mozzi_fixmath.h +++ b/mozzi_fixmath.h @@ -12,11 +12,7 @@ #ifndef FIXEDMATH_H_ #define FIXEDMATH_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include /** @defgroup fixmath Fast integer based fixed-point arithmetic */ diff --git a/mozzi_utils.h b/mozzi_utils.h index a21f4b03b..018f91e5e 100644 --- a/mozzi_utils.h +++ b/mozzi_utils.h @@ -3,11 +3,7 @@ #define UTILS_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "hardware_defines.h" diff --git a/samples/abomb16384_int8.h b/samples/abomb16384_int8.h index 313f31508..d6cd3c5e2 100644 --- a/samples/abomb16384_int8.h +++ b/samples/abomb16384_int8.h @@ -1,11 +1,7 @@ #ifndef ABOMB_H_ #define ABOMB_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define ABOMB_NUM_CELLS 16384 diff --git a/samples/bamboo/bamboo_00_2048_int8.h b/samples/bamboo/bamboo_00_2048_int8.h index fddeed9c0..434327fd1 100644 --- a/samples/bamboo/bamboo_00_2048_int8.h +++ b/samples/bamboo/bamboo_00_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_00_2048_H_ #define BAMBOO_00_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_00_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_00_4096_int8.h b/samples/bamboo/bamboo_00_4096_int8.h index 7be4856a7..7054638e1 100644 --- a/samples/bamboo/bamboo_00_4096_int8.h +++ b/samples/bamboo/bamboo_00_4096_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_00_4096_H_ #define BAMBOO_00_4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_00_4096_NUM_CELLS 4096 diff --git a/samples/bamboo/bamboo_01_2048_int8.h b/samples/bamboo/bamboo_01_2048_int8.h index 2cd5f28d2..1594ed29c 100644 --- a/samples/bamboo/bamboo_01_2048_int8.h +++ b/samples/bamboo/bamboo_01_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_01_2048_H_ #define BAMBOO_01_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_01_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_01_4096_int8.h b/samples/bamboo/bamboo_01_4096_int8.h index 08ca2805d..700f86894 100644 --- a/samples/bamboo/bamboo_01_4096_int8.h +++ b/samples/bamboo/bamboo_01_4096_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_01_4096_H_ #define BAMBOO_01_4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_01_4096_NUM_CELLS 4096 diff --git a/samples/bamboo/bamboo_02_2048_int8.h b/samples/bamboo/bamboo_02_2048_int8.h index 2b3f5a016..35c8bf612 100644 --- a/samples/bamboo/bamboo_02_2048_int8.h +++ b/samples/bamboo/bamboo_02_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_02_2048_H_ #define BAMBOO_02_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_02_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_02_4096_int8.h b/samples/bamboo/bamboo_02_4096_int8.h index cd7195330..218c15333 100644 --- a/samples/bamboo/bamboo_02_4096_int8.h +++ b/samples/bamboo/bamboo_02_4096_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_02_4096_H_ #define BAMBOO_02_4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_02_4096_NUM_CELLS 4096 diff --git a/samples/bamboo/bamboo_03_2048_int8.h b/samples/bamboo/bamboo_03_2048_int8.h index f73745986..72bee01ab 100644 --- a/samples/bamboo/bamboo_03_2048_int8.h +++ b/samples/bamboo/bamboo_03_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_03_2048_H_ #define BAMBOO_03_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_03_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_03_4096_int8.h b/samples/bamboo/bamboo_03_4096_int8.h index a6af1d446..0e5c5ec34 100644 --- a/samples/bamboo/bamboo_03_4096_int8.h +++ b/samples/bamboo/bamboo_03_4096_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_03_4096_H_ #define BAMBOO_03_4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_03_4096_NUM_CELLS 4096 diff --git a/samples/bamboo/bamboo_04_2048_int8.h b/samples/bamboo/bamboo_04_2048_int8.h index a0b0f74e5..a11122729 100644 --- a/samples/bamboo/bamboo_04_2048_int8.h +++ b/samples/bamboo/bamboo_04_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_04_2048_H_ #define BAMBOO_04_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_04_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_04_4096_int8.h b/samples/bamboo/bamboo_04_4096_int8.h index b559b1492..de4949af6 100644 --- a/samples/bamboo/bamboo_04_4096_int8.h +++ b/samples/bamboo/bamboo_04_4096_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_04_4096_H_ #define BAMBOO_04_4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_04_4096_NUM_CELLS 4096 diff --git a/samples/bamboo/bamboo_05_2048_int8.h b/samples/bamboo/bamboo_05_2048_int8.h index a73444a20..9051ced2b 100644 --- a/samples/bamboo/bamboo_05_2048_int8.h +++ b/samples/bamboo/bamboo_05_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_05_2048_H_ #define BAMBOO_05_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_05_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_05_4096_int8.h b/samples/bamboo/bamboo_05_4096_int8.h index 42ea4a3be..796f22b2d 100644 --- a/samples/bamboo/bamboo_05_4096_int8.h +++ b/samples/bamboo/bamboo_05_4096_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_05_4096_H_ #define BAMBOO_05_4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_05_4096_NUM_CELLS 4096 diff --git a/samples/bamboo/bamboo_06_2048_int8.h b/samples/bamboo/bamboo_06_2048_int8.h index ead7b0a81..4166ec094 100644 --- a/samples/bamboo/bamboo_06_2048_int8.h +++ b/samples/bamboo/bamboo_06_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_06_2048_H_ #define BAMBOO_06_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_06_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_07_2048_int8.h b/samples/bamboo/bamboo_07_2048_int8.h index ebf5ea2b1..a70e8e6ec 100644 --- a/samples/bamboo/bamboo_07_2048_int8.h +++ b/samples/bamboo/bamboo_07_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_07_2048_H_ #define BAMBOO_07_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_07_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_08_2048_int8.h b/samples/bamboo/bamboo_08_2048_int8.h index 9973d2e0b..73d523894 100644 --- a/samples/bamboo/bamboo_08_2048_int8.h +++ b/samples/bamboo/bamboo_08_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_08_2048_H_ #define BAMBOO_08_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_08_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_09_2048_int8.h b/samples/bamboo/bamboo_09_2048_int8.h index d9bab92e8..c48b531e7 100644 --- a/samples/bamboo/bamboo_09_2048_int8.h +++ b/samples/bamboo/bamboo_09_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_09_2048_H_ #define BAMBOO_09_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_09_2048_NUM_CELLS 2048 diff --git a/samples/bamboo/bamboo_10_2048_int8.h b/samples/bamboo/bamboo_10_2048_int8.h index 9ba7dba5a..8ca432d7a 100644 --- a/samples/bamboo/bamboo_10_2048_int8.h +++ b/samples/bamboo/bamboo_10_2048_int8.h @@ -1,11 +1,7 @@ #ifndef BAMBOO_10_2048_H_ #define BAMBOO_10_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BAMBOO_10_2048_NUM_CELLS 2048 diff --git a/samples/burroughs1_18649_int8.h b/samples/burroughs1_18649_int8.h index cb8b598b4..109a91451 100644 --- a/samples/burroughs1_18649_int8.h +++ b/samples/burroughs1_18649_int8.h @@ -1,11 +1,7 @@ #ifndef BURROUGHS1_18649_H_ #define BURROUGHS1_18649_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define BURROUGHS1_18649_NUM_CELLS 18649 diff --git a/samples/empty_0_int8.h b/samples/empty_0_int8.h index 719b079ce..dbf5824eb 100644 --- a/samples/empty_0_int8.h +++ b/samples/empty_0_int8.h @@ -1,11 +1,7 @@ #ifndef EMPTY_0_H_ #define EMPTY_0_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define EMPTY_0_NUM_CELLS 0 diff --git a/samples/raven_arh_int8.h b/samples/raven_arh_int8.h index 0342aa0af..37212a823 100644 --- a/samples/raven_arh_int8.h +++ b/samples/raven_arh_int8.h @@ -1,11 +1,7 @@ #ifndef RAVEN_ARH_H_ #define RAVEN_ARH_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define RAVEN_ARH_NUM_CELLS 8192 diff --git a/samples/thumbpiano_huffman/thumbpiano0.h b/samples/thumbpiano_huffman/thumbpiano0.h index 1f9494938..c88998e91 100644 --- a/samples/thumbpiano_huffman/thumbpiano0.h +++ b/samples/thumbpiano_huffman/thumbpiano0.h @@ -3,11 +3,7 @@ #ifndef THUMB0_H_ #define THUMB0_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/samples/thumbpiano_huffman/thumbpiano1.h b/samples/thumbpiano_huffman/thumbpiano1.h index c289f3a58..270f67f9e 100644 --- a/samples/thumbpiano_huffman/thumbpiano1.h +++ b/samples/thumbpiano_huffman/thumbpiano1.h @@ -3,11 +3,7 @@ #ifndef THUMB1_H_ #define THUMB1_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/samples/thumbpiano_huffman/thumbpiano2.h b/samples/thumbpiano_huffman/thumbpiano2.h index 59edc05cd..b9ea62825 100644 --- a/samples/thumbpiano_huffman/thumbpiano2.h +++ b/samples/thumbpiano_huffman/thumbpiano2.h @@ -3,11 +3,7 @@ #ifndef THUMB2_H_ #define THUMB2_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/samples/thumbpiano_huffman/thumbpiano3.h b/samples/thumbpiano_huffman/thumbpiano3.h index 35501fe72..1ccaa6350 100644 --- a/samples/thumbpiano_huffman/thumbpiano3.h +++ b/samples/thumbpiano_huffman/thumbpiano3.h @@ -3,11 +3,7 @@ #ifndef THUMB3_H_ #define THUMB3_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/samples/thumbpiano_huffman/thumbpiano4.h b/samples/thumbpiano_huffman/thumbpiano4.h index d9f57bb4e..82c63d9d0 100644 --- a/samples/thumbpiano_huffman/thumbpiano4.h +++ b/samples/thumbpiano_huffman/thumbpiano4.h @@ -3,11 +3,7 @@ #ifndef THUMB4_H_ #define THUMB4_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_1024_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_1024_at_16384_1024_int8.h index 20cc0c85d..2777614dd 100644 --- a/tables/BandLimited_SAW/1024/saw_max_1024_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_1024_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1024_AT_16384_1024INT8_H_ #define SAW_MAX_1024_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_1170_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_1170_at_16384_1024_int8.h index d3f2039db..dcd8a3ef4 100644 --- a/tables/BandLimited_SAW/1024/saw_max_1170_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_1170_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1170_AT_16384_1024INT8_H_ #define SAW_MAX_1170_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_1365_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_1365_at_16384_1024_int8.h index 1a16ab271..8530c4389 100644 --- a/tables/BandLimited_SAW/1024/saw_max_1365_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_1365_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1365_AT_16384_1024INT8_H_ #define SAW_MAX_1365_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_136_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_136_at_16384_1024_int8.h index 21a648057..e95d9c58a 100644 --- a/tables/BandLimited_SAW/1024/saw_max_136_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_136_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_136_AT_16384_1024INT8_H_ #define SAW_MAX_136_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_138_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_138_at_16384_1024_int8.h index 0fae2044a..1217961b6 100644 --- a/tables/BandLimited_SAW/1024/saw_max_138_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_138_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_138_AT_16384_1024INT8_H_ #define SAW_MAX_138_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_141_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_141_at_16384_1024_int8.h index 713be079c..23105634c 100644 --- a/tables/BandLimited_SAW/1024/saw_max_141_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_141_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_141_AT_16384_1024INT8_H_ #define SAW_MAX_141_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_143_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_143_at_16384_1024_int8.h index eeea202bb..3b47bf9be 100644 --- a/tables/BandLimited_SAW/1024/saw_max_143_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_143_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_143_AT_16384_1024INT8_H_ #define SAW_MAX_143_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_146_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_146_at_16384_1024_int8.h index ec71250d2..22822a469 100644 --- a/tables/BandLimited_SAW/1024/saw_max_146_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_146_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_146_AT_16384_1024INT8_H_ #define SAW_MAX_146_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_148_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_148_at_16384_1024_int8.h index 9482472f2..97f8629a8 100644 --- a/tables/BandLimited_SAW/1024/saw_max_148_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_148_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_148_AT_16384_1024INT8_H_ #define SAW_MAX_148_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_151_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_151_at_16384_1024_int8.h index 7d6f17bd6..2e69b2ee7 100644 --- a/tables/BandLimited_SAW/1024/saw_max_151_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_151_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_151_AT_16384_1024INT8_H_ #define SAW_MAX_151_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_154_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_154_at_16384_1024_int8.h index b626ba85a..7c3bb6976 100644 --- a/tables/BandLimited_SAW/1024/saw_max_154_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_154_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_154_AT_16384_1024INT8_H_ #define SAW_MAX_154_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_157_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_157_at_16384_1024_int8.h index 505ed7c94..17c8bdf5a 100644 --- a/tables/BandLimited_SAW/1024/saw_max_157_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_157_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_157_AT_16384_1024INT8_H_ #define SAW_MAX_157_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_160_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_160_at_16384_1024_int8.h index 0ab690def..3326425bc 100644 --- a/tables/BandLimited_SAW/1024/saw_max_160_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_160_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_160_AT_16384_1024INT8_H_ #define SAW_MAX_160_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_1638_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_1638_at_16384_1024_int8.h index 7c4c0451c..7b1c0355f 100644 --- a/tables/BandLimited_SAW/1024/saw_max_1638_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_1638_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1638_AT_16384_1024INT8_H_ #define SAW_MAX_1638_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_163_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_163_at_16384_1024_int8.h index cf73fa532..ea3111630 100644 --- a/tables/BandLimited_SAW/1024/saw_max_163_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_163_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_163_AT_16384_1024INT8_H_ #define SAW_MAX_163_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_167_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_167_at_16384_1024_int8.h index aa1278d2a..0a1ed45dd 100644 --- a/tables/BandLimited_SAW/1024/saw_max_167_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_167_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_167_AT_16384_1024INT8_H_ #define SAW_MAX_167_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_170_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_170_at_16384_1024_int8.h index cc7fc3cfb..8ebbd5895 100644 --- a/tables/BandLimited_SAW/1024/saw_max_170_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_170_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_170_AT_16384_1024INT8_H_ #define SAW_MAX_170_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_174_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_174_at_16384_1024_int8.h index ddffab01e..fd5f3c47a 100644 --- a/tables/BandLimited_SAW/1024/saw_max_174_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_174_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_174_AT_16384_1024INT8_H_ #define SAW_MAX_174_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_178_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_178_at_16384_1024_int8.h index 070b4966a..b7266e7e3 100644 --- a/tables/BandLimited_SAW/1024/saw_max_178_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_178_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_178_AT_16384_1024INT8_H_ #define SAW_MAX_178_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_182_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_182_at_16384_1024_int8.h index 885f9e2b6..e016858b2 100644 --- a/tables/BandLimited_SAW/1024/saw_max_182_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_182_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_182_AT_16384_1024INT8_H_ #define SAW_MAX_182_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_186_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_186_at_16384_1024_int8.h index 5ec2644da..84170e0db 100644 --- a/tables/BandLimited_SAW/1024/saw_max_186_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_186_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_186_AT_16384_1024INT8_H_ #define SAW_MAX_186_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_190_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_190_at_16384_1024_int8.h index 1ba5a0e24..39716a652 100644 --- a/tables/BandLimited_SAW/1024/saw_max_190_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_190_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_190_AT_16384_1024INT8_H_ #define SAW_MAX_190_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_195_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_195_at_16384_1024_int8.h index 5fe3a201b..11e532f77 100644 --- a/tables/BandLimited_SAW/1024/saw_max_195_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_195_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_195_AT_16384_1024INT8_H_ #define SAW_MAX_195_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_199_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_199_at_16384_1024_int8.h index bb1ae6d72..93d72f262 100644 --- a/tables/BandLimited_SAW/1024/saw_max_199_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_199_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_199_AT_16384_1024INT8_H_ #define SAW_MAX_199_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_2048_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_2048_at_16384_1024_int8.h index 5f6ba48a0..491ef4ac3 100644 --- a/tables/BandLimited_SAW/1024/saw_max_2048_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_2048_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_2048_AT_16384_1024INT8_H_ #define SAW_MAX_2048_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_204_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_204_at_16384_1024_int8.h index bd842abe9..6efa499a4 100644 --- a/tables/BandLimited_SAW/1024/saw_max_204_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_204_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_204_AT_16384_1024INT8_H_ #define SAW_MAX_204_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_210_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_210_at_16384_1024_int8.h index 47a085ba7..5dfa2b0de 100644 --- a/tables/BandLimited_SAW/1024/saw_max_210_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_210_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_210_AT_16384_1024INT8_H_ #define SAW_MAX_210_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_215_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_215_at_16384_1024_int8.h index 546130a66..31b6f28ce 100644 --- a/tables/BandLimited_SAW/1024/saw_max_215_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_215_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_215_AT_16384_1024INT8_H_ #define SAW_MAX_215_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_221_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_221_at_16384_1024_int8.h index 60a75c846..422ac453a 100644 --- a/tables/BandLimited_SAW/1024/saw_max_221_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_221_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_221_AT_16384_1024INT8_H_ #define SAW_MAX_221_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_227_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_227_at_16384_1024_int8.h index 9fd8317d7..f360be970 100644 --- a/tables/BandLimited_SAW/1024/saw_max_227_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_227_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_227_AT_16384_1024INT8_H_ #define SAW_MAX_227_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_234_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_234_at_16384_1024_int8.h index 761e0b176..9e774cc5b 100644 --- a/tables/BandLimited_SAW/1024/saw_max_234_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_234_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_234_AT_16384_1024INT8_H_ #define SAW_MAX_234_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_240_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_240_at_16384_1024_int8.h index 4a59bd8e0..7446174e0 100644 --- a/tables/BandLimited_SAW/1024/saw_max_240_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_240_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_240_AT_16384_1024INT8_H_ #define SAW_MAX_240_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_248_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_248_at_16384_1024_int8.h index 6db706fce..f07cbaa1e 100644 --- a/tables/BandLimited_SAW/1024/saw_max_248_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_248_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_248_AT_16384_1024INT8_H_ #define SAW_MAX_248_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_256_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_256_at_16384_1024_int8.h index e97ce40dd..849085aee 100644 --- a/tables/BandLimited_SAW/1024/saw_max_256_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_256_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_256_AT_16384_1024INT8_H_ #define SAW_MAX_256_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_264_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_264_at_16384_1024_int8.h index ccaa5086b..ba115ed2e 100644 --- a/tables/BandLimited_SAW/1024/saw_max_264_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_264_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_264_AT_16384_1024INT8_H_ #define SAW_MAX_264_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_2730_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_2730_at_16384_1024_int8.h index 4a19105c6..d85638ec5 100644 --- a/tables/BandLimited_SAW/1024/saw_max_2730_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_2730_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_2730_AT_16384_1024INT8_H_ #define SAW_MAX_2730_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_273_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_273_at_16384_1024_int8.h index 8bd2124da..32aebb9a3 100644 --- a/tables/BandLimited_SAW/1024/saw_max_273_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_273_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_273_AT_16384_1024INT8_H_ #define SAW_MAX_273_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_282_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_282_at_16384_1024_int8.h index 7c65a1c0c..f6683f23e 100644 --- a/tables/BandLimited_SAW/1024/saw_max_282_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_282_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_282_AT_16384_1024INT8_H_ #define SAW_MAX_282_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_292_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_292_at_16384_1024_int8.h index c92f31582..2e84da8cb 100644 --- a/tables/BandLimited_SAW/1024/saw_max_292_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_292_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_292_AT_16384_1024INT8_H_ #define SAW_MAX_292_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_303_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_303_at_16384_1024_int8.h index fd4b0e671..a66e3823a 100644 --- a/tables/BandLimited_SAW/1024/saw_max_303_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_303_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_303_AT_16384_1024INT8_H_ #define SAW_MAX_303_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_315_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_315_at_16384_1024_int8.h index 7060f8c62..bba716ef5 100644 --- a/tables/BandLimited_SAW/1024/saw_max_315_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_315_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_315_AT_16384_1024INT8_H_ #define SAW_MAX_315_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_327_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_327_at_16384_1024_int8.h index a71bb88cb..c68d683bf 100644 --- a/tables/BandLimited_SAW/1024/saw_max_327_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_327_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_327_AT_16384_1024INT8_H_ #define SAW_MAX_327_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_341_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_341_at_16384_1024_int8.h index d3d7837fd..776d4d266 100644 --- a/tables/BandLimited_SAW/1024/saw_max_341_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_341_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_341_AT_16384_1024INT8_H_ #define SAW_MAX_341_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_356_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_356_at_16384_1024_int8.h index 04aa17921..e0c5b15fa 100644 --- a/tables/BandLimited_SAW/1024/saw_max_356_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_356_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_356_AT_16384_1024INT8_H_ #define SAW_MAX_356_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_372_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_372_at_16384_1024_int8.h index 9c43ef116..0667217fb 100644 --- a/tables/BandLimited_SAW/1024/saw_max_372_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_372_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_372_AT_16384_1024INT8_H_ #define SAW_MAX_372_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_390_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_390_at_16384_1024_int8.h index 54c9945fa..9dee15003 100644 --- a/tables/BandLimited_SAW/1024/saw_max_390_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_390_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_390_AT_16384_1024INT8_H_ #define SAW_MAX_390_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_4096_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_4096_at_16384_1024_int8.h index 0ccb21535..eae896ae8 100644 --- a/tables/BandLimited_SAW/1024/saw_max_4096_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_4096_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_4096_AT_16384_1024INT8_H_ #define SAW_MAX_4096_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_409_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_409_at_16384_1024_int8.h index 5486dcc30..406ddae81 100644 --- a/tables/BandLimited_SAW/1024/saw_max_409_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_409_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_409_AT_16384_1024INT8_H_ #define SAW_MAX_409_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_431_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_431_at_16384_1024_int8.h index 3605bd346..9dd00675a 100644 --- a/tables/BandLimited_SAW/1024/saw_max_431_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_431_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_431_AT_16384_1024INT8_H_ #define SAW_MAX_431_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_455_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_455_at_16384_1024_int8.h index 3a44ec78e..a4cd3870e 100644 --- a/tables/BandLimited_SAW/1024/saw_max_455_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_455_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_455_AT_16384_1024INT8_H_ #define SAW_MAX_455_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_481_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_481_at_16384_1024_int8.h index ad90049ce..26b2fa4c2 100644 --- a/tables/BandLimited_SAW/1024/saw_max_481_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_481_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_481_AT_16384_1024INT8_H_ #define SAW_MAX_481_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_512_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_512_at_16384_1024_int8.h index 975232c68..06f1be325 100644 --- a/tables/BandLimited_SAW/1024/saw_max_512_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_512_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_512_AT_16384_1024INT8_H_ #define SAW_MAX_512_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_546_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_546_at_16384_1024_int8.h index 50792c50b..519e5b543 100644 --- a/tables/BandLimited_SAW/1024/saw_max_546_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_546_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_546_AT_16384_1024INT8_H_ #define SAW_MAX_546_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_585_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_585_at_16384_1024_int8.h index 2679e1c22..20a9087d8 100644 --- a/tables/BandLimited_SAW/1024/saw_max_585_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_585_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_585_AT_16384_1024INT8_H_ #define SAW_MAX_585_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_630_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_630_at_16384_1024_int8.h index e4e0ca946..524e87335 100644 --- a/tables/BandLimited_SAW/1024/saw_max_630_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_630_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_630_AT_16384_1024INT8_H_ #define SAW_MAX_630_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_682_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_682_at_16384_1024_int8.h index 87a60706f..bed6f9573 100644 --- a/tables/BandLimited_SAW/1024/saw_max_682_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_682_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_682_AT_16384_1024INT8_H_ #define SAW_MAX_682_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_744_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_744_at_16384_1024_int8.h index e3e7569c4..19ed439df 100644 --- a/tables/BandLimited_SAW/1024/saw_max_744_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_744_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_744_AT_16384_1024INT8_H_ #define SAW_MAX_744_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_8192_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_8192_at_16384_1024_int8.h index 82078e8e9..c101a64bd 100644 --- a/tables/BandLimited_SAW/1024/saw_max_8192_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_8192_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_8192_AT_16384_1024INT8_H_ #define SAW_MAX_8192_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_819_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_819_at_16384_1024_int8.h index 6efb1fffe..861fe0674 100644 --- a/tables/BandLimited_SAW/1024/saw_max_819_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_819_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_819_AT_16384_1024INT8_H_ #define SAW_MAX_819_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/1024/saw_max_910_at_16384_1024_int8.h b/tables/BandLimited_SAW/1024/saw_max_910_at_16384_1024_int8.h index 436c82a61..8f388c1ca 100644 --- a/tables/BandLimited_SAW/1024/saw_max_910_at_16384_1024_int8.h +++ b/tables/BandLimited_SAW/1024/saw_max_910_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_910_AT_16384_1024INT8_H_ #define SAW_MAX_910_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_1024_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_1024_at_16384_2048_int8.h index 0b4a18fd7..ba72e88e6 100644 --- a/tables/BandLimited_SAW/2048/saw_max_1024_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_1024_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1024_AT_16384_2048INT8_H_ #define SAW_MAX_1024_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_1170_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_1170_at_16384_2048_int8.h index e6eaf9f9f..a2b82ebc4 100644 --- a/tables/BandLimited_SAW/2048/saw_max_1170_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_1170_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1170_AT_16384_2048INT8_H_ #define SAW_MAX_1170_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_1365_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_1365_at_16384_2048_int8.h index 6f91e75d9..03d8fec80 100644 --- a/tables/BandLimited_SAW/2048/saw_max_1365_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_1365_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1365_AT_16384_2048INT8_H_ #define SAW_MAX_1365_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_136_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_136_at_16384_2048_int8.h index e2771f0aa..aa52e71aa 100644 --- a/tables/BandLimited_SAW/2048/saw_max_136_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_136_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_136_AT_16384_2048INT8_H_ #define SAW_MAX_136_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_138_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_138_at_16384_2048_int8.h index f01f16897..8bc6e1095 100644 --- a/tables/BandLimited_SAW/2048/saw_max_138_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_138_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_138_AT_16384_2048INT8_H_ #define SAW_MAX_138_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_141_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_141_at_16384_2048_int8.h index 5f83d80e1..6e30af7c8 100644 --- a/tables/BandLimited_SAW/2048/saw_max_141_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_141_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_141_AT_16384_2048INT8_H_ #define SAW_MAX_141_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_143_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_143_at_16384_2048_int8.h index 0edc78161..24f020ede 100644 --- a/tables/BandLimited_SAW/2048/saw_max_143_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_143_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_143_AT_16384_2048INT8_H_ #define SAW_MAX_143_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_146_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_146_at_16384_2048_int8.h index c4e87c4ad..ebc2beb09 100644 --- a/tables/BandLimited_SAW/2048/saw_max_146_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_146_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_146_AT_16384_2048INT8_H_ #define SAW_MAX_146_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_148_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_148_at_16384_2048_int8.h index 7814337cb..9dce5d611 100644 --- a/tables/BandLimited_SAW/2048/saw_max_148_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_148_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_148_AT_16384_2048INT8_H_ #define SAW_MAX_148_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_151_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_151_at_16384_2048_int8.h index d7a0e75ea..ad324d4b5 100644 --- a/tables/BandLimited_SAW/2048/saw_max_151_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_151_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_151_AT_16384_2048INT8_H_ #define SAW_MAX_151_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_154_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_154_at_16384_2048_int8.h index 99ca0de90..c147c973f 100644 --- a/tables/BandLimited_SAW/2048/saw_max_154_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_154_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_154_AT_16384_2048INT8_H_ #define SAW_MAX_154_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_157_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_157_at_16384_2048_int8.h index a005ea711..1c78f6989 100644 --- a/tables/BandLimited_SAW/2048/saw_max_157_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_157_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_157_AT_16384_2048INT8_H_ #define SAW_MAX_157_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_160_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_160_at_16384_2048_int8.h index 2965d45ed..f5d170cd7 100644 --- a/tables/BandLimited_SAW/2048/saw_max_160_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_160_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_160_AT_16384_2048INT8_H_ #define SAW_MAX_160_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_1638_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_1638_at_16384_2048_int8.h index cc48bb810..50b5d8c42 100644 --- a/tables/BandLimited_SAW/2048/saw_max_1638_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_1638_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1638_AT_16384_2048INT8_H_ #define SAW_MAX_1638_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_163_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_163_at_16384_2048_int8.h index 6187019bf..bb52ceaf4 100644 --- a/tables/BandLimited_SAW/2048/saw_max_163_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_163_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_163_AT_16384_2048INT8_H_ #define SAW_MAX_163_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_167_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_167_at_16384_2048_int8.h index 36add0791..c38261f0d 100644 --- a/tables/BandLimited_SAW/2048/saw_max_167_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_167_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_167_AT_16384_2048INT8_H_ #define SAW_MAX_167_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_170_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_170_at_16384_2048_int8.h index 32cecc767..b47e0691e 100644 --- a/tables/BandLimited_SAW/2048/saw_max_170_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_170_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_170_AT_16384_2048INT8_H_ #define SAW_MAX_170_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_174_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_174_at_16384_2048_int8.h index 568e9a886..cf2f18008 100644 --- a/tables/BandLimited_SAW/2048/saw_max_174_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_174_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_174_AT_16384_2048INT8_H_ #define SAW_MAX_174_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_178_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_178_at_16384_2048_int8.h index 056490785..a12ecaeec 100644 --- a/tables/BandLimited_SAW/2048/saw_max_178_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_178_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_178_AT_16384_2048INT8_H_ #define SAW_MAX_178_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_182_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_182_at_16384_2048_int8.h index 10c1ec367..a08604a93 100644 --- a/tables/BandLimited_SAW/2048/saw_max_182_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_182_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_182_AT_16384_2048INT8_H_ #define SAW_MAX_182_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_186_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_186_at_16384_2048_int8.h index f74189406..a0b6d64f3 100644 --- a/tables/BandLimited_SAW/2048/saw_max_186_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_186_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_186_AT_16384_2048INT8_H_ #define SAW_MAX_186_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_190_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_190_at_16384_2048_int8.h index 36e3855ce..6348c56ca 100644 --- a/tables/BandLimited_SAW/2048/saw_max_190_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_190_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_190_AT_16384_2048INT8_H_ #define SAW_MAX_190_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_195_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_195_at_16384_2048_int8.h index c1b5bdec9..dad556732 100644 --- a/tables/BandLimited_SAW/2048/saw_max_195_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_195_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_195_AT_16384_2048INT8_H_ #define SAW_MAX_195_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_199_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_199_at_16384_2048_int8.h index 2118e9061..809b25736 100644 --- a/tables/BandLimited_SAW/2048/saw_max_199_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_199_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_199_AT_16384_2048INT8_H_ #define SAW_MAX_199_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_2048_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_2048_at_16384_2048_int8.h index c155490ac..517ff4ece 100644 --- a/tables/BandLimited_SAW/2048/saw_max_2048_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_2048_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_2048_AT_16384_2048INT8_H_ #define SAW_MAX_2048_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_204_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_204_at_16384_2048_int8.h index f81058bd9..ebc79ea8e 100644 --- a/tables/BandLimited_SAW/2048/saw_max_204_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_204_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_204_AT_16384_2048INT8_H_ #define SAW_MAX_204_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_210_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_210_at_16384_2048_int8.h index 7f25835a1..f2c147144 100644 --- a/tables/BandLimited_SAW/2048/saw_max_210_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_210_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_210_AT_16384_2048INT8_H_ #define SAW_MAX_210_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_215_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_215_at_16384_2048_int8.h index 068570cb1..e057bdb26 100644 --- a/tables/BandLimited_SAW/2048/saw_max_215_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_215_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_215_AT_16384_2048INT8_H_ #define SAW_MAX_215_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_221_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_221_at_16384_2048_int8.h index 182458169..ae11cecfc 100644 --- a/tables/BandLimited_SAW/2048/saw_max_221_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_221_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_221_AT_16384_2048INT8_H_ #define SAW_MAX_221_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_227_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_227_at_16384_2048_int8.h index b4591058e..10bfacaae 100644 --- a/tables/BandLimited_SAW/2048/saw_max_227_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_227_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_227_AT_16384_2048INT8_H_ #define SAW_MAX_227_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_234_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_234_at_16384_2048_int8.h index bb7afad36..f22a76193 100644 --- a/tables/BandLimited_SAW/2048/saw_max_234_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_234_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_234_AT_16384_2048INT8_H_ #define SAW_MAX_234_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_240_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_240_at_16384_2048_int8.h index 0ba2af8e6..b8dc2ea0a 100644 --- a/tables/BandLimited_SAW/2048/saw_max_240_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_240_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_240_AT_16384_2048INT8_H_ #define SAW_MAX_240_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_248_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_248_at_16384_2048_int8.h index 8865f94ea..c6563d331 100644 --- a/tables/BandLimited_SAW/2048/saw_max_248_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_248_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_248_AT_16384_2048INT8_H_ #define SAW_MAX_248_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_256_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_256_at_16384_2048_int8.h index 923ac7e72..740ce244b 100644 --- a/tables/BandLimited_SAW/2048/saw_max_256_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_256_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_256_AT_16384_2048INT8_H_ #define SAW_MAX_256_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_264_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_264_at_16384_2048_int8.h index e9f3b7cff..813ee0795 100644 --- a/tables/BandLimited_SAW/2048/saw_max_264_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_264_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_264_AT_16384_2048INT8_H_ #define SAW_MAX_264_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_2730_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_2730_at_16384_2048_int8.h index 62a14abc6..0df89dc2c 100644 --- a/tables/BandLimited_SAW/2048/saw_max_2730_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_2730_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_2730_AT_16384_2048INT8_H_ #define SAW_MAX_2730_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_273_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_273_at_16384_2048_int8.h index 2e7f826cd..4d641028e 100644 --- a/tables/BandLimited_SAW/2048/saw_max_273_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_273_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_273_AT_16384_2048INT8_H_ #define SAW_MAX_273_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_282_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_282_at_16384_2048_int8.h index 141da710a..4253233d5 100644 --- a/tables/BandLimited_SAW/2048/saw_max_282_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_282_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_282_AT_16384_2048INT8_H_ #define SAW_MAX_282_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_292_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_292_at_16384_2048_int8.h index 6f59ba889..0aad4d22a 100644 --- a/tables/BandLimited_SAW/2048/saw_max_292_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_292_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_292_AT_16384_2048INT8_H_ #define SAW_MAX_292_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_303_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_303_at_16384_2048_int8.h index c82493e0e..1878ea6bd 100644 --- a/tables/BandLimited_SAW/2048/saw_max_303_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_303_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_303_AT_16384_2048INT8_H_ #define SAW_MAX_303_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_315_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_315_at_16384_2048_int8.h index 4ab86b587..f2f6c6ada 100644 --- a/tables/BandLimited_SAW/2048/saw_max_315_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_315_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_315_AT_16384_2048INT8_H_ #define SAW_MAX_315_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_327_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_327_at_16384_2048_int8.h index e2fd9ef0a..e4d907ec0 100644 --- a/tables/BandLimited_SAW/2048/saw_max_327_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_327_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_327_AT_16384_2048INT8_H_ #define SAW_MAX_327_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_341_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_341_at_16384_2048_int8.h index 99f796674..6c28730f0 100644 --- a/tables/BandLimited_SAW/2048/saw_max_341_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_341_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_341_AT_16384_2048INT8_H_ #define SAW_MAX_341_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_356_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_356_at_16384_2048_int8.h index d15ce6ffd..996e3741a 100644 --- a/tables/BandLimited_SAW/2048/saw_max_356_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_356_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_356_AT_16384_2048INT8_H_ #define SAW_MAX_356_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_372_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_372_at_16384_2048_int8.h index bb877e8b7..2188b548c 100644 --- a/tables/BandLimited_SAW/2048/saw_max_372_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_372_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_372_AT_16384_2048INT8_H_ #define SAW_MAX_372_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_390_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_390_at_16384_2048_int8.h index e657d5c48..1c67146f1 100644 --- a/tables/BandLimited_SAW/2048/saw_max_390_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_390_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_390_AT_16384_2048INT8_H_ #define SAW_MAX_390_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_4096_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_4096_at_16384_2048_int8.h index e0289680e..d4bfdb222 100644 --- a/tables/BandLimited_SAW/2048/saw_max_4096_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_4096_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_4096_AT_16384_2048INT8_H_ #define SAW_MAX_4096_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_409_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_409_at_16384_2048_int8.h index b2db8b7cc..3ea2774df 100644 --- a/tables/BandLimited_SAW/2048/saw_max_409_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_409_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_409_AT_16384_2048INT8_H_ #define SAW_MAX_409_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_431_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_431_at_16384_2048_int8.h index 9747fcf69..876f7095f 100644 --- a/tables/BandLimited_SAW/2048/saw_max_431_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_431_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_431_AT_16384_2048INT8_H_ #define SAW_MAX_431_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_455_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_455_at_16384_2048_int8.h index 858df35b1..7d54c510c 100644 --- a/tables/BandLimited_SAW/2048/saw_max_455_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_455_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_455_AT_16384_2048INT8_H_ #define SAW_MAX_455_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_481_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_481_at_16384_2048_int8.h index 8e0b9bcfc..1ab0a120a 100644 --- a/tables/BandLimited_SAW/2048/saw_max_481_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_481_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_481_AT_16384_2048INT8_H_ #define SAW_MAX_481_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_512_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_512_at_16384_2048_int8.h index 49fd5879c..d3d386159 100644 --- a/tables/BandLimited_SAW/2048/saw_max_512_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_512_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_512_AT_16384_2048INT8_H_ #define SAW_MAX_512_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_546_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_546_at_16384_2048_int8.h index 10fc90cc5..0f3b8b231 100644 --- a/tables/BandLimited_SAW/2048/saw_max_546_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_546_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_546_AT_16384_2048INT8_H_ #define SAW_MAX_546_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_585_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_585_at_16384_2048_int8.h index e74510307..9a11e3f13 100644 --- a/tables/BandLimited_SAW/2048/saw_max_585_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_585_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_585_AT_16384_2048INT8_H_ #define SAW_MAX_585_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_630_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_630_at_16384_2048_int8.h index 9c0e810fe..a9d8ff479 100644 --- a/tables/BandLimited_SAW/2048/saw_max_630_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_630_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_630_AT_16384_2048INT8_H_ #define SAW_MAX_630_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_682_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_682_at_16384_2048_int8.h index 42202ba25..f1066e336 100644 --- a/tables/BandLimited_SAW/2048/saw_max_682_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_682_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_682_AT_16384_2048INT8_H_ #define SAW_MAX_682_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_744_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_744_at_16384_2048_int8.h index b4a640057..760c31037 100644 --- a/tables/BandLimited_SAW/2048/saw_max_744_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_744_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_744_AT_16384_2048INT8_H_ #define SAW_MAX_744_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_8192_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_8192_at_16384_2048_int8.h index fa30d4355..0b27460de 100644 --- a/tables/BandLimited_SAW/2048/saw_max_8192_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_8192_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_8192_AT_16384_2048INT8_H_ #define SAW_MAX_8192_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_819_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_819_at_16384_2048_int8.h index 6788ba30e..6a64bbeb8 100644 --- a/tables/BandLimited_SAW/2048/saw_max_819_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_819_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_819_AT_16384_2048INT8_H_ #define SAW_MAX_819_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/2048/saw_max_910_at_16384_2048_int8.h b/tables/BandLimited_SAW/2048/saw_max_910_at_16384_2048_int8.h index 57fda200a..4c556cbd1 100644 --- a/tables/BandLimited_SAW/2048/saw_max_910_at_16384_2048_int8.h +++ b/tables/BandLimited_SAW/2048/saw_max_910_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_910_AT_16384_2048INT8_H_ #define SAW_MAX_910_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_1024_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_1024_at_16384_512_int8.h index 95b0f97c7..01a3daf05 100644 --- a/tables/BandLimited_SAW/512/saw_max_1024_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_1024_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1024_AT_16384_512INT8_H_ #define SAW_MAX_1024_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_1170_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_1170_at_16384_512_int8.h index 3c06a1ae7..0c8390985 100644 --- a/tables/BandLimited_SAW/512/saw_max_1170_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_1170_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1170_AT_16384_512INT8_H_ #define SAW_MAX_1170_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_1365_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_1365_at_16384_512_int8.h index 60787543e..897e8c48d 100644 --- a/tables/BandLimited_SAW/512/saw_max_1365_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_1365_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1365_AT_16384_512INT8_H_ #define SAW_MAX_1365_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_136_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_136_at_16384_512_int8.h index 65408dbb3..6dde8c943 100644 --- a/tables/BandLimited_SAW/512/saw_max_136_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_136_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_136_AT_16384_512INT8_H_ #define SAW_MAX_136_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_138_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_138_at_16384_512_int8.h index 15256e868..bd505a65a 100644 --- a/tables/BandLimited_SAW/512/saw_max_138_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_138_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_138_AT_16384_512INT8_H_ #define SAW_MAX_138_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_141_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_141_at_16384_512_int8.h index 88909c785..023ee01af 100644 --- a/tables/BandLimited_SAW/512/saw_max_141_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_141_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_141_AT_16384_512INT8_H_ #define SAW_MAX_141_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_143_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_143_at_16384_512_int8.h index 199ed60e8..7a0b3119c 100644 --- a/tables/BandLimited_SAW/512/saw_max_143_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_143_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_143_AT_16384_512INT8_H_ #define SAW_MAX_143_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_146_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_146_at_16384_512_int8.h index eb2ec88e9..017f802d5 100644 --- a/tables/BandLimited_SAW/512/saw_max_146_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_146_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_146_AT_16384_512INT8_H_ #define SAW_MAX_146_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_148_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_148_at_16384_512_int8.h index a76ae7a0b..35572a62a 100644 --- a/tables/BandLimited_SAW/512/saw_max_148_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_148_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_148_AT_16384_512INT8_H_ #define SAW_MAX_148_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_151_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_151_at_16384_512_int8.h index 3ee507d1a..2f7206ec4 100644 --- a/tables/BandLimited_SAW/512/saw_max_151_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_151_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_151_AT_16384_512INT8_H_ #define SAW_MAX_151_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_154_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_154_at_16384_512_int8.h index b7507c8da..805c93360 100644 --- a/tables/BandLimited_SAW/512/saw_max_154_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_154_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_154_AT_16384_512INT8_H_ #define SAW_MAX_154_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_157_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_157_at_16384_512_int8.h index 37f0ebcca..86f46e5f7 100644 --- a/tables/BandLimited_SAW/512/saw_max_157_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_157_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_157_AT_16384_512INT8_H_ #define SAW_MAX_157_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_160_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_160_at_16384_512_int8.h index da6034d11..73be3e437 100644 --- a/tables/BandLimited_SAW/512/saw_max_160_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_160_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_160_AT_16384_512INT8_H_ #define SAW_MAX_160_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_1638_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_1638_at_16384_512_int8.h index c78b282dc..16f3f0491 100644 --- a/tables/BandLimited_SAW/512/saw_max_1638_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_1638_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_1638_AT_16384_512INT8_H_ #define SAW_MAX_1638_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_163_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_163_at_16384_512_int8.h index 88f0c04d2..6f3d813e1 100644 --- a/tables/BandLimited_SAW/512/saw_max_163_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_163_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_163_AT_16384_512INT8_H_ #define SAW_MAX_163_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_167_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_167_at_16384_512_int8.h index 63eb3f435..1067207ee 100644 --- a/tables/BandLimited_SAW/512/saw_max_167_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_167_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_167_AT_16384_512INT8_H_ #define SAW_MAX_167_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_170_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_170_at_16384_512_int8.h index 828b23bd4..1214e3573 100644 --- a/tables/BandLimited_SAW/512/saw_max_170_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_170_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_170_AT_16384_512INT8_H_ #define SAW_MAX_170_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_174_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_174_at_16384_512_int8.h index 5a4a9b22e..90595faed 100644 --- a/tables/BandLimited_SAW/512/saw_max_174_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_174_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_174_AT_16384_512INT8_H_ #define SAW_MAX_174_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_178_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_178_at_16384_512_int8.h index affff8a98..fce537b22 100644 --- a/tables/BandLimited_SAW/512/saw_max_178_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_178_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_178_AT_16384_512INT8_H_ #define SAW_MAX_178_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_182_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_182_at_16384_512_int8.h index 3a337ef63..9eb3853a5 100644 --- a/tables/BandLimited_SAW/512/saw_max_182_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_182_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_182_AT_16384_512INT8_H_ #define SAW_MAX_182_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_186_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_186_at_16384_512_int8.h index 3f6b65efe..781a342bd 100644 --- a/tables/BandLimited_SAW/512/saw_max_186_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_186_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_186_AT_16384_512INT8_H_ #define SAW_MAX_186_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_190_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_190_at_16384_512_int8.h index 877a937ad..491a35752 100644 --- a/tables/BandLimited_SAW/512/saw_max_190_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_190_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_190_AT_16384_512INT8_H_ #define SAW_MAX_190_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_195_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_195_at_16384_512_int8.h index 0c2c0edbd..e9cc87e72 100644 --- a/tables/BandLimited_SAW/512/saw_max_195_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_195_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_195_AT_16384_512INT8_H_ #define SAW_MAX_195_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_199_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_199_at_16384_512_int8.h index b3ba04667..fab108847 100644 --- a/tables/BandLimited_SAW/512/saw_max_199_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_199_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_199_AT_16384_512INT8_H_ #define SAW_MAX_199_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_2048_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_2048_at_16384_512_int8.h index 4f3c14032..ac0416693 100644 --- a/tables/BandLimited_SAW/512/saw_max_2048_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_2048_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_2048_AT_16384_512INT8_H_ #define SAW_MAX_2048_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_204_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_204_at_16384_512_int8.h index 29de1aec1..5fe5f0a34 100644 --- a/tables/BandLimited_SAW/512/saw_max_204_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_204_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_204_AT_16384_512INT8_H_ #define SAW_MAX_204_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_210_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_210_at_16384_512_int8.h index 648bfd511..338fb2329 100644 --- a/tables/BandLimited_SAW/512/saw_max_210_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_210_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_210_AT_16384_512INT8_H_ #define SAW_MAX_210_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_215_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_215_at_16384_512_int8.h index 7403e4fe2..e0e211561 100644 --- a/tables/BandLimited_SAW/512/saw_max_215_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_215_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_215_AT_16384_512INT8_H_ #define SAW_MAX_215_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_221_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_221_at_16384_512_int8.h index 23faa609b..c88698bb0 100644 --- a/tables/BandLimited_SAW/512/saw_max_221_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_221_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_221_AT_16384_512INT8_H_ #define SAW_MAX_221_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_227_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_227_at_16384_512_int8.h index fe8aa1682..db34b223e 100644 --- a/tables/BandLimited_SAW/512/saw_max_227_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_227_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_227_AT_16384_512INT8_H_ #define SAW_MAX_227_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_234_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_234_at_16384_512_int8.h index 54f7fac3e..4848e06a4 100644 --- a/tables/BandLimited_SAW/512/saw_max_234_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_234_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_234_AT_16384_512INT8_H_ #define SAW_MAX_234_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_240_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_240_at_16384_512_int8.h index 2d4a0187a..478548b0f 100644 --- a/tables/BandLimited_SAW/512/saw_max_240_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_240_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_240_AT_16384_512INT8_H_ #define SAW_MAX_240_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_248_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_248_at_16384_512_int8.h index 1405199da..443520f99 100644 --- a/tables/BandLimited_SAW/512/saw_max_248_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_248_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_248_AT_16384_512INT8_H_ #define SAW_MAX_248_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_256_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_256_at_16384_512_int8.h index 48e0d2566..ea1c27974 100644 --- a/tables/BandLimited_SAW/512/saw_max_256_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_256_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_256_AT_16384_512INT8_H_ #define SAW_MAX_256_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_264_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_264_at_16384_512_int8.h index 3c522a888..d77a30bc9 100644 --- a/tables/BandLimited_SAW/512/saw_max_264_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_264_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_264_AT_16384_512INT8_H_ #define SAW_MAX_264_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_2730_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_2730_at_16384_512_int8.h index e08702b96..55e111d9c 100644 --- a/tables/BandLimited_SAW/512/saw_max_2730_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_2730_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_2730_AT_16384_512INT8_H_ #define SAW_MAX_2730_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_273_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_273_at_16384_512_int8.h index d8b298a69..e48bdc4c7 100644 --- a/tables/BandLimited_SAW/512/saw_max_273_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_273_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_273_AT_16384_512INT8_H_ #define SAW_MAX_273_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_282_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_282_at_16384_512_int8.h index ecbd46a48..3623be12b 100644 --- a/tables/BandLimited_SAW/512/saw_max_282_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_282_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_282_AT_16384_512INT8_H_ #define SAW_MAX_282_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_292_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_292_at_16384_512_int8.h index 1089ff84e..6fde28a6b 100644 --- a/tables/BandLimited_SAW/512/saw_max_292_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_292_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_292_AT_16384_512INT8_H_ #define SAW_MAX_292_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_303_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_303_at_16384_512_int8.h index 87948e49e..7224a037f 100644 --- a/tables/BandLimited_SAW/512/saw_max_303_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_303_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_303_AT_16384_512INT8_H_ #define SAW_MAX_303_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_315_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_315_at_16384_512_int8.h index d2afb69d6..7bbf32d21 100644 --- a/tables/BandLimited_SAW/512/saw_max_315_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_315_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_315_AT_16384_512INT8_H_ #define SAW_MAX_315_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_327_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_327_at_16384_512_int8.h index 0137be1ba..5b057bfd4 100644 --- a/tables/BandLimited_SAW/512/saw_max_327_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_327_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_327_AT_16384_512INT8_H_ #define SAW_MAX_327_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_341_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_341_at_16384_512_int8.h index 0dd924a18..d86e29c47 100644 --- a/tables/BandLimited_SAW/512/saw_max_341_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_341_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_341_AT_16384_512INT8_H_ #define SAW_MAX_341_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_356_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_356_at_16384_512_int8.h index 0f4e3a7d9..36a5d5834 100644 --- a/tables/BandLimited_SAW/512/saw_max_356_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_356_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_356_AT_16384_512INT8_H_ #define SAW_MAX_356_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_372_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_372_at_16384_512_int8.h index 82a947d56..6677c84ee 100644 --- a/tables/BandLimited_SAW/512/saw_max_372_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_372_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_372_AT_16384_512INT8_H_ #define SAW_MAX_372_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_390_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_390_at_16384_512_int8.h index 6aa9170e0..a1c899a1f 100644 --- a/tables/BandLimited_SAW/512/saw_max_390_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_390_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_390_AT_16384_512INT8_H_ #define SAW_MAX_390_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_4096_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_4096_at_16384_512_int8.h index d6cc98d2d..f7f200765 100644 --- a/tables/BandLimited_SAW/512/saw_max_4096_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_4096_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_4096_AT_16384_512INT8_H_ #define SAW_MAX_4096_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_409_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_409_at_16384_512_int8.h index b67719283..7f3ad9cb3 100644 --- a/tables/BandLimited_SAW/512/saw_max_409_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_409_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_409_AT_16384_512INT8_H_ #define SAW_MAX_409_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_431_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_431_at_16384_512_int8.h index ae552aef1..80b5cee25 100644 --- a/tables/BandLimited_SAW/512/saw_max_431_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_431_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_431_AT_16384_512INT8_H_ #define SAW_MAX_431_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_455_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_455_at_16384_512_int8.h index 5ae470170..965e13822 100644 --- a/tables/BandLimited_SAW/512/saw_max_455_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_455_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_455_AT_16384_512INT8_H_ #define SAW_MAX_455_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_481_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_481_at_16384_512_int8.h index 7270a3167..f9d84d51c 100644 --- a/tables/BandLimited_SAW/512/saw_max_481_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_481_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_481_AT_16384_512INT8_H_ #define SAW_MAX_481_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_512_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_512_at_16384_512_int8.h index 19b1f240f..415fa9299 100644 --- a/tables/BandLimited_SAW/512/saw_max_512_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_512_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_512_AT_16384_512INT8_H_ #define SAW_MAX_512_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_546_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_546_at_16384_512_int8.h index 575c02def..6e3bf6448 100644 --- a/tables/BandLimited_SAW/512/saw_max_546_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_546_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_546_AT_16384_512INT8_H_ #define SAW_MAX_546_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_585_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_585_at_16384_512_int8.h index 7fc3a92e1..0760a104a 100644 --- a/tables/BandLimited_SAW/512/saw_max_585_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_585_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_585_AT_16384_512INT8_H_ #define SAW_MAX_585_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_630_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_630_at_16384_512_int8.h index 0259d9424..beda4a5c1 100644 --- a/tables/BandLimited_SAW/512/saw_max_630_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_630_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_630_AT_16384_512INT8_H_ #define SAW_MAX_630_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_682_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_682_at_16384_512_int8.h index bafd2cb76..c1d65c49d 100644 --- a/tables/BandLimited_SAW/512/saw_max_682_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_682_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_682_AT_16384_512INT8_H_ #define SAW_MAX_682_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_744_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_744_at_16384_512_int8.h index 630ad3066..20769e302 100644 --- a/tables/BandLimited_SAW/512/saw_max_744_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_744_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_744_AT_16384_512INT8_H_ #define SAW_MAX_744_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_8192_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_8192_at_16384_512_int8.h index 64d41c5ba..6188ff461 100644 --- a/tables/BandLimited_SAW/512/saw_max_8192_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_8192_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_8192_AT_16384_512INT8_H_ #define SAW_MAX_8192_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_819_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_819_at_16384_512_int8.h index 8c6733dd4..93b414e09 100644 --- a/tables/BandLimited_SAW/512/saw_max_819_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_819_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_819_AT_16384_512INT8_H_ #define SAW_MAX_819_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SAW/512/saw_max_910_at_16384_512_int8.h b/tables/BandLimited_SAW/512/saw_max_910_at_16384_512_int8.h index 31674d112..b445dd7a2 100644 --- a/tables/BandLimited_SAW/512/saw_max_910_at_16384_512_int8.h +++ b/tables/BandLimited_SAW/512/saw_max_910_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_MAX_910_AT_16384_512INT8_H_ #define SAW_MAX_910_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_101_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_101_at_16384_1024_int8.h index bf53e5f3b..b76065759 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_101_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_101_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_101_AT_16384_1024INT8_H_ #define SQUARE_MAX_101_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_103_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_103_at_16384_1024_int8.h index c3219a00b..343900733 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_103_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_103_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_103_AT_16384_1024INT8_H_ #define SQUARE_MAX_103_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_106_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_106_at_16384_1024_int8.h index a1dd19410..55496d5bd 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_106_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_106_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_106_AT_16384_1024INT8_H_ #define SQUARE_MAX_106_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_109_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_109_at_16384_1024_int8.h index e29b03bc0..84f0916b2 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_109_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_109_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_109_AT_16384_1024INT8_H_ #define SQUARE_MAX_109_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_112_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_112_at_16384_1024_int8.h index d98b42738..e9d9b3c27 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_112_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_112_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_112_AT_16384_1024INT8_H_ #define SQUARE_MAX_112_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_115_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_115_at_16384_1024_int8.h index f0b9e68e4..0ca679454 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_115_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_115_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_115_AT_16384_1024INT8_H_ #define SQUARE_MAX_115_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_1170_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_1170_at_16384_1024_int8.h index 996a51fde..d28efa0ca 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_1170_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_1170_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_1170_AT_16384_1024INT8_H_ #define SQUARE_MAX_1170_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_118_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_118_at_16384_1024_int8.h index f26b603e2..f05355f13 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_118_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_118_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_118_AT_16384_1024INT8_H_ #define SQUARE_MAX_118_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_122_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_122_at_16384_1024_int8.h index 4dc7deb93..08f8827d8 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_122_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_122_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_122_AT_16384_1024INT8_H_ #define SQUARE_MAX_122_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_126_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_126_at_16384_1024_int8.h index f2f1d697a..51c4ebd50 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_126_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_126_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_126_AT_16384_1024INT8_H_ #define SQUARE_MAX_126_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_130_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_130_at_16384_1024_int8.h index 716855015..26f67960e 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_130_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_130_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_130_AT_16384_1024INT8_H_ #define SQUARE_MAX_130_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_134_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_134_at_16384_1024_int8.h index 0911c8331..96eedcd97 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_134_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_134_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_134_AT_16384_1024INT8_H_ #define SQUARE_MAX_134_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_138_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_138_at_16384_1024_int8.h index a3f7fd281..f986c9ede 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_138_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_138_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_138_AT_16384_1024INT8_H_ #define SQUARE_MAX_138_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_143_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_143_at_16384_1024_int8.h index 476034b5d..e2dbce047 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_143_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_143_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_143_AT_16384_1024INT8_H_ #define SQUARE_MAX_143_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_148_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_148_at_16384_1024_int8.h index c32d07044..a840cf81b 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_148_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_148_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_148_AT_16384_1024INT8_H_ #define SQUARE_MAX_148_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_154_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_154_at_16384_1024_int8.h index f1f986f74..caa117f5a 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_154_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_154_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_154_AT_16384_1024INT8_H_ #define SQUARE_MAX_154_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_160_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_160_at_16384_1024_int8.h index ab75a95f0..0469f5310 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_160_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_160_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_160_AT_16384_1024INT8_H_ #define SQUARE_MAX_160_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_1638_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_1638_at_16384_1024_int8.h index 3f5f94391..ad559bb2f 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_1638_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_1638_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_1638_AT_16384_1024INT8_H_ #define SQUARE_MAX_1638_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_167_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_167_at_16384_1024_int8.h index 2abc13966..ffe3bbda2 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_167_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_167_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_167_AT_16384_1024INT8_H_ #define SQUARE_MAX_167_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_174_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_174_at_16384_1024_int8.h index d4fd99631..7aded1a66 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_174_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_174_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_174_AT_16384_1024INT8_H_ #define SQUARE_MAX_174_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_182_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_182_at_16384_1024_int8.h index 3dc132c6b..4406a4654 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_182_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_182_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_182_AT_16384_1024INT8_H_ #define SQUARE_MAX_182_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_190_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_190_at_16384_1024_int8.h index 8c63da3fa..8e42b351c 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_190_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_190_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_190_AT_16384_1024INT8_H_ #define SQUARE_MAX_190_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_199_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_199_at_16384_1024_int8.h index 4ddb30cc9..d4ac13e86 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_199_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_199_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_199_AT_16384_1024INT8_H_ #define SQUARE_MAX_199_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_210_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_210_at_16384_1024_int8.h index 245dcae8c..210a545bd 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_210_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_210_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_210_AT_16384_1024INT8_H_ #define SQUARE_MAX_210_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_221_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_221_at_16384_1024_int8.h index 74d422e9a..b60140fa5 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_221_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_221_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_221_AT_16384_1024INT8_H_ #define SQUARE_MAX_221_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_234_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_234_at_16384_1024_int8.h index f3546c0dc..dee99ec68 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_234_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_234_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_234_AT_16384_1024INT8_H_ #define SQUARE_MAX_234_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_248_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_248_at_16384_1024_int8.h index ae3cc0d6c..22f61679f 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_248_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_248_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_248_AT_16384_1024INT8_H_ #define SQUARE_MAX_248_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_264_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_264_at_16384_1024_int8.h index 2a75cf0c6..189fad7ec 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_264_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_264_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_264_AT_16384_1024INT8_H_ #define SQUARE_MAX_264_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_2730_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_2730_at_16384_1024_int8.h index b1d9a67a7..a671f7dcd 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_2730_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_2730_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_2730_AT_16384_1024INT8_H_ #define SQUARE_MAX_2730_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_282_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_282_at_16384_1024_int8.h index d20e6440e..091611e50 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_282_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_282_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_282_AT_16384_1024INT8_H_ #define SQUARE_MAX_282_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_303_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_303_at_16384_1024_int8.h index bb8b1bb1f..38a577e70 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_303_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_303_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_303_AT_16384_1024INT8_H_ #define SQUARE_MAX_303_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_327_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_327_at_16384_1024_int8.h index 62e8022eb..1b25b2d62 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_327_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_327_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_327_AT_16384_1024INT8_H_ #define SQUARE_MAX_327_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_356_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_356_at_16384_1024_int8.h index c64ecd68a..d583cc558 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_356_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_356_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_356_AT_16384_1024INT8_H_ #define SQUARE_MAX_356_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_390_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_390_at_16384_1024_int8.h index 35ea40b0f..280afccca 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_390_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_390_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_390_AT_16384_1024INT8_H_ #define SQUARE_MAX_390_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_431_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_431_at_16384_1024_int8.h index fb4845342..5386662eb 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_431_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_431_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_431_AT_16384_1024INT8_H_ #define SQUARE_MAX_431_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_481_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_481_at_16384_1024_int8.h index affaa80a8..57f114c76 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_481_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_481_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_481_AT_16384_1024INT8_H_ #define SQUARE_MAX_481_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_546_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_546_at_16384_1024_int8.h index 15f29bc99..98d067e92 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_546_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_546_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_546_AT_16384_1024INT8_H_ #define SQUARE_MAX_546_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_630_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_630_at_16384_1024_int8.h index 9b632a333..1e5d52e89 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_630_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_630_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_630_AT_16384_1024INT8_H_ #define SQUARE_MAX_630_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_68_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_68_at_16384_1024_int8.h index 1336c6f14..02549ad43 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_68_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_68_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_68_AT_16384_1024INT8_H_ #define SQUARE_MAX_68_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_70_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_70_at_16384_1024_int8.h index c685ea611..022cb6e5d 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_70_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_70_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_70_AT_16384_1024INT8_H_ #define SQUARE_MAX_70_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_71_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_71_at_16384_1024_int8.h index da4e40211..4929f76fb 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_71_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_71_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_71_AT_16384_1024INT8_H_ #define SQUARE_MAX_71_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_72_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_72_at_16384_1024_int8.h index d6f4f5a9c..17f024f33 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_72_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_72_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_72_AT_16384_1024INT8_H_ #define SQUARE_MAX_72_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_73_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_73_at_16384_1024_int8.h index a1c6c6239..a1372c791 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_73_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_73_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_73_AT_16384_1024INT8_H_ #define SQUARE_MAX_73_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_744_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_744_at_16384_1024_int8.h index ef6a3542a..1741c3e74 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_744_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_744_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_744_AT_16384_1024INT8_H_ #define SQUARE_MAX_744_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_75_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_75_at_16384_1024_int8.h index 9b6be774c..ac8ef29a4 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_75_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_75_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_75_AT_16384_1024INT8_H_ #define SQUARE_MAX_75_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_76_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_76_at_16384_1024_int8.h index 6b9ea9a20..2cd0cfd5c 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_76_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_76_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_76_AT_16384_1024INT8_H_ #define SQUARE_MAX_76_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_78_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_78_at_16384_1024_int8.h index 5ec06e239..23192f3a5 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_78_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_78_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_78_AT_16384_1024INT8_H_ #define SQUARE_MAX_78_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_79_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_79_at_16384_1024_int8.h index da5b603ec..8acca06a2 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_79_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_79_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_79_AT_16384_1024INT8_H_ #define SQUARE_MAX_79_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_8192_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_8192_at_16384_1024_int8.h index c1ecf553f..7db566281 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_8192_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_8192_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_8192_AT_16384_1024INT8_H_ #define SQUARE_MAX_8192_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_81_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_81_at_16384_1024_int8.h index b10b3a9f2..6e1192f61 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_81_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_81_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_81_AT_16384_1024INT8_H_ #define SQUARE_MAX_81_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_82_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_82_at_16384_1024_int8.h index fa4274aea..7163608c9 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_82_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_82_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_82_AT_16384_1024INT8_H_ #define SQUARE_MAX_82_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_84_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_84_at_16384_1024_int8.h index 60ebd4f19..7622cf802 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_84_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_84_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_84_AT_16384_1024INT8_H_ #define SQUARE_MAX_84_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_86_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_86_at_16384_1024_int8.h index 1fd35200e..89b4d09d6 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_86_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_86_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_86_AT_16384_1024INT8_H_ #define SQUARE_MAX_86_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_88_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_88_at_16384_1024_int8.h index 22faa0490..db22c9533 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_88_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_88_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_88_AT_16384_1024INT8_H_ #define SQUARE_MAX_88_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_90_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_90_at_16384_1024_int8.h index e059cbe46..01fb4d591 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_90_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_90_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_90_AT_16384_1024INT8_H_ #define SQUARE_MAX_90_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_910_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_910_at_16384_1024_int8.h index 7e1aca905..e63034fff 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_910_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_910_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_910_AT_16384_1024INT8_H_ #define SQUARE_MAX_910_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_92_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_92_at_16384_1024_int8.h index f31c582a8..2f5e666c6 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_92_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_92_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_92_AT_16384_1024INT8_H_ #define SQUARE_MAX_92_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_94_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_94_at_16384_1024_int8.h index e870970b5..5752159c7 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_94_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_94_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_94_AT_16384_1024INT8_H_ #define SQUARE_MAX_94_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_96_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_96_at_16384_1024_int8.h index 281b9ed5f..247a94b2c 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_96_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_96_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_96_AT_16384_1024INT8_H_ #define SQUARE_MAX_96_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/1024/square_max_98_at_16384_1024_int8.h b/tables/BandLimited_SQUARE/1024/square_max_98_at_16384_1024_int8.h index 091515083..7f1ae4cd9 100644 --- a/tables/BandLimited_SQUARE/1024/square_max_98_at_16384_1024_int8.h +++ b/tables/BandLimited_SQUARE/1024/square_max_98_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_98_AT_16384_1024INT8_H_ #define SQUARE_MAX_98_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_101_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_101_at_16384_2048_int8.h index 57edbb381..ef6d8bca4 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_101_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_101_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_101_AT_16384_2048INT8_H_ #define SQUARE_MAX_101_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_103_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_103_at_16384_2048_int8.h index f24082399..43e4957c4 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_103_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_103_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_103_AT_16384_2048INT8_H_ #define SQUARE_MAX_103_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_106_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_106_at_16384_2048_int8.h index e1569eb6a..74e19c5ec 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_106_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_106_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_106_AT_16384_2048INT8_H_ #define SQUARE_MAX_106_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_109_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_109_at_16384_2048_int8.h index 0970e7562..a6ceb5828 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_109_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_109_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_109_AT_16384_2048INT8_H_ #define SQUARE_MAX_109_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_112_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_112_at_16384_2048_int8.h index dc62563ce..80cd35fb3 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_112_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_112_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_112_AT_16384_2048INT8_H_ #define SQUARE_MAX_112_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_115_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_115_at_16384_2048_int8.h index 2ad1fd995..ee5f646cf 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_115_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_115_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_115_AT_16384_2048INT8_H_ #define SQUARE_MAX_115_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_1170_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_1170_at_16384_2048_int8.h index 363286376..b4a90cea2 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_1170_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_1170_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_1170_AT_16384_2048INT8_H_ #define SQUARE_MAX_1170_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_118_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_118_at_16384_2048_int8.h index cb0542831..6e67093a9 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_118_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_118_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_118_AT_16384_2048INT8_H_ #define SQUARE_MAX_118_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_122_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_122_at_16384_2048_int8.h index d5d88e6ed..4634574e1 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_122_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_122_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_122_AT_16384_2048INT8_H_ #define SQUARE_MAX_122_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_126_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_126_at_16384_2048_int8.h index f0daeb859..867beb904 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_126_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_126_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_126_AT_16384_2048INT8_H_ #define SQUARE_MAX_126_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_130_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_130_at_16384_2048_int8.h index a6a984410..beb0fd579 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_130_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_130_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_130_AT_16384_2048INT8_H_ #define SQUARE_MAX_130_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_134_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_134_at_16384_2048_int8.h index 56235ff53..05364c50c 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_134_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_134_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_134_AT_16384_2048INT8_H_ #define SQUARE_MAX_134_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_138_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_138_at_16384_2048_int8.h index 07c47bb94..df090430f 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_138_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_138_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_138_AT_16384_2048INT8_H_ #define SQUARE_MAX_138_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_143_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_143_at_16384_2048_int8.h index 243229c37..386c6aa67 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_143_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_143_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_143_AT_16384_2048INT8_H_ #define SQUARE_MAX_143_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_148_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_148_at_16384_2048_int8.h index 5c3783a20..78967d624 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_148_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_148_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_148_AT_16384_2048INT8_H_ #define SQUARE_MAX_148_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_154_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_154_at_16384_2048_int8.h index db0705860..b3cc3f507 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_154_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_154_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_154_AT_16384_2048INT8_H_ #define SQUARE_MAX_154_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_160_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_160_at_16384_2048_int8.h index 219cd7270..6ceab1cfa 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_160_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_160_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_160_AT_16384_2048INT8_H_ #define SQUARE_MAX_160_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_1638_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_1638_at_16384_2048_int8.h index 59180b9f1..c17b833fd 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_1638_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_1638_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_1638_AT_16384_2048INT8_H_ #define SQUARE_MAX_1638_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_167_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_167_at_16384_2048_int8.h index 876ea9980..d1328c4c4 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_167_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_167_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_167_AT_16384_2048INT8_H_ #define SQUARE_MAX_167_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_174_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_174_at_16384_2048_int8.h index fec1aebb6..b28bc5f74 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_174_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_174_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_174_AT_16384_2048INT8_H_ #define SQUARE_MAX_174_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_182_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_182_at_16384_2048_int8.h index 94eb40441..78ebe67a7 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_182_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_182_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_182_AT_16384_2048INT8_H_ #define SQUARE_MAX_182_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_190_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_190_at_16384_2048_int8.h index eba913519..1392d13ff 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_190_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_190_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_190_AT_16384_2048INT8_H_ #define SQUARE_MAX_190_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_199_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_199_at_16384_2048_int8.h index dadafc639..22df9b245 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_199_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_199_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_199_AT_16384_2048INT8_H_ #define SQUARE_MAX_199_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_210_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_210_at_16384_2048_int8.h index ca7d0c90d..aa4545461 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_210_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_210_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_210_AT_16384_2048INT8_H_ #define SQUARE_MAX_210_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_221_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_221_at_16384_2048_int8.h index e61a0bc6c..95e93d6b3 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_221_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_221_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_221_AT_16384_2048INT8_H_ #define SQUARE_MAX_221_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_234_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_234_at_16384_2048_int8.h index c5da51187..0a5de1da8 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_234_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_234_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_234_AT_16384_2048INT8_H_ #define SQUARE_MAX_234_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_248_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_248_at_16384_2048_int8.h index ee14eb997..b5df82ff3 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_248_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_248_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_248_AT_16384_2048INT8_H_ #define SQUARE_MAX_248_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_264_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_264_at_16384_2048_int8.h index 155f2232a..e689687b7 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_264_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_264_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_264_AT_16384_2048INT8_H_ #define SQUARE_MAX_264_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_2730_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_2730_at_16384_2048_int8.h index ce4e92e82..90a86d95f 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_2730_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_2730_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_2730_AT_16384_2048INT8_H_ #define SQUARE_MAX_2730_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_282_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_282_at_16384_2048_int8.h index 05f3f2e50..9ba64b37c 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_282_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_282_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_282_AT_16384_2048INT8_H_ #define SQUARE_MAX_282_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_303_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_303_at_16384_2048_int8.h index a71824b1b..1371b90fe 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_303_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_303_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_303_AT_16384_2048INT8_H_ #define SQUARE_MAX_303_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_327_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_327_at_16384_2048_int8.h index 946896310..3ad74a7a7 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_327_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_327_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_327_AT_16384_2048INT8_H_ #define SQUARE_MAX_327_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_356_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_356_at_16384_2048_int8.h index 91dfcf5c9..4495e56b1 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_356_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_356_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_356_AT_16384_2048INT8_H_ #define SQUARE_MAX_356_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_390_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_390_at_16384_2048_int8.h index 2262738f9..897e3cd75 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_390_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_390_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_390_AT_16384_2048INT8_H_ #define SQUARE_MAX_390_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_431_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_431_at_16384_2048_int8.h index 7a170b9f2..075bca112 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_431_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_431_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_431_AT_16384_2048INT8_H_ #define SQUARE_MAX_431_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_481_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_481_at_16384_2048_int8.h index 8bb18307d..ed0743ae0 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_481_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_481_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_481_AT_16384_2048INT8_H_ #define SQUARE_MAX_481_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_546_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_546_at_16384_2048_int8.h index 1b8e0f7d2..a1c2bbf15 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_546_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_546_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_546_AT_16384_2048INT8_H_ #define SQUARE_MAX_546_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_630_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_630_at_16384_2048_int8.h index 995e10b35..ec7b2f7be 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_630_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_630_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_630_AT_16384_2048INT8_H_ #define SQUARE_MAX_630_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_68_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_68_at_16384_2048_int8.h index 65b147ab6..5a1e11c86 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_68_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_68_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_68_AT_16384_2048INT8_H_ #define SQUARE_MAX_68_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_70_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_70_at_16384_2048_int8.h index b1b9ba156..ba6442aed 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_70_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_70_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_70_AT_16384_2048INT8_H_ #define SQUARE_MAX_70_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_71_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_71_at_16384_2048_int8.h index 36538d5c3..bed5bebbb 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_71_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_71_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_71_AT_16384_2048INT8_H_ #define SQUARE_MAX_71_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_72_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_72_at_16384_2048_int8.h index 1145c798f..4f381a114 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_72_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_72_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_72_AT_16384_2048INT8_H_ #define SQUARE_MAX_72_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_73_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_73_at_16384_2048_int8.h index 855a44d48..652608dee 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_73_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_73_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_73_AT_16384_2048INT8_H_ #define SQUARE_MAX_73_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_744_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_744_at_16384_2048_int8.h index 3a67a366f..ef14f5e70 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_744_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_744_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_744_AT_16384_2048INT8_H_ #define SQUARE_MAX_744_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_75_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_75_at_16384_2048_int8.h index 2f806e008..35d70530d 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_75_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_75_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_75_AT_16384_2048INT8_H_ #define SQUARE_MAX_75_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_76_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_76_at_16384_2048_int8.h index d8482e820..c52a34253 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_76_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_76_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_76_AT_16384_2048INT8_H_ #define SQUARE_MAX_76_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_78_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_78_at_16384_2048_int8.h index 75a1ebc52..2700414e4 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_78_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_78_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_78_AT_16384_2048INT8_H_ #define SQUARE_MAX_78_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_79_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_79_at_16384_2048_int8.h index 7816ab54b..1588576c1 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_79_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_79_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_79_AT_16384_2048INT8_H_ #define SQUARE_MAX_79_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_8192_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_8192_at_16384_2048_int8.h index 0d70758d8..de424aa8b 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_8192_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_8192_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_8192_AT_16384_2048INT8_H_ #define SQUARE_MAX_8192_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_81_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_81_at_16384_2048_int8.h index d7e791591..132b44d87 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_81_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_81_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_81_AT_16384_2048INT8_H_ #define SQUARE_MAX_81_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_82_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_82_at_16384_2048_int8.h index a5ebdf510..af1b889b9 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_82_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_82_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_82_AT_16384_2048INT8_H_ #define SQUARE_MAX_82_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_84_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_84_at_16384_2048_int8.h index 659f02e49..e7bd7db30 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_84_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_84_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_84_AT_16384_2048INT8_H_ #define SQUARE_MAX_84_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_86_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_86_at_16384_2048_int8.h index 890f00ad7..30aaa265b 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_86_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_86_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_86_AT_16384_2048INT8_H_ #define SQUARE_MAX_86_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_88_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_88_at_16384_2048_int8.h index a83fb0b5c..20ca861bc 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_88_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_88_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_88_AT_16384_2048INT8_H_ #define SQUARE_MAX_88_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_90_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_90_at_16384_2048_int8.h index 057f5410d..f898989b3 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_90_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_90_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_90_AT_16384_2048INT8_H_ #define SQUARE_MAX_90_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_910_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_910_at_16384_2048_int8.h index a5576b0ef..a80e3efaf 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_910_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_910_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_910_AT_16384_2048INT8_H_ #define SQUARE_MAX_910_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_92_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_92_at_16384_2048_int8.h index 39cb45d42..d48e90e6a 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_92_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_92_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_92_AT_16384_2048INT8_H_ #define SQUARE_MAX_92_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_94_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_94_at_16384_2048_int8.h index 42212f374..a7067f379 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_94_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_94_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_94_AT_16384_2048INT8_H_ #define SQUARE_MAX_94_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_96_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_96_at_16384_2048_int8.h index e7ca20990..c27a55f5f 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_96_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_96_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_96_AT_16384_2048INT8_H_ #define SQUARE_MAX_96_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/2048/square_max_98_at_16384_2048_int8.h b/tables/BandLimited_SQUARE/2048/square_max_98_at_16384_2048_int8.h index 3b131483b..06c52224f 100644 --- a/tables/BandLimited_SQUARE/2048/square_max_98_at_16384_2048_int8.h +++ b/tables/BandLimited_SQUARE/2048/square_max_98_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_98_AT_16384_2048INT8_H_ #define SQUARE_MAX_98_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_101_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_101_at_16384_512_int8.h index a4bca9f20..56ef45e38 100644 --- a/tables/BandLimited_SQUARE/512/square_max_101_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_101_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_101_AT_16384_512INT8_H_ #define SQUARE_MAX_101_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_103_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_103_at_16384_512_int8.h index 51b7e2902..1a9706f66 100644 --- a/tables/BandLimited_SQUARE/512/square_max_103_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_103_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_103_AT_16384_512INT8_H_ #define SQUARE_MAX_103_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_106_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_106_at_16384_512_int8.h index 33c78bdf7..45c857792 100644 --- a/tables/BandLimited_SQUARE/512/square_max_106_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_106_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_106_AT_16384_512INT8_H_ #define SQUARE_MAX_106_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_109_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_109_at_16384_512_int8.h index 3c9535a1c..5f7266555 100644 --- a/tables/BandLimited_SQUARE/512/square_max_109_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_109_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_109_AT_16384_512INT8_H_ #define SQUARE_MAX_109_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_112_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_112_at_16384_512_int8.h index 9cbb834d5..f0b05647e 100644 --- a/tables/BandLimited_SQUARE/512/square_max_112_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_112_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_112_AT_16384_512INT8_H_ #define SQUARE_MAX_112_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_115_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_115_at_16384_512_int8.h index 048bfbdea..15d773087 100644 --- a/tables/BandLimited_SQUARE/512/square_max_115_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_115_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_115_AT_16384_512INT8_H_ #define SQUARE_MAX_115_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_1170_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_1170_at_16384_512_int8.h index 99b75792f..e37b59304 100644 --- a/tables/BandLimited_SQUARE/512/square_max_1170_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_1170_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_1170_AT_16384_512INT8_H_ #define SQUARE_MAX_1170_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_118_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_118_at_16384_512_int8.h index 1419105a6..55fc78525 100644 --- a/tables/BandLimited_SQUARE/512/square_max_118_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_118_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_118_AT_16384_512INT8_H_ #define SQUARE_MAX_118_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_122_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_122_at_16384_512_int8.h index fcb95cba2..3fd5e9e53 100644 --- a/tables/BandLimited_SQUARE/512/square_max_122_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_122_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_122_AT_16384_512INT8_H_ #define SQUARE_MAX_122_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_126_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_126_at_16384_512_int8.h index ce15679ca..c74e2c6a9 100644 --- a/tables/BandLimited_SQUARE/512/square_max_126_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_126_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_126_AT_16384_512INT8_H_ #define SQUARE_MAX_126_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_130_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_130_at_16384_512_int8.h index 7ef18a8b8..e46787047 100644 --- a/tables/BandLimited_SQUARE/512/square_max_130_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_130_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_130_AT_16384_512INT8_H_ #define SQUARE_MAX_130_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_134_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_134_at_16384_512_int8.h index 64a857c7e..1153a7b88 100644 --- a/tables/BandLimited_SQUARE/512/square_max_134_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_134_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_134_AT_16384_512INT8_H_ #define SQUARE_MAX_134_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_138_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_138_at_16384_512_int8.h index ba9b79caf..d8a878bff 100644 --- a/tables/BandLimited_SQUARE/512/square_max_138_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_138_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_138_AT_16384_512INT8_H_ #define SQUARE_MAX_138_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_143_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_143_at_16384_512_int8.h index 38d8c7371..5ec47858f 100644 --- a/tables/BandLimited_SQUARE/512/square_max_143_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_143_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_143_AT_16384_512INT8_H_ #define SQUARE_MAX_143_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_148_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_148_at_16384_512_int8.h index 18785b007..b517b767d 100644 --- a/tables/BandLimited_SQUARE/512/square_max_148_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_148_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_148_AT_16384_512INT8_H_ #define SQUARE_MAX_148_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_154_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_154_at_16384_512_int8.h index e03535aeb..d32411642 100644 --- a/tables/BandLimited_SQUARE/512/square_max_154_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_154_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_154_AT_16384_512INT8_H_ #define SQUARE_MAX_154_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_160_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_160_at_16384_512_int8.h index c0eab099e..eee270792 100644 --- a/tables/BandLimited_SQUARE/512/square_max_160_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_160_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_160_AT_16384_512INT8_H_ #define SQUARE_MAX_160_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_1638_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_1638_at_16384_512_int8.h index 5a1474cad..44aa7a268 100644 --- a/tables/BandLimited_SQUARE/512/square_max_1638_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_1638_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_1638_AT_16384_512INT8_H_ #define SQUARE_MAX_1638_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_167_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_167_at_16384_512_int8.h index 9e92ee38b..bb5908973 100644 --- a/tables/BandLimited_SQUARE/512/square_max_167_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_167_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_167_AT_16384_512INT8_H_ #define SQUARE_MAX_167_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_174_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_174_at_16384_512_int8.h index 082bfbe98..cf9a4ce2c 100644 --- a/tables/BandLimited_SQUARE/512/square_max_174_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_174_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_174_AT_16384_512INT8_H_ #define SQUARE_MAX_174_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_182_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_182_at_16384_512_int8.h index ce6dd084c..a506ed431 100644 --- a/tables/BandLimited_SQUARE/512/square_max_182_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_182_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_182_AT_16384_512INT8_H_ #define SQUARE_MAX_182_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_190_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_190_at_16384_512_int8.h index 57581dcc3..cb834279d 100644 --- a/tables/BandLimited_SQUARE/512/square_max_190_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_190_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_190_AT_16384_512INT8_H_ #define SQUARE_MAX_190_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_199_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_199_at_16384_512_int8.h index 7c4452a1b..3a83873ae 100644 --- a/tables/BandLimited_SQUARE/512/square_max_199_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_199_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_199_AT_16384_512INT8_H_ #define SQUARE_MAX_199_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_210_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_210_at_16384_512_int8.h index a033146ec..ad3575379 100644 --- a/tables/BandLimited_SQUARE/512/square_max_210_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_210_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_210_AT_16384_512INT8_H_ #define SQUARE_MAX_210_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_221_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_221_at_16384_512_int8.h index edd10901e..325833df6 100644 --- a/tables/BandLimited_SQUARE/512/square_max_221_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_221_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_221_AT_16384_512INT8_H_ #define SQUARE_MAX_221_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_234_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_234_at_16384_512_int8.h index b79abfd6a..dedf26454 100644 --- a/tables/BandLimited_SQUARE/512/square_max_234_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_234_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_234_AT_16384_512INT8_H_ #define SQUARE_MAX_234_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_248_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_248_at_16384_512_int8.h index 7d58fc891..d7b88d174 100644 --- a/tables/BandLimited_SQUARE/512/square_max_248_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_248_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_248_AT_16384_512INT8_H_ #define SQUARE_MAX_248_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_264_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_264_at_16384_512_int8.h index 4b2ced278..0dcf692b0 100644 --- a/tables/BandLimited_SQUARE/512/square_max_264_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_264_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_264_AT_16384_512INT8_H_ #define SQUARE_MAX_264_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_2730_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_2730_at_16384_512_int8.h index 06b9ad94b..d38722443 100644 --- a/tables/BandLimited_SQUARE/512/square_max_2730_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_2730_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_2730_AT_16384_512INT8_H_ #define SQUARE_MAX_2730_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_282_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_282_at_16384_512_int8.h index 38de8d279..f3ad2a1cb 100644 --- a/tables/BandLimited_SQUARE/512/square_max_282_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_282_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_282_AT_16384_512INT8_H_ #define SQUARE_MAX_282_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_303_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_303_at_16384_512_int8.h index 1dfb1cbcf..e62488e33 100644 --- a/tables/BandLimited_SQUARE/512/square_max_303_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_303_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_303_AT_16384_512INT8_H_ #define SQUARE_MAX_303_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_327_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_327_at_16384_512_int8.h index 64055d0fa..25c514d05 100644 --- a/tables/BandLimited_SQUARE/512/square_max_327_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_327_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_327_AT_16384_512INT8_H_ #define SQUARE_MAX_327_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_356_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_356_at_16384_512_int8.h index 3ae8de860..e75fc481e 100644 --- a/tables/BandLimited_SQUARE/512/square_max_356_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_356_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_356_AT_16384_512INT8_H_ #define SQUARE_MAX_356_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_390_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_390_at_16384_512_int8.h index b21240b24..e13c7e01f 100644 --- a/tables/BandLimited_SQUARE/512/square_max_390_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_390_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_390_AT_16384_512INT8_H_ #define SQUARE_MAX_390_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_431_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_431_at_16384_512_int8.h index e817bf55f..a40659e8e 100644 --- a/tables/BandLimited_SQUARE/512/square_max_431_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_431_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_431_AT_16384_512INT8_H_ #define SQUARE_MAX_431_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_481_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_481_at_16384_512_int8.h index ad086ca5f..d6b505890 100644 --- a/tables/BandLimited_SQUARE/512/square_max_481_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_481_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_481_AT_16384_512INT8_H_ #define SQUARE_MAX_481_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_546_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_546_at_16384_512_int8.h index c5fad71fc..ac0269fbc 100644 --- a/tables/BandLimited_SQUARE/512/square_max_546_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_546_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_546_AT_16384_512INT8_H_ #define SQUARE_MAX_546_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_630_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_630_at_16384_512_int8.h index 088549f7b..8dd59ce67 100644 --- a/tables/BandLimited_SQUARE/512/square_max_630_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_630_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_630_AT_16384_512INT8_H_ #define SQUARE_MAX_630_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_68_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_68_at_16384_512_int8.h index 2f6f37681..023194e27 100644 --- a/tables/BandLimited_SQUARE/512/square_max_68_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_68_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_68_AT_16384_512INT8_H_ #define SQUARE_MAX_68_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_70_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_70_at_16384_512_int8.h index 81a59b3ea..7a407bc6d 100644 --- a/tables/BandLimited_SQUARE/512/square_max_70_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_70_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_70_AT_16384_512INT8_H_ #define SQUARE_MAX_70_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_71_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_71_at_16384_512_int8.h index 119d00833..666c210a3 100644 --- a/tables/BandLimited_SQUARE/512/square_max_71_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_71_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_71_AT_16384_512INT8_H_ #define SQUARE_MAX_71_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_72_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_72_at_16384_512_int8.h index fdc3420c4..d5d388ced 100644 --- a/tables/BandLimited_SQUARE/512/square_max_72_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_72_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_72_AT_16384_512INT8_H_ #define SQUARE_MAX_72_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_73_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_73_at_16384_512_int8.h index dadf70bce..cef5a2eb3 100644 --- a/tables/BandLimited_SQUARE/512/square_max_73_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_73_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_73_AT_16384_512INT8_H_ #define SQUARE_MAX_73_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_744_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_744_at_16384_512_int8.h index 2f02c4219..739f9bb16 100644 --- a/tables/BandLimited_SQUARE/512/square_max_744_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_744_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_744_AT_16384_512INT8_H_ #define SQUARE_MAX_744_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_75_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_75_at_16384_512_int8.h index ddb639bfc..e19a7071a 100644 --- a/tables/BandLimited_SQUARE/512/square_max_75_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_75_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_75_AT_16384_512INT8_H_ #define SQUARE_MAX_75_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_76_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_76_at_16384_512_int8.h index feb7c510b..701ea7d43 100644 --- a/tables/BandLimited_SQUARE/512/square_max_76_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_76_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_76_AT_16384_512INT8_H_ #define SQUARE_MAX_76_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_78_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_78_at_16384_512_int8.h index 254daea66..b0933d0f4 100644 --- a/tables/BandLimited_SQUARE/512/square_max_78_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_78_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_78_AT_16384_512INT8_H_ #define SQUARE_MAX_78_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_79_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_79_at_16384_512_int8.h index 8380309f4..6d7da45bb 100644 --- a/tables/BandLimited_SQUARE/512/square_max_79_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_79_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_79_AT_16384_512INT8_H_ #define SQUARE_MAX_79_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_8192_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_8192_at_16384_512_int8.h index 076a03ffa..0392d78b9 100644 --- a/tables/BandLimited_SQUARE/512/square_max_8192_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_8192_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_8192_AT_16384_512INT8_H_ #define SQUARE_MAX_8192_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_81_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_81_at_16384_512_int8.h index 68a76e665..8cf862a2d 100644 --- a/tables/BandLimited_SQUARE/512/square_max_81_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_81_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_81_AT_16384_512INT8_H_ #define SQUARE_MAX_81_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_82_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_82_at_16384_512_int8.h index 39069f35d..952f05216 100644 --- a/tables/BandLimited_SQUARE/512/square_max_82_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_82_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_82_AT_16384_512INT8_H_ #define SQUARE_MAX_82_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_84_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_84_at_16384_512_int8.h index 543ff1364..0495d82f7 100644 --- a/tables/BandLimited_SQUARE/512/square_max_84_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_84_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_84_AT_16384_512INT8_H_ #define SQUARE_MAX_84_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_86_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_86_at_16384_512_int8.h index 2974896e1..cb14d8953 100644 --- a/tables/BandLimited_SQUARE/512/square_max_86_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_86_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_86_AT_16384_512INT8_H_ #define SQUARE_MAX_86_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_88_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_88_at_16384_512_int8.h index e540db398..bb0894d40 100644 --- a/tables/BandLimited_SQUARE/512/square_max_88_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_88_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_88_AT_16384_512INT8_H_ #define SQUARE_MAX_88_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_90_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_90_at_16384_512_int8.h index 933a1535b..67a439b4f 100644 --- a/tables/BandLimited_SQUARE/512/square_max_90_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_90_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_90_AT_16384_512INT8_H_ #define SQUARE_MAX_90_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_910_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_910_at_16384_512_int8.h index cfb512af6..9f01ed043 100644 --- a/tables/BandLimited_SQUARE/512/square_max_910_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_910_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_910_AT_16384_512INT8_H_ #define SQUARE_MAX_910_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_92_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_92_at_16384_512_int8.h index 0c3e10062..28b5393a9 100644 --- a/tables/BandLimited_SQUARE/512/square_max_92_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_92_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_92_AT_16384_512INT8_H_ #define SQUARE_MAX_92_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_94_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_94_at_16384_512_int8.h index 220b81048..745cc62d3 100644 --- a/tables/BandLimited_SQUARE/512/square_max_94_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_94_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_94_AT_16384_512INT8_H_ #define SQUARE_MAX_94_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_96_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_96_at_16384_512_int8.h index a43c67c1b..72b1f26fb 100644 --- a/tables/BandLimited_SQUARE/512/square_max_96_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_96_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_96_AT_16384_512INT8_H_ #define SQUARE_MAX_96_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_SQUARE/512/square_max_98_at_16384_512_int8.h b/tables/BandLimited_SQUARE/512/square_max_98_at_16384_512_int8.h index c692549f0..005d3e411 100644 --- a/tables/BandLimited_SQUARE/512/square_max_98_at_16384_512_int8.h +++ b/tables/BandLimited_SQUARE/512/square_max_98_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_MAX_98_AT_16384_512INT8_H_ #define SQUARE_MAX_98_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_103_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_103_at_16384_1024_int8.h index 6862495b4..38cef0f8e 100644 --- a/tables/BandLimited_TRI/1024/tri_max_103_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_103_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_103_AT_16384_1024INT8_H_ #define TRI_MAX_103_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_106_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_106_at_16384_1024_int8.h index 41b25448e..58f88e83a 100644 --- a/tables/BandLimited_TRI/1024/tri_max_106_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_106_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_106_AT_16384_1024INT8_H_ #define TRI_MAX_106_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_109_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_109_at_16384_1024_int8.h index 7b0102f22..f1f996e38 100644 --- a/tables/BandLimited_TRI/1024/tri_max_109_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_109_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_109_AT_16384_1024INT8_H_ #define TRI_MAX_109_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_112_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_112_at_16384_1024_int8.h index d5c35c230..11c45c3ed 100644 --- a/tables/BandLimited_TRI/1024/tri_max_112_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_112_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_112_AT_16384_1024INT8_H_ #define TRI_MAX_112_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_115_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_115_at_16384_1024_int8.h index 45a6518d9..6a9ba5513 100644 --- a/tables/BandLimited_TRI/1024/tri_max_115_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_115_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_115_AT_16384_1024INT8_H_ #define TRI_MAX_115_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_1170_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_1170_at_16384_1024_int8.h index b38b81e65..d81e6e2f9 100644 --- a/tables/BandLimited_TRI/1024/tri_max_1170_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_1170_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_1170_AT_16384_1024INT8_H_ #define TRI_MAX_1170_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_118_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_118_at_16384_1024_int8.h index 245052b76..03eed4bb6 100644 --- a/tables/BandLimited_TRI/1024/tri_max_118_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_118_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_118_AT_16384_1024INT8_H_ #define TRI_MAX_118_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_122_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_122_at_16384_1024_int8.h index 0110de51f..b93b1679f 100644 --- a/tables/BandLimited_TRI/1024/tri_max_122_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_122_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_122_AT_16384_1024INT8_H_ #define TRI_MAX_122_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_126_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_126_at_16384_1024_int8.h index 3cfeb3b41..a9936eb6d 100644 --- a/tables/BandLimited_TRI/1024/tri_max_126_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_126_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_126_AT_16384_1024INT8_H_ #define TRI_MAX_126_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_130_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_130_at_16384_1024_int8.h index 079261a09..fea985f85 100644 --- a/tables/BandLimited_TRI/1024/tri_max_130_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_130_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_130_AT_16384_1024INT8_H_ #define TRI_MAX_130_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_134_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_134_at_16384_1024_int8.h index 165a8b3c8..c7d8ed554 100644 --- a/tables/BandLimited_TRI/1024/tri_max_134_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_134_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_134_AT_16384_1024INT8_H_ #define TRI_MAX_134_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_138_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_138_at_16384_1024_int8.h index 0c2072862..f9577e7e1 100644 --- a/tables/BandLimited_TRI/1024/tri_max_138_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_138_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_138_AT_16384_1024INT8_H_ #define TRI_MAX_138_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_143_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_143_at_16384_1024_int8.h index fe9cc23a5..a8cf8fb7a 100644 --- a/tables/BandLimited_TRI/1024/tri_max_143_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_143_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_143_AT_16384_1024INT8_H_ #define TRI_MAX_143_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_148_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_148_at_16384_1024_int8.h index 3a0dec582..ca7e851d6 100644 --- a/tables/BandLimited_TRI/1024/tri_max_148_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_148_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_148_AT_16384_1024INT8_H_ #define TRI_MAX_148_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_154_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_154_at_16384_1024_int8.h index b0b90da98..bbfc43ded 100644 --- a/tables/BandLimited_TRI/1024/tri_max_154_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_154_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_154_AT_16384_1024INT8_H_ #define TRI_MAX_154_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_160_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_160_at_16384_1024_int8.h index 0491d4c3f..beeaae9bd 100644 --- a/tables/BandLimited_TRI/1024/tri_max_160_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_160_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_160_AT_16384_1024INT8_H_ #define TRI_MAX_160_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_1638_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_1638_at_16384_1024_int8.h index 1158346e5..b3bd0eebf 100644 --- a/tables/BandLimited_TRI/1024/tri_max_1638_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_1638_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_1638_AT_16384_1024INT8_H_ #define TRI_MAX_1638_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_167_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_167_at_16384_1024_int8.h index 01414a677..d5b689736 100644 --- a/tables/BandLimited_TRI/1024/tri_max_167_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_167_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_167_AT_16384_1024INT8_H_ #define TRI_MAX_167_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_174_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_174_at_16384_1024_int8.h index acb94ff3a..4ed04d570 100644 --- a/tables/BandLimited_TRI/1024/tri_max_174_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_174_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_174_AT_16384_1024INT8_H_ #define TRI_MAX_174_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_182_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_182_at_16384_1024_int8.h index 04d34e2e8..393ac1151 100644 --- a/tables/BandLimited_TRI/1024/tri_max_182_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_182_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_182_AT_16384_1024INT8_H_ #define TRI_MAX_182_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_190_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_190_at_16384_1024_int8.h index 7d01e246d..18deaad42 100644 --- a/tables/BandLimited_TRI/1024/tri_max_190_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_190_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_190_AT_16384_1024INT8_H_ #define TRI_MAX_190_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_199_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_199_at_16384_1024_int8.h index a79b852f6..1f70379e3 100644 --- a/tables/BandLimited_TRI/1024/tri_max_199_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_199_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_199_AT_16384_1024INT8_H_ #define TRI_MAX_199_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_210_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_210_at_16384_1024_int8.h index 57808688f..bf17d4b08 100644 --- a/tables/BandLimited_TRI/1024/tri_max_210_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_210_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_210_AT_16384_1024INT8_H_ #define TRI_MAX_210_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_221_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_221_at_16384_1024_int8.h index 00231564e..b4b9f2225 100644 --- a/tables/BandLimited_TRI/1024/tri_max_221_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_221_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_221_AT_16384_1024INT8_H_ #define TRI_MAX_221_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_234_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_234_at_16384_1024_int8.h index 1724c5e4b..3fe05bd3b 100644 --- a/tables/BandLimited_TRI/1024/tri_max_234_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_234_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_234_AT_16384_1024INT8_H_ #define TRI_MAX_234_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_248_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_248_at_16384_1024_int8.h index c9386097b..d597830b8 100644 --- a/tables/BandLimited_TRI/1024/tri_max_248_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_248_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_248_AT_16384_1024INT8_H_ #define TRI_MAX_248_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_264_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_264_at_16384_1024_int8.h index 1eac9d04e..844cadaae 100644 --- a/tables/BandLimited_TRI/1024/tri_max_264_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_264_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_264_AT_16384_1024INT8_H_ #define TRI_MAX_264_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_2730_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_2730_at_16384_1024_int8.h index 9fc42eda7..bde21e6dd 100644 --- a/tables/BandLimited_TRI/1024/tri_max_2730_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_2730_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_2730_AT_16384_1024INT8_H_ #define TRI_MAX_2730_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_282_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_282_at_16384_1024_int8.h index 58979b09d..456736494 100644 --- a/tables/BandLimited_TRI/1024/tri_max_282_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_282_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_282_AT_16384_1024INT8_H_ #define TRI_MAX_282_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_303_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_303_at_16384_1024_int8.h index 49dfa034f..be4a2adfa 100644 --- a/tables/BandLimited_TRI/1024/tri_max_303_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_303_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_303_AT_16384_1024INT8_H_ #define TRI_MAX_303_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_327_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_327_at_16384_1024_int8.h index 66b5a7b22..d04027a44 100644 --- a/tables/BandLimited_TRI/1024/tri_max_327_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_327_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_327_AT_16384_1024INT8_H_ #define TRI_MAX_327_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_356_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_356_at_16384_1024_int8.h index de5ce8ed9..622a884fb 100644 --- a/tables/BandLimited_TRI/1024/tri_max_356_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_356_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_356_AT_16384_1024INT8_H_ #define TRI_MAX_356_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_390_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_390_at_16384_1024_int8.h index 978fbd452..ab8658a81 100644 --- a/tables/BandLimited_TRI/1024/tri_max_390_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_390_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_390_AT_16384_1024INT8_H_ #define TRI_MAX_390_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_431_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_431_at_16384_1024_int8.h index 9f1d0a312..c36420270 100644 --- a/tables/BandLimited_TRI/1024/tri_max_431_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_431_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_431_AT_16384_1024INT8_H_ #define TRI_MAX_431_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_481_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_481_at_16384_1024_int8.h index 53c7de70e..1a5214fd2 100644 --- a/tables/BandLimited_TRI/1024/tri_max_481_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_481_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_481_AT_16384_1024INT8_H_ #define TRI_MAX_481_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_546_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_546_at_16384_1024_int8.h index 03f7ec43a..463ac7ad7 100644 --- a/tables/BandLimited_TRI/1024/tri_max_546_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_546_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_546_AT_16384_1024INT8_H_ #define TRI_MAX_546_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_630_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_630_at_16384_1024_int8.h index 1dae2efc6..8735306a9 100644 --- a/tables/BandLimited_TRI/1024/tri_max_630_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_630_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_630_AT_16384_1024INT8_H_ #define TRI_MAX_630_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_744_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_744_at_16384_1024_int8.h index e7d35c679..78dfb16b1 100644 --- a/tables/BandLimited_TRI/1024/tri_max_744_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_744_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_744_AT_16384_1024INT8_H_ #define TRI_MAX_744_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_8192_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_8192_at_16384_1024_int8.h index d3c2c705e..6ec365758 100644 --- a/tables/BandLimited_TRI/1024/tri_max_8192_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_8192_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_8192_AT_16384_1024INT8_H_ #define TRI_MAX_8192_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/1024/tri_max_910_at_16384_1024_int8.h b/tables/BandLimited_TRI/1024/tri_max_910_at_16384_1024_int8.h index 09d88fc69..a30fe1bcd 100644 --- a/tables/BandLimited_TRI/1024/tri_max_910_at_16384_1024_int8.h +++ b/tables/BandLimited_TRI/1024/tri_max_910_at_16384_1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_910_AT_16384_1024INT8_H_ #define TRI_MAX_910_AT_16384_1024INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_103_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_103_at_16384_2048_int8.h index 20ce1def7..e22e75066 100644 --- a/tables/BandLimited_TRI/2048/tri_max_103_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_103_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_103_AT_16384_2048INT8_H_ #define TRI_MAX_103_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_106_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_106_at_16384_2048_int8.h index 19870cde9..794906403 100644 --- a/tables/BandLimited_TRI/2048/tri_max_106_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_106_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_106_AT_16384_2048INT8_H_ #define TRI_MAX_106_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_109_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_109_at_16384_2048_int8.h index ace639f4d..47197a1b1 100644 --- a/tables/BandLimited_TRI/2048/tri_max_109_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_109_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_109_AT_16384_2048INT8_H_ #define TRI_MAX_109_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_112_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_112_at_16384_2048_int8.h index 83edf58c6..ca8724127 100644 --- a/tables/BandLimited_TRI/2048/tri_max_112_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_112_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_112_AT_16384_2048INT8_H_ #define TRI_MAX_112_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_115_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_115_at_16384_2048_int8.h index 0c07b8e84..f64a7e37b 100644 --- a/tables/BandLimited_TRI/2048/tri_max_115_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_115_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_115_AT_16384_2048INT8_H_ #define TRI_MAX_115_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_1170_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_1170_at_16384_2048_int8.h index 717c001e9..c17edaa40 100644 --- a/tables/BandLimited_TRI/2048/tri_max_1170_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_1170_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_1170_AT_16384_2048INT8_H_ #define TRI_MAX_1170_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_118_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_118_at_16384_2048_int8.h index fba088192..86173fd21 100644 --- a/tables/BandLimited_TRI/2048/tri_max_118_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_118_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_118_AT_16384_2048INT8_H_ #define TRI_MAX_118_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_122_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_122_at_16384_2048_int8.h index 400d91961..78b1a0158 100644 --- a/tables/BandLimited_TRI/2048/tri_max_122_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_122_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_122_AT_16384_2048INT8_H_ #define TRI_MAX_122_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_126_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_126_at_16384_2048_int8.h index cb12b9eb3..552350e47 100644 --- a/tables/BandLimited_TRI/2048/tri_max_126_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_126_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_126_AT_16384_2048INT8_H_ #define TRI_MAX_126_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_130_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_130_at_16384_2048_int8.h index b8148d3af..8564e2cd6 100644 --- a/tables/BandLimited_TRI/2048/tri_max_130_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_130_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_130_AT_16384_2048INT8_H_ #define TRI_MAX_130_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_134_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_134_at_16384_2048_int8.h index 393aa5ee1..f0685f5ad 100644 --- a/tables/BandLimited_TRI/2048/tri_max_134_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_134_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_134_AT_16384_2048INT8_H_ #define TRI_MAX_134_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_138_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_138_at_16384_2048_int8.h index 086bd0f8e..6404de046 100644 --- a/tables/BandLimited_TRI/2048/tri_max_138_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_138_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_138_AT_16384_2048INT8_H_ #define TRI_MAX_138_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_143_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_143_at_16384_2048_int8.h index b4adccbea..e8b6ce12a 100644 --- a/tables/BandLimited_TRI/2048/tri_max_143_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_143_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_143_AT_16384_2048INT8_H_ #define TRI_MAX_143_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_148_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_148_at_16384_2048_int8.h index ff8710c4d..915a19792 100644 --- a/tables/BandLimited_TRI/2048/tri_max_148_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_148_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_148_AT_16384_2048INT8_H_ #define TRI_MAX_148_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_154_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_154_at_16384_2048_int8.h index c5fd5a98f..c604506f3 100644 --- a/tables/BandLimited_TRI/2048/tri_max_154_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_154_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_154_AT_16384_2048INT8_H_ #define TRI_MAX_154_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_160_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_160_at_16384_2048_int8.h index e4eec5332..2ab31242b 100644 --- a/tables/BandLimited_TRI/2048/tri_max_160_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_160_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_160_AT_16384_2048INT8_H_ #define TRI_MAX_160_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_1638_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_1638_at_16384_2048_int8.h index 85ecae58f..cc9cba232 100644 --- a/tables/BandLimited_TRI/2048/tri_max_1638_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_1638_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_1638_AT_16384_2048INT8_H_ #define TRI_MAX_1638_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_167_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_167_at_16384_2048_int8.h index d15d1ca4f..2c88961c0 100644 --- a/tables/BandLimited_TRI/2048/tri_max_167_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_167_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_167_AT_16384_2048INT8_H_ #define TRI_MAX_167_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_174_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_174_at_16384_2048_int8.h index e91946276..8416c7ae4 100644 --- a/tables/BandLimited_TRI/2048/tri_max_174_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_174_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_174_AT_16384_2048INT8_H_ #define TRI_MAX_174_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_182_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_182_at_16384_2048_int8.h index ee6d3560c..04b1ca5b0 100644 --- a/tables/BandLimited_TRI/2048/tri_max_182_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_182_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_182_AT_16384_2048INT8_H_ #define TRI_MAX_182_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_190_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_190_at_16384_2048_int8.h index 4a5ce7060..ca3064f58 100644 --- a/tables/BandLimited_TRI/2048/tri_max_190_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_190_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_190_AT_16384_2048INT8_H_ #define TRI_MAX_190_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_199_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_199_at_16384_2048_int8.h index 0e9009bf6..bc238882c 100644 --- a/tables/BandLimited_TRI/2048/tri_max_199_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_199_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_199_AT_16384_2048INT8_H_ #define TRI_MAX_199_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_210_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_210_at_16384_2048_int8.h index d959af209..3fceab650 100644 --- a/tables/BandLimited_TRI/2048/tri_max_210_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_210_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_210_AT_16384_2048INT8_H_ #define TRI_MAX_210_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_221_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_221_at_16384_2048_int8.h index 86395b166..357085097 100644 --- a/tables/BandLimited_TRI/2048/tri_max_221_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_221_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_221_AT_16384_2048INT8_H_ #define TRI_MAX_221_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_234_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_234_at_16384_2048_int8.h index b97a072ab..0edf62cea 100644 --- a/tables/BandLimited_TRI/2048/tri_max_234_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_234_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_234_AT_16384_2048INT8_H_ #define TRI_MAX_234_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_248_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_248_at_16384_2048_int8.h index 1c300fea0..4de338283 100644 --- a/tables/BandLimited_TRI/2048/tri_max_248_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_248_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_248_AT_16384_2048INT8_H_ #define TRI_MAX_248_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_264_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_264_at_16384_2048_int8.h index 0d082b608..6644b4a00 100644 --- a/tables/BandLimited_TRI/2048/tri_max_264_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_264_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_264_AT_16384_2048INT8_H_ #define TRI_MAX_264_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_2730_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_2730_at_16384_2048_int8.h index f9b37b70c..d19fd91c0 100644 --- a/tables/BandLimited_TRI/2048/tri_max_2730_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_2730_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_2730_AT_16384_2048INT8_H_ #define TRI_MAX_2730_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_282_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_282_at_16384_2048_int8.h index 3d1d2445f..bfcb05aaa 100644 --- a/tables/BandLimited_TRI/2048/tri_max_282_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_282_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_282_AT_16384_2048INT8_H_ #define TRI_MAX_282_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_303_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_303_at_16384_2048_int8.h index 4467b05dd..d44cd903b 100644 --- a/tables/BandLimited_TRI/2048/tri_max_303_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_303_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_303_AT_16384_2048INT8_H_ #define TRI_MAX_303_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_327_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_327_at_16384_2048_int8.h index 66095402f..1de94ccbd 100644 --- a/tables/BandLimited_TRI/2048/tri_max_327_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_327_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_327_AT_16384_2048INT8_H_ #define TRI_MAX_327_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_356_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_356_at_16384_2048_int8.h index 5132c4d7b..c63e2a3e8 100644 --- a/tables/BandLimited_TRI/2048/tri_max_356_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_356_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_356_AT_16384_2048INT8_H_ #define TRI_MAX_356_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_390_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_390_at_16384_2048_int8.h index 72f161d54..6cc21aded 100644 --- a/tables/BandLimited_TRI/2048/tri_max_390_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_390_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_390_AT_16384_2048INT8_H_ #define TRI_MAX_390_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_431_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_431_at_16384_2048_int8.h index a9c6436cf..fb5a9263d 100644 --- a/tables/BandLimited_TRI/2048/tri_max_431_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_431_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_431_AT_16384_2048INT8_H_ #define TRI_MAX_431_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_481_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_481_at_16384_2048_int8.h index d4d027d41..e3e8ba7fe 100644 --- a/tables/BandLimited_TRI/2048/tri_max_481_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_481_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_481_AT_16384_2048INT8_H_ #define TRI_MAX_481_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_546_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_546_at_16384_2048_int8.h index d80c64bb7..35318a79f 100644 --- a/tables/BandLimited_TRI/2048/tri_max_546_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_546_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_546_AT_16384_2048INT8_H_ #define TRI_MAX_546_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_630_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_630_at_16384_2048_int8.h index 91ebb8810..dbd1a2cb6 100644 --- a/tables/BandLimited_TRI/2048/tri_max_630_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_630_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_630_AT_16384_2048INT8_H_ #define TRI_MAX_630_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_744_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_744_at_16384_2048_int8.h index ce269dc10..2d50d46a9 100644 --- a/tables/BandLimited_TRI/2048/tri_max_744_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_744_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_744_AT_16384_2048INT8_H_ #define TRI_MAX_744_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_8192_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_8192_at_16384_2048_int8.h index 7af7efd81..0059c18e7 100644 --- a/tables/BandLimited_TRI/2048/tri_max_8192_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_8192_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_8192_AT_16384_2048INT8_H_ #define TRI_MAX_8192_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/2048/tri_max_910_at_16384_2048_int8.h b/tables/BandLimited_TRI/2048/tri_max_910_at_16384_2048_int8.h index 04ec387a0..d188ccb81 100644 --- a/tables/BandLimited_TRI/2048/tri_max_910_at_16384_2048_int8.h +++ b/tables/BandLimited_TRI/2048/tri_max_910_at_16384_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_910_AT_16384_2048INT8_H_ #define TRI_MAX_910_AT_16384_2048INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_103_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_103_at_16384_512_int8.h index b0b809349..42b8086f9 100644 --- a/tables/BandLimited_TRI/512/tri_max_103_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_103_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_103_AT_16384_512INT8_H_ #define TRI_MAX_103_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_106_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_106_at_16384_512_int8.h index 9db7db739..bb0038c2c 100644 --- a/tables/BandLimited_TRI/512/tri_max_106_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_106_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_106_AT_16384_512INT8_H_ #define TRI_MAX_106_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_109_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_109_at_16384_512_int8.h index 1153e5b12..bd947747b 100644 --- a/tables/BandLimited_TRI/512/tri_max_109_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_109_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_109_AT_16384_512INT8_H_ #define TRI_MAX_109_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_112_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_112_at_16384_512_int8.h index 81a344b86..3ec0d3f24 100644 --- a/tables/BandLimited_TRI/512/tri_max_112_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_112_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_112_AT_16384_512INT8_H_ #define TRI_MAX_112_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_115_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_115_at_16384_512_int8.h index fe40feb03..a6b3d6c0d 100644 --- a/tables/BandLimited_TRI/512/tri_max_115_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_115_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_115_AT_16384_512INT8_H_ #define TRI_MAX_115_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_1170_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_1170_at_16384_512_int8.h index 8c3652084..cec350427 100644 --- a/tables/BandLimited_TRI/512/tri_max_1170_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_1170_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_1170_AT_16384_512INT8_H_ #define TRI_MAX_1170_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_118_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_118_at_16384_512_int8.h index 0fd36132b..1da455db7 100644 --- a/tables/BandLimited_TRI/512/tri_max_118_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_118_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_118_AT_16384_512INT8_H_ #define TRI_MAX_118_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_122_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_122_at_16384_512_int8.h index ff1eb6778..4a561a20f 100644 --- a/tables/BandLimited_TRI/512/tri_max_122_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_122_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_122_AT_16384_512INT8_H_ #define TRI_MAX_122_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_126_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_126_at_16384_512_int8.h index 5fed45717..798efbaef 100644 --- a/tables/BandLimited_TRI/512/tri_max_126_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_126_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_126_AT_16384_512INT8_H_ #define TRI_MAX_126_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_130_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_130_at_16384_512_int8.h index d28e43e56..1529db173 100644 --- a/tables/BandLimited_TRI/512/tri_max_130_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_130_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_130_AT_16384_512INT8_H_ #define TRI_MAX_130_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_134_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_134_at_16384_512_int8.h index b5c3dfb5c..6bef92f32 100644 --- a/tables/BandLimited_TRI/512/tri_max_134_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_134_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_134_AT_16384_512INT8_H_ #define TRI_MAX_134_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_138_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_138_at_16384_512_int8.h index e11f9a0c2..e4272a4ed 100644 --- a/tables/BandLimited_TRI/512/tri_max_138_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_138_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_138_AT_16384_512INT8_H_ #define TRI_MAX_138_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_143_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_143_at_16384_512_int8.h index ae3018dd0..f7bd1674d 100644 --- a/tables/BandLimited_TRI/512/tri_max_143_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_143_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_143_AT_16384_512INT8_H_ #define TRI_MAX_143_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_148_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_148_at_16384_512_int8.h index 077ebcfec..414516dc0 100644 --- a/tables/BandLimited_TRI/512/tri_max_148_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_148_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_148_AT_16384_512INT8_H_ #define TRI_MAX_148_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_154_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_154_at_16384_512_int8.h index 3da152548..00300cc19 100644 --- a/tables/BandLimited_TRI/512/tri_max_154_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_154_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_154_AT_16384_512INT8_H_ #define TRI_MAX_154_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_160_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_160_at_16384_512_int8.h index 36b380a4d..a29a27294 100644 --- a/tables/BandLimited_TRI/512/tri_max_160_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_160_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_160_AT_16384_512INT8_H_ #define TRI_MAX_160_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_1638_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_1638_at_16384_512_int8.h index d55208703..1544e19c4 100644 --- a/tables/BandLimited_TRI/512/tri_max_1638_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_1638_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_1638_AT_16384_512INT8_H_ #define TRI_MAX_1638_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_167_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_167_at_16384_512_int8.h index 87b0e9770..f66fbc8ee 100644 --- a/tables/BandLimited_TRI/512/tri_max_167_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_167_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_167_AT_16384_512INT8_H_ #define TRI_MAX_167_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_174_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_174_at_16384_512_int8.h index d089e28e3..72e65bc21 100644 --- a/tables/BandLimited_TRI/512/tri_max_174_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_174_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_174_AT_16384_512INT8_H_ #define TRI_MAX_174_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_182_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_182_at_16384_512_int8.h index 6d305f8c7..5ad8a97e0 100644 --- a/tables/BandLimited_TRI/512/tri_max_182_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_182_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_182_AT_16384_512INT8_H_ #define TRI_MAX_182_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_190_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_190_at_16384_512_int8.h index f1d548821..e438f0b8a 100644 --- a/tables/BandLimited_TRI/512/tri_max_190_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_190_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_190_AT_16384_512INT8_H_ #define TRI_MAX_190_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_199_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_199_at_16384_512_int8.h index abe01256e..d6d03467c 100644 --- a/tables/BandLimited_TRI/512/tri_max_199_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_199_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_199_AT_16384_512INT8_H_ #define TRI_MAX_199_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_210_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_210_at_16384_512_int8.h index 99f5fc975..d0686dfa8 100644 --- a/tables/BandLimited_TRI/512/tri_max_210_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_210_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_210_AT_16384_512INT8_H_ #define TRI_MAX_210_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_221_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_221_at_16384_512_int8.h index e962e02ce..0ca31e0f0 100644 --- a/tables/BandLimited_TRI/512/tri_max_221_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_221_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_221_AT_16384_512INT8_H_ #define TRI_MAX_221_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_234_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_234_at_16384_512_int8.h index 185a8bc0c..c257f5445 100644 --- a/tables/BandLimited_TRI/512/tri_max_234_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_234_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_234_AT_16384_512INT8_H_ #define TRI_MAX_234_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_248_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_248_at_16384_512_int8.h index 76783e592..4f3396467 100644 --- a/tables/BandLimited_TRI/512/tri_max_248_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_248_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_248_AT_16384_512INT8_H_ #define TRI_MAX_248_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_264_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_264_at_16384_512_int8.h index f2ad1dbb7..ab651958c 100644 --- a/tables/BandLimited_TRI/512/tri_max_264_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_264_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_264_AT_16384_512INT8_H_ #define TRI_MAX_264_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_2730_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_2730_at_16384_512_int8.h index cbae314f7..ffc5f0c9b 100644 --- a/tables/BandLimited_TRI/512/tri_max_2730_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_2730_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_2730_AT_16384_512INT8_H_ #define TRI_MAX_2730_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_282_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_282_at_16384_512_int8.h index ed4959e31..ea1e8e209 100644 --- a/tables/BandLimited_TRI/512/tri_max_282_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_282_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_282_AT_16384_512INT8_H_ #define TRI_MAX_282_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_303_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_303_at_16384_512_int8.h index 4b1596205..05957ed48 100644 --- a/tables/BandLimited_TRI/512/tri_max_303_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_303_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_303_AT_16384_512INT8_H_ #define TRI_MAX_303_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_327_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_327_at_16384_512_int8.h index 33b1d8b01..467a659e4 100644 --- a/tables/BandLimited_TRI/512/tri_max_327_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_327_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_327_AT_16384_512INT8_H_ #define TRI_MAX_327_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_356_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_356_at_16384_512_int8.h index 6ec7608b0..8bcee1396 100644 --- a/tables/BandLimited_TRI/512/tri_max_356_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_356_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_356_AT_16384_512INT8_H_ #define TRI_MAX_356_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_390_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_390_at_16384_512_int8.h index 257092529..73301c9af 100644 --- a/tables/BandLimited_TRI/512/tri_max_390_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_390_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_390_AT_16384_512INT8_H_ #define TRI_MAX_390_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_431_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_431_at_16384_512_int8.h index a027825ab..b370a6d2b 100644 --- a/tables/BandLimited_TRI/512/tri_max_431_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_431_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_431_AT_16384_512INT8_H_ #define TRI_MAX_431_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_481_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_481_at_16384_512_int8.h index 04678eb67..36d915d71 100644 --- a/tables/BandLimited_TRI/512/tri_max_481_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_481_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_481_AT_16384_512INT8_H_ #define TRI_MAX_481_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_546_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_546_at_16384_512_int8.h index 792a71e89..9920fbc23 100644 --- a/tables/BandLimited_TRI/512/tri_max_546_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_546_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_546_AT_16384_512INT8_H_ #define TRI_MAX_546_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_630_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_630_at_16384_512_int8.h index 2a9b2f505..746ceeb11 100644 --- a/tables/BandLimited_TRI/512/tri_max_630_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_630_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_630_AT_16384_512INT8_H_ #define TRI_MAX_630_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_744_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_744_at_16384_512_int8.h index b6cef7e24..9468bbf55 100644 --- a/tables/BandLimited_TRI/512/tri_max_744_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_744_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_744_AT_16384_512INT8_H_ #define TRI_MAX_744_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_8192_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_8192_at_16384_512_int8.h index d0126e8b0..5c287a760 100644 --- a/tables/BandLimited_TRI/512/tri_max_8192_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_8192_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_8192_AT_16384_512INT8_H_ #define TRI_MAX_8192_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/BandLimited_TRI/512/tri_max_910_at_16384_512_int8.h b/tables/BandLimited_TRI/512/tri_max_910_at_16384_512_int8.h index 3280a9ebe..dd26f2879 100644 --- a/tables/BandLimited_TRI/512/tri_max_910_at_16384_512_int8.h +++ b/tables/BandLimited_TRI/512/tri_max_910_at_16384_512_int8.h @@ -1,11 +1,7 @@ #ifndef TRI_MAX_910_AT_16384_512INT8_H_ #define TRI_MAX_910_AT_16384_512INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/brownnoise8192_int8.h b/tables/brownnoise8192_int8.h index 2f5419107..825014008 100644 --- a/tables/brownnoise8192_int8.h +++ b/tables/brownnoise8192_int8.h @@ -1,11 +1,7 @@ #ifndef BROWNNOISE8192_H_ #define BROWNNOISE8192_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* Brown noise generated in Audacity diff --git a/tables/chum78_int8.h b/tables/chum78_int8.h index 47a4a987b..e7dec25d0 100644 --- a/tables/chum78_int8.h +++ b/tables/chum78_int8.h @@ -1,11 +1,7 @@ #ifndef CHUM78_H_ #define CHUM78_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* A sampled guitar sound diff --git a/tables/chum9_int8.h b/tables/chum9_int8.h index 8124d716d..d59614fe0 100644 --- a/tables/chum9_int8.h +++ b/tables/chum9_int8.h @@ -1,11 +1,7 @@ #ifndef CHUM9_H_ #define CHUM9_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* A sampled guitar sound diff --git a/tables/cos1024_int8.h b/tables/cos1024_int8.h index 14e822b3e..807fc47f0 100644 --- a/tables/cos1024_int8.h +++ b/tables/cos1024_int8.h @@ -1,11 +1,7 @@ #ifndef COS1024_H_ #define COS1024_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define COS1024_NUM_CELLS 1024 diff --git a/tables/cos2048_int8.h b/tables/cos2048_int8.h index 85450be03..e7974c0bb 100644 --- a/tables/cos2048_int8.h +++ b/tables/cos2048_int8.h @@ -1,11 +1,7 @@ #ifndef COS2048_H_ #define COS2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define COS2048_NUM_CELLS 2048 diff --git a/tables/cos256_int8.h b/tables/cos256_int8.h index 5e9ba062c..342159682 100644 --- a/tables/cos256_int8.h +++ b/tables/cos256_int8.h @@ -1,11 +1,7 @@ #ifndef COS256_H_ #define COS256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define COS256_NUM_CELLS 256 diff --git a/tables/cos4096_int16.h b/tables/cos4096_int16.h index 2523be799..cab64f903 100644 --- a/tables/cos4096_int16.h +++ b/tables/cos4096_int16.h @@ -1,11 +1,7 @@ #ifndef COS4096X16_H_ #define COS4096X16_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define COS4096X16_NUM_CELLS 4096 #define COS4096X16_SAMPLERATE 4096 diff --git a/tables/cos4096_int8.h b/tables/cos4096_int8.h index de8c687d5..736095e11 100644 --- a/tables/cos4096_int8.h +++ b/tables/cos4096_int8.h @@ -1,11 +1,7 @@ #ifndef COS4096_H_ #define COS4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define COS4096_NUM_CELLS 4096 diff --git a/tables/cos512_int8.h b/tables/cos512_int8.h index 7218b5584..293521df6 100644 --- a/tables/cos512_int8.h +++ b/tables/cos512_int8.h @@ -1,11 +1,7 @@ #ifndef COS512_H_ #define COS512_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define COS512_NUM_CELLS 512 diff --git a/tables/cos8192_int8.h b/tables/cos8192_int8.h index 02df086d4..9e5eebb65 100644 --- a/tables/cos8192_int8.h +++ b/tables/cos8192_int8.h @@ -1,11 +1,7 @@ #ifndef COS8192_INT8_H_ #define COS8192_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define COS8192_NUM_CELLS 8192 diff --git a/tables/cosphase2048_int8.h b/tables/cosphase2048_int8.h index 003162778..0b65c664c 100644 --- a/tables/cosphase2048_int8.h +++ b/tables/cosphase2048_int8.h @@ -1,11 +1,7 @@ #ifndef COSPHASE2048_H_ #define COSPHASE2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /** Cosine wave, out-of-phase so it starts at 127, cycles to -128 and ends at 127 diff --git a/tables/cosphase256_int8.h b/tables/cosphase256_int8.h index a8aae05cc..3124b1eec 100644 --- a/tables/cosphase256_int8.h +++ b/tables/cosphase256_int8.h @@ -1,11 +1,7 @@ #ifndef COSPHASE256_H_ #define COSPHASE256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* cos out-of-phase diff --git a/tables/cosphase8192_int8.h b/tables/cosphase8192_int8.h index 54119a0bb..3ad82b7f5 100644 --- a/tables/cosphase8192_int8.h +++ b/tables/cosphase8192_int8.h @@ -1,11 +1,7 @@ #ifndef COSPHASE8192_H_ #define COSPHASE8192_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* cos out-of-phase diff --git a/tables/envelop2048_uint8.h b/tables/envelop2048_uint8.h index 053d3cdae..11664b7cc 100644 --- a/tables/envelop2048_uint8.h +++ b/tables/envelop2048_uint8.h @@ -1,11 +1,7 @@ #ifndef ENVELOP2048_INT8_H_ #define ENVELOP2048_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* a hand-drawn envelope with fast attack and slow decay diff --git a/tables/halfsin256_uint8.h b/tables/halfsin256_uint8.h index 53f9c3744..cb933d1cf 100644 --- a/tables/halfsin256_uint8.h +++ b/tables/halfsin256_uint8.h @@ -1,11 +1,7 @@ #ifndef HALFSIN256_H_ #define HALFSIN256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define HALFSIN256_NUM_CELLS 256 diff --git a/tables/halfsinwindow512_uint8.h b/tables/halfsinwindow512_uint8.h index 9806ee8fc..58acada5b 100644 --- a/tables/halfsinwindow512_uint8.h +++ b/tables/halfsinwindow512_uint8.h @@ -1,11 +1,7 @@ #ifndef HALFSINWINDOW512_H_ #define HALFSINWINDOW512_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" // this is the top half of a sin, used as a rough envelope for a cycling fade-in, fade-out with empty space in between. diff --git a/tables/noise_static_1_16384_int8.h b/tables/noise_static_1_16384_int8.h index eb100a432..2f53628ce 100644 --- a/tables/noise_static_1_16384_int8.h +++ b/tables/noise_static_1_16384_int8.h @@ -1,11 +1,7 @@ #ifndef NOISE_STATIC_1_16384_H_ #define NOISE_STATIC_1_16384_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* static noise from needle on old record diff --git a/tables/phasor256_int8.h b/tables/phasor256_int8.h index 0e13304f9..4af9185a5 100644 --- a/tables/phasor256_int8.h +++ b/tables/phasor256_int8.h @@ -1,11 +1,7 @@ #ifndef PHASOR256_H_ #define PHASOR256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* ramp diff --git a/tables/pinknoise8192_int8.h b/tables/pinknoise8192_int8.h index 4848bcace..ac22804e7 100644 --- a/tables/pinknoise8192_int8.h +++ b/tables/pinknoise8192_int8.h @@ -1,11 +1,7 @@ #ifndef PINKNOISE8192_H_ #define PINKNOISE8192_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* generated pink noise diff --git a/tables/saw1024_int8.h b/tables/saw1024_int8.h index 9314db744..dda63e363 100644 --- a/tables/saw1024_int8.h +++ b/tables/saw1024_int8.h @@ -1,11 +1,7 @@ #ifndef SAW1024_H_ #define SAW1024_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SAW1024_NUM_CELLS 1024 diff --git a/tables/saw2048_int8.h b/tables/saw2048_int8.h index 7eb5bcdfd..d14688634 100644 --- a/tables/saw2048_int8.h +++ b/tables/saw2048_int8.h @@ -1,11 +1,7 @@ #ifndef SAW2048_H_ #define SAW2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SAW2048_NUM_CELLS 2048 diff --git a/tables/saw256_int8.h b/tables/saw256_int8.h index 8fc586d9e..0abda15f1 100644 --- a/tables/saw256_int8.h +++ b/tables/saw256_int8.h @@ -1,11 +1,7 @@ #ifndef SAW256_H_ #define SAW256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SAW256_NUM_CELLS 256 diff --git a/tables/saw4096_int8.h b/tables/saw4096_int8.h index 31b2ff9e3..95d5ec117 100644 --- a/tables/saw4096_int8.h +++ b/tables/saw4096_int8.h @@ -1,11 +1,7 @@ #ifndef SAW4096_H_ #define SAW4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SAW4096_NUM_CELLS 4096 diff --git a/tables/saw512_int8.h b/tables/saw512_int8.h index 70ad271f4..7bd1d2691 100644 --- a/tables/saw512_int8.h +++ b/tables/saw512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW512_H_ #define SAW512_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SAW512_NUM_CELLS 512 diff --git a/tables/saw8192_int8.h b/tables/saw8192_int8.h index b85efa60b..22731ce5b 100644 --- a/tables/saw8192_int8.h +++ b/tables/saw8192_int8.h @@ -1,11 +1,7 @@ #ifndef SAW8192_H_ #define SAW8192_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SAW8192_NUM_CELLS 8192 diff --git a/tables/saw_analogue512_int8.h b/tables/saw_analogue512_int8.h index ee842a99f..c89d06cb4 100644 --- a/tables/saw_analogue512_int8.h +++ b/tables/saw_analogue512_int8.h @@ -1,11 +1,7 @@ #ifndef SAW_ANALOGUE512_INT8_H_ #define SAW_ANALOGUE512_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* generated "analogue" saw wave from Audacity diff --git a/tables/sin1024_int8.h b/tables/sin1024_int8.h index a7c848d40..717065287 100644 --- a/tables/sin1024_int8.h +++ b/tables/sin1024_int8.h @@ -1,11 +1,7 @@ #ifndef SIN1024_H_ #define SIN1024_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SIN1024_NUM_CELLS 1024 diff --git a/tables/sin1024_uint8.h b/tables/sin1024_uint8.h index 0b27a8094..ac4a4a762 100644 --- a/tables/sin1024_uint8.h +++ b/tables/sin1024_uint8.h @@ -1,11 +1,7 @@ #ifndef sin1024_uint_H_ #define sin1024_uint_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define sin1024_uint_NUM_CELLS 1024 diff --git a/tables/sin2048_int8.h b/tables/sin2048_int8.h index c59701b8b..00e428a0c 100644 --- a/tables/sin2048_int8.h +++ b/tables/sin2048_int8.h @@ -1,11 +1,7 @@ #ifndef SIN2048_H_ #define SIN2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SIN2048_NUM_CELLS 2048 diff --git a/tables/sin256_int8.h b/tables/sin256_int8.h index fa2a8b026..9588d68a6 100644 --- a/tables/sin256_int8.h +++ b/tables/sin256_int8.h @@ -1,11 +1,7 @@ #ifndef SIN256_INT8_H_ #define SIN256_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SIN256_NUM_CELLS 256 diff --git a/tables/sin4096_int8.h b/tables/sin4096_int8.h index adfe566a4..172a31ce1 100644 --- a/tables/sin4096_int8.h +++ b/tables/sin4096_int8.h @@ -1,11 +1,7 @@ #ifndef SIN4096_H_ #define SIN4096_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SIN4096_NUM_CELLS 4096 diff --git a/tables/sin512_int8.h b/tables/sin512_int8.h index 86a44c0fd..712968c45 100644 --- a/tables/sin512_int8.h +++ b/tables/sin512_int8.h @@ -1,11 +1,7 @@ #ifndef SIN512_INT8_H_ #define SIN512_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SIN512_NUM_CELLS 512 diff --git a/tables/sin8192_int8.h b/tables/sin8192_int8.h index 2d09f2c39..9f8185e72 100644 --- a/tables/sin8192_int8.h +++ b/tables/sin8192_int8.h @@ -1,11 +1,7 @@ #ifndef SIN8192_INT8_H_ #define SIN8192_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SIN8192_NUM_CELLS 8192 diff --git a/tables/sin8192_uint8.h b/tables/sin8192_uint8.h index 1177366f2..992f61f5b 100644 --- a/tables/sin8192_uint8.h +++ b/tables/sin8192_uint8.h @@ -1,11 +1,7 @@ #ifndef sin8192_uint_H_ #define sin8192_uint_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" diff --git a/tables/sintest_int8.h b/tables/sintest_int8.h index 1a070f404..717a1ea47 100644 --- a/tables/sintest_int8.h +++ b/tables/sintest_int8.h @@ -2,11 +2,7 @@ #ifndef SINTEST_H_ #define SINTEST_H_ /* -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" template diff --git a/tables/smoothsquare8192_int8.h b/tables/smoothsquare8192_int8.h index 9c3dbc57a..0ae8a31da 100644 --- a/tables/smoothsquare8192_int8.h +++ b/tables/smoothsquare8192_int8.h @@ -1,11 +1,7 @@ #ifndef SMOOTHSQUARE8192_H_ #define SMOOTHSQUARE8192_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* hand-drawn square wave with rounded corners from Audacity diff --git a/tables/square_analogue512_int8.h b/tables/square_analogue512_int8.h index 1d4b30d5f..3db363005 100644 --- a/tables/square_analogue512_int8.h +++ b/tables/square_analogue512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_ANALOGUE512_INT8_H_ #define SQUARE_ANALOGUE512_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* generated "analogue" square wave from Audacity diff --git a/tables/square_no_alias512_int8.h b/tables/square_no_alias512_int8.h index a2e8732d7..e3e4b8521 100644 --- a/tables/square_no_alias512_int8.h +++ b/tables/square_no_alias512_int8.h @@ -1,11 +1,7 @@ #ifndef SQUARE_NO_ALIAS512_INT8_H_ #define SQUARE_NO_ALIAS512_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* square wave with rounded corners from Audacity diff --git a/tables/square_no_alias_2048_int8.h b/tables/square_no_alias_2048_int8.h index 392527fd5..0fc2fbf5a 100644 --- a/tables/square_no_alias_2048_int8.h +++ b/tables/square_no_alias_2048_int8.h @@ -4,11 +4,7 @@ If anyone knows an efficient way to do bandlimited synthesis which could work fo #ifndef SQUARE_NO_ALIAS_2048_H_ #define SQUARE_NO_ALIAS_2048_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define SQUARE_NO_ALIAS_2048_NUM_CELLS 2048 diff --git a/tables/triangle1024_int8.h b/tables/triangle1024_int8.h index d75f04e90..f3e594e7d 100644 --- a/tables/triangle1024_int8.h +++ b/tables/triangle1024_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE1024_H_ #define TRIANGLE1024_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define TRIANGLE1024_NUM_CELLS 1024 diff --git a/tables/triangle2048_int8.h b/tables/triangle2048_int8.h index 48112b806..ca86746ff 100644 --- a/tables/triangle2048_int8.h +++ b/tables/triangle2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE2048_H_ #define TRIANGLE2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define TRIANGLE2048_NUM_CELLS 2048 diff --git a/tables/triangle512_int8.h b/tables/triangle512_int8.h index 42f8fc71f..a7fbf8190 100644 --- a/tables/triangle512_int8.h +++ b/tables/triangle512_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE512_H_ #define TRIANGLE512_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define TRIANGLE512_NUM_CELLS 512 diff --git a/tables/triangle_analogue512_int8.h b/tables/triangle_analogue512_int8.h index a21684cde..40e70b6a3 100644 --- a/tables/triangle_analogue512_int8.h +++ b/tables/triangle_analogue512_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE_ANALOGUE512_INT8_H_ #define TRIANGLE_ANALOGUE512_INT8_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* generated "analogue" triangle wave from Audacity diff --git a/tables/triangle_dist_cubed_2048_int8.h b/tables/triangle_dist_cubed_2048_int8.h index 8424161e3..04279c783 100644 --- a/tables/triangle_dist_cubed_2048_int8.h +++ b/tables/triangle_dist_cubed_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE_DIST_CUBED_2048_H_ #define TRIANGLE_DIST_CUBED_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* triangle wave with distortion from Audacity diff --git a/tables/triangle_dist_squared_2048_int8.h b/tables/triangle_dist_squared_2048_int8.h index 58d33ffa2..95705dbb5 100644 --- a/tables/triangle_dist_squared_2048_int8.h +++ b/tables/triangle_dist_squared_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE_DIST_SQUARED_2048_H_ #define TRIANGLE_DIST_SQUARED_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* triangle wave with distortion from Audacity diff --git a/tables/triangle_hermes_2048_int8.h b/tables/triangle_hermes_2048_int8.h index c9f591741..db10950d4 100644 --- a/tables/triangle_hermes_2048_int8.h +++ b/tables/triangle_hermes_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE_HERMES_2048_H_ #define TRIANGLE_HERMES_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* triangle wave with distortion from Audacity diff --git a/tables/triangle_valve_2048_int8.h b/tables/triangle_valve_2048_int8.h index 1fd935684..94df2374a 100644 --- a/tables/triangle_valve_2048_int8.h +++ b/tables/triangle_valve_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE_VALVE_2048_H_ #define TRIANGLE_VALVE_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* triangle wave with distortion from Audacity diff --git a/tables/triangle_valve_2_2048_int8.h b/tables/triangle_valve_2_2048_int8.h index 0a207390e..5d5c0fc5b 100644 --- a/tables/triangle_valve_2_2048_int8.h +++ b/tables/triangle_valve_2_2048_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE_VALVE_2_2048_H_ #define TRIANGLE_VALVE_2_2048_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* triangle wave with distortion from Audacity diff --git a/tables/triangle_warm8192_int8.h b/tables/triangle_warm8192_int8.h index a8dd03d5f..d7a4a8cac 100644 --- a/tables/triangle_warm8192_int8.h +++ b/tables/triangle_warm8192_int8.h @@ -1,11 +1,7 @@ #ifndef TRIANGLE_WARM8192_INT8_H_ #define TRIANGLE_WARM8192_INT8_H_ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* triangle wave with "warmth" from Audacity diff --git a/tables/uphasor256_uint8.h b/tables/uphasor256_uint8.h index fe3748a14..011c2a552 100644 --- a/tables/uphasor256_uint8.h +++ b/tables/uphasor256_uint8.h @@ -1,11 +1,7 @@ #ifndef UPHASOR256_H_ #define UPHASOR256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* ramp diff --git a/tables/waveshape1_softclip_int8.h b/tables/waveshape1_softclip_int8.h index 2ce796073..ef9ebc710 100644 --- a/tables/waveshape1_softclip_int8.h +++ b/tables/waveshape1_softclip_int8.h @@ -1,11 +1,7 @@ #ifndef WAVESHAPE1_SOFTCLIP_H_ #define WAVESHAPE1_SOFTCLIP_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* table for waveshaper to impose soft clipping diff --git a/tables/waveshape2_softerclip_int8.h b/tables/waveshape2_softerclip_int8.h index 8a0cd2370..8534e9b59 100644 --- a/tables/waveshape2_softerclip_int8.h +++ b/tables/waveshape2_softerclip_int8.h @@ -1,11 +1,7 @@ #ifndef WAVESHAPE2_SOFTERCLIP_H_ #define WAVESHAPE2_SOFTERCLIP_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* table for waveshaper to impose softer clipping diff --git a/tables/waveshape_chebyshev_3rd_256_int8.h b/tables/waveshape_chebyshev_3rd_256_int8.h index b699cb022..645c015a2 100644 --- a/tables/waveshape_chebyshev_3rd_256_int8.h +++ b/tables/waveshape_chebyshev_3rd_256_int8.h @@ -1,11 +1,7 @@ #ifndef CHEBYSHEV_3RD_256_H_ #define CHEBYSHEV_3RD_256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* table for waveshaper using chebyshev polynomials diff --git a/tables/waveshape_chebyshev_4th_256_int8.h b/tables/waveshape_chebyshev_4th_256_int8.h index 8bb8105fc..e2ab41bf7 100644 --- a/tables/waveshape_chebyshev_4th_256_int8.h +++ b/tables/waveshape_chebyshev_4th_256_int8.h @@ -1,11 +1,7 @@ #ifndef CHEBYSHEV_4TH_256_H_ #define CHEBYSHEV_4TH_256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* table for waveshaper using chebyshev polynomials diff --git a/tables/waveshape_chebyshev_5th_256_int8.h b/tables/waveshape_chebyshev_5th_256_int8.h index 37854a01c..34fe8f275 100644 --- a/tables/waveshape_chebyshev_5th_256_int8.h +++ b/tables/waveshape_chebyshev_5th_256_int8.h @@ -1,11 +1,7 @@ #ifndef CHEBYSHEV_5TH_256_H_ #define CHEBYSHEV_5TH_256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* table for waveshaper using chebyshev polynomials diff --git a/tables/waveshape_chebyshev_6th_256_int8.h b/tables/waveshape_chebyshev_6th_256_int8.h index 8fcd0ca6a..04e4d340c 100644 --- a/tables/waveshape_chebyshev_6th_256_int8.h +++ b/tables/waveshape_chebyshev_6th_256_int8.h @@ -1,11 +1,7 @@ #ifndef CHEBYSHEV_6TH_256_H_ #define CHEBYSHEV_6TH_256_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* table for waveshaper using chebyshev polynomials diff --git a/tables/waveshape_compress_512_to_488_int16.h b/tables/waveshape_compress_512_to_488_int16.h index 8e046965b..248650250 100644 --- a/tables/waveshape_compress_512_to_488_int16.h +++ b/tables/waveshape_compress_512_to_488_int16.h @@ -1,11 +1,7 @@ #ifndef WAVESHAPE_COMPRESS_512_TO_488_H_ #define WAVESHAPE_COMPRESS_512_TO_488_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" /* table for waveshaper to impart compression diff --git a/tables/waveshape_sigmoid_int8.h b/tables/waveshape_sigmoid_int8.h index a60526814..166d02722 100644 --- a/tables/waveshape_sigmoid_int8.h +++ b/tables/waveshape_sigmoid_int8.h @@ -1,11 +1,7 @@ #ifndef WAVESHAPE_SIGMOID_H_ #define WAVESHAPE_SIGMOID_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define WAVESHAPE_SIGMOID_NUM_CELLS 256 diff --git a/tables/waveshape_tanh_int8.h b/tables/waveshape_tanh_int8.h index 423286682..5f6a19f2b 100644 --- a/tables/waveshape_tanh_int8.h +++ b/tables/waveshape_tanh_int8.h @@ -1,11 +1,7 @@ #ifndef WAVESHAPE_TANH_H_ #define WAVESHAPE_TANH_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define WAVESHAPE_TANH_NUM_CELLS 256 diff --git a/tables/whitenoise8192_int8.h b/tables/whitenoise8192_int8.h index 6e3b418e4..44ef4eb74 100644 --- a/tables/whitenoise8192_int8.h +++ b/tables/whitenoise8192_int8.h @@ -1,11 +1,7 @@ #ifndef WHITENOISE8192_H_ #define WHITENOISE8192_H_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "mozzi_pgmspace.h" #define WHITENOISE8192_NUM_CELLS 8192 diff --git a/utility/FrequencyTimer2.h b/utility/FrequencyTimer2.h index 58367432f..ed3cf4e18 100644 --- a/utility/FrequencyTimer2.h +++ b/utility/FrequencyTimer2.h @@ -27,11 +27,7 @@ MODIFIED by Tim Barrass 2013,2014: see .cpp file */ -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include /* // Arduino Mega From ae47538101a42a0171384278177aeac160dc7608 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Wed, 14 Feb 2024 19:58:13 +0100 Subject: [PATCH 146/215] Add teensy 3 auto-build --- .github/workflows/compile_examples.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/compile_examples.yml b/.github/workflows/compile_examples.yml index c9b1f9f9f..ac607edd7 100644 --- a/.github/workflows/compile_examples.yml +++ b/.github/workflows/compile_examples.yml @@ -88,6 +88,11 @@ jobs: platforms: | - name: arduino:renesas_uno internalid: arduino_unor4 + - fqbn: teensy:avr:teensy36 + platforms: | + - name: teensy:avr + source-url: https://www.pjrc.com/teensy/package_teensy_index.json + internalid: teensy36 steps: - name: Checkout repository From f3c13b039c1d845831d4b1e5bdb9d47c373aebce Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Wed, 14 Feb 2024 20:41:38 +0100 Subject: [PATCH 147/215] Add Teensy 4.1 and Arduino Mega builds --- .github/workflows/compile_examples.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/compile_examples.yml b/.github/workflows/compile_examples.yml index ac607edd7..18aa43370 100644 --- a/.github/workflows/compile_examples.yml +++ b/.github/workflows/compile_examples.yml @@ -57,7 +57,11 @@ jobs: - fqbn: arduino:avr:uno platforms: | - name: arduino:avr - internalid: arduino_avr # This is just some unique id string we assign for use in the artifact name (fqbn does not qualify due to containing colons) + internalid: arduino_uno # This is just some unique id string we assign for use in the artifact name (fqbn does not qualify due to containing colons) + - fqbn: arduino:avr:mega + platforms: | + - name: arduino:avr + internalid: arduino_mega - fqbn: esp8266:esp8266:huzzah type: 8266 platforms: | @@ -93,6 +97,11 @@ jobs: - name: teensy:avr source-url: https://www.pjrc.com/teensy/package_teensy_index.json internalid: teensy36 + - fqbn: teensy:avr:teensy41 + platforms: | + - name: teensy:avr + source-url: https://www.pjrc.com/teensy/package_teensy_index.json + internalid: teensy41 steps: - name: Checkout repository From 5166c0d253a37966f6aed976ffab0d27e1737688 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Wed, 14 Feb 2024 20:42:15 +0100 Subject: [PATCH 148/215] Try again updating checkout action --- .github/workflows/compile_examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compile_examples.yml b/.github/workflows/compile_examples.yml index 18aa43370..68454ae72 100644 --- a/.github/workflows/compile_examples.yml +++ b/.github/workflows/compile_examples.yml @@ -105,7 +105,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Add marker file for github run run: echo "#define IN_GITHUB_RUNNER 1" > detect_github_runner.h From 3784ade6bc5cf6930010ff0c8f145279f6396388 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Thu, 15 Feb 2024 21:13:30 +0100 Subject: [PATCH 149/215] Fix portamento example --- .../05.Control_Filters/MIDI_portamento/MIDI_portamento.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino index 1cecc9fc5..a13eb59fe 100644 --- a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino +++ b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino @@ -40,9 +40,9 @@ MIDI_CREATE_DEFAULT_INSTANCE(); Oscil aSin(SIN2048_DATA); // envelope generator -ADSR envelope; +ADSR envelope; -Portamento aPortamento; +Portamento aPortamento; #define LED 13 From 285795e74be8c7ddf6ee03be6237e69d19a7a5f7 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 18 Feb 2024 16:02:24 +0100 Subject: [PATCH 150/215] Added specializations to Line for U/SFix --- Line.h | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) diff --git a/Line.h b/Line.h index f433907d3..d0c632756 100644 --- a/Line.h +++ b/Line.h @@ -18,6 +18,8 @@ #include "WProgram.h" #endif +#include + /** For linear changes with a minimum of calculation at each step. For instance, you can use Line to make an oscillator glide from one frequency to another, pre-calculating the required phase increments for each end and then letting your @@ -33,6 +35,9 @@ represent fractional numbers. Google "fixed point arithmetic" if this is new to you. */ + + + template class Line { @@ -315,6 +320,174 @@ class Line } }; + +/* UFix specialisation */ +template +class Line> +{ +private: + typedef UFix internal_type; + internal_type current_value; + internal_type step_size; + +public: + /** Constructor. Use the template parameter to set the type of numbers you + want to use. For example, Line \ myline; makes a Line which uses ints. + */ + Line (){;} + + /** Increments one step along the line. + @return the next value. + */ + inline + internal_type next() + { + current_value = current_value + step_size; + return current_value; + } + + /** Set the current value of the line. + The Line will continue incrementing from this + value using any previously calculated step size. + @param value the number to set the Line's current_value to. + */ + inline + void set(internal_type value) + { + current_value=value; + } + + /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. + @param targetvalue the value to move towards. + @param num_steps how many steps to take to reach the target as a UFix<_NI,0> + */ + template + void set(internal_type targetvalue, UFix<_NI,0> num_steps) + { + if(num_steps.asRaw()) { + internal_type numerator = targetvalue-current_value; + step_size = numerator*num_steps.invAccurate(); + } else { + step_size = 0; + current_value = targetvalue; + } + } + + + /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. + @param targetvalue the value to move towards. + @param num_steps how many steps to take to reach the target. + */ + template + void set(internal_type targetvalue, T num_steps) + { + if(num_steps) { + internal_type numerator = targetvalue-current_value; + step_size = internal_type(numerator.asRaw()/num_steps,true); + } else { + step_size = 0; + current_value = targetvalue; + } + } + + /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. + @param startvalue the number to set the Line's current_value to. + @param targetvalue the value to move towards. + @param num_steps how many steps to take to reach the target. + */ + template + void set(internal_type startvalue, internal_type targetvalue, T num_steps) + { + set(startvalue); + set(targetvalue, num_steps); + } +}; + + +/* SFix specialisation (if someone has an idea to avoid duplication with UFix) */ +template +class Line> +{ +private: + typedef SFix internal_type; + internal_type current_value; + internal_type step_size; + +public: + /** Constructor. Use the template parameter to set the type of numbers you + want to use. For example, Line \ myline; makes a Line which uses ints. + */ + Line (){;} + + /** Increments one step along the line. + @return the next value. + */ + inline + internal_type next() + { + current_value = current_value + step_size; + return current_value; + } + + /** Set the current value of the line. + The Line will continue incrementing from this + value using any previously calculated step size. + @param value the number to set the Line's current_value to. + */ + inline + void set(internal_type value) + { + current_value=value; + } + + /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. + @param targetvalue the value to move towards. + @param num_steps how many steps to take to reach the target as a UFix<_NI,0> + */ + template + void set(internal_type targetvalue, UFix<_NI,0> num_steps) + { + if(num_steps.asRaw()) { + internal_type numerator = targetvalue-current_value; + step_size = numerator*num_steps.invAccurate(); + } else { + step_size = 0; + current_value = targetvalue; + } + } + + + /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. + @param targetvalue the value to move towards. + @param num_steps how many steps to take to reach the target. + */ + template + void set(internal_type targetvalue, T num_steps) + { + if(num_steps) { + internal_type numerator = targetvalue-current_value; + step_size = internal_type(numerator.asRaw()/num_steps,true); + } else { + step_size = 0; + current_value = targetvalue; + } + } + + /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. + @param startvalue the number to set the Line's current_value to. + @param targetvalue the value to move towards. + @param num_steps how many steps to take to reach the target. + */ + template + void set(internal_type startvalue, internal_type targetvalue, T num_steps) + { + set(startvalue); + set(targetvalue, num_steps); + } +}; + + + /** @example 02.Control/Control_Tremelo/Control_Tremelo.ino This example demonstrates the Line class. From 59b1778ce1fd176a899efc9c3d3697a97abf506d Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 18 Feb 2024 18:04:10 +0100 Subject: [PATCH 151/215] Added U/SFix specialization to Smooth.h --- Smooth.h | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/Smooth.h b/Smooth.h index c5bc62280..34fab9efe 100644 --- a/Smooth.h +++ b/Smooth.h @@ -268,6 +268,160 @@ class Smooth /** @endcond */ + +/* Specialization for UFix */ +template +class Smooth> +{ +private: + typedef UFix internal_type; + internal_type last_out; + UFix<0,16> a; + +public: + + + /** Constructor. + @param smoothness sets how much smoothing the filter will apply to + its input. Use a float or a UFix<0,NF> in the range 0~1, where 0 is not very smooth and 0.99 is + very smooth. + */ + template + Smooth(T smoothness) + { + setSmoothness(smoothness); + } + + /** Constructor. + This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition. + You need to call setSmoothness(float) for your object before using Smooth. + @note there's probably a better way to do this... + */ + Smooth() + {} + + + /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value). + @param in the signal to be smoothed. + @return the filtered signal. + */ + inline + internal_type next(internal_type in) + { + internal_type out = last_out + a * (in - last_out); // With FixMath, the syntax is actually the same than with floats :) + last_out = out; + return out; + } + + + + inline + internal_type operator()(internal_type n) { + return next(n); + } + + /** Sets how much smoothing the filter will apply to its input. + @param smoothness sets how much smoothing the filter will apply to + its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is + very smooth. + */ + inline + void setSmoothness(float smoothness) + { + a=internal_type(1.f-smoothness); + } + + /** Sets how much smoothing the filter will apply to its input. + @param smoothness sets how much smoothing the filter will apply to + its input. Use a UFix<0,NF> in the range 0~1, where 0 is not very smooth and 0.99 is + very smooth. + */ + template + void setSmoothness(UFix<0,_NF> smoothness) + { + a = UFix<1,0>(1) - smoothness; + } + +}; + + + + +/* Specialization for SFix */ +template +class Smooth> +{ +private: + typedef SFix internal_type; + internal_type last_out; + UFix<0,16> a; + +public: + + + /** Constructor. + @param smoothness sets how much smoothing the filter will apply to + its input. Use a float or a UFix<0,NF> in the range 0~1, where 0 is not very smooth and 0.99 is + very smooth. + */ + template + Smooth(T smoothness) + { + setSmoothness(smoothness); + } + + /** Constructor. + This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition. + You need to call setSmoothness(float) for your object before using Smooth. + @note there's probably a better way to do this... + */ + Smooth() + {} + + + /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value). + @param in the signal to be smoothed. + @return the filtered signal. + */ + inline + internal_type next(internal_type in) + { + internal_type out = last_out + a * (in - last_out); + last_out = out; + return out; + } + + + + inline + internal_type operator()(internal_type n) { + return next(n); + } + + /** Sets how much smoothing the filter will apply to its input. + @param smoothness sets how much smoothing the filter will apply to + its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is + very smooth. + */ + inline + void setSmoothness(float smoothness) + { + a=internal_type(1.f-smoothness); + } + + /** Sets how much smoothing the filter will apply to its input. + @param smoothness sets how much smoothing the filter will apply to + its input. Use a UFix<0,NF> in the range 0~1, where 0 is not very smooth and 0.99 is + very smooth. + */ + template + void setSmoothness(UFix<0,_NF> smoothness) + { + a = UFix<1,0>(1) - smoothness; + } + +}; + /** @example 05.Control_Filters/Smooth/Smooth.ino This example demonstrates the Smooth class. From ebca5ab0ddbf7148482afd2ff1cf8c88d7ef724b Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 19 Feb 2024 23:25:36 +0100 Subject: [PATCH 152/215] Added an example of FM synthesis with FixMath --- examples/06.Synthesis/FMsynth/FMsynth.ino | 3 + .../FMsynth_FixMath/FMsynth_FixMath.ino | 103 ++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino diff --git a/examples/06.Synthesis/FMsynth/FMsynth.ino b/examples/06.Synthesis/FMsynth/FMsynth.ino index b21c40ebf..a411e5ff0 100644 --- a/examples/06.Synthesis/FMsynth/FMsynth.ino +++ b/examples/06.Synthesis/FMsynth/FMsynth.ino @@ -20,6 +20,9 @@ https://groups.google.com/forum/#!forum/mozzi-users Tim Barrass 2012, CC by-nc-sa. + + Note: an similar example, but using the newer FixMath + framework is given is FMsynth_FixMath. */ #include diff --git a/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino b/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino new file mode 100644 index 000000000..552ec2bba --- /dev/null +++ b/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino @@ -0,0 +1,103 @@ +/* Example of simple FM with the phase modulation technique, + using Mozzi sonification library. + + Demonstrates Oscil::phMod() for phase modulation, + Smooth() for smoothing control signals, + and FixMath fixed point number types for fractional frequencies. + This is the same technique than the FMsynth example but + using FixMath instead of mozzi_fixmath. + + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Thomas Combriat and the Mozzi team 2023, CC by-nc-sa. +*/ + + + +#include +#include +#include // table for Oscils to play +#include +#include +#include +#include + + +#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable + +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); +Oscil kModIndex(COS2048_DATA); + +UFix<0, 16> mod_index; +UFix<16, 16> deviation; + +UFix<16, 16> carrier_freq, mod_freq; +const UFix<0,16> modulation_amp = 0.001; // how much the modulation index will vary around its mean +const UFix<2,0> mean_modulation_unscaled = 2; // the real mean modulation will be mean_modulation_unscaled * modulation_max + // this one is adding a bias to the oscillator, hence it should be bigger than one. + +const UFix<2, 0> mod_to_carrier_ratio = 3; // 3 fits in UFix<2,0> which has a maximum range of (2^2)-1=3 + +EventDelay kNoteChangeDelay; + +const UFix<7, 0> note_upper_limit = 50, note_lower_limit = 32; + +UFix<7, 0> note0 = note_lower_limit, note1 = note_lower_limit + UFix<7, 0>(5), target_note = note0; +SFix<2, 0> note_change_step = 3; // will only take +3 or -3, 2bits are enough for that + +UFix<7,8> smoothed_note; + +Smooth> kSmoothNote(0.95f); + +void setup() { + kNoteChangeDelay.set(768); + kModIndex.setFreq(.768f); // sync with kNoteChangeDelay + startMozzi(CONTROL_RATE); +} + +void setFreqs(UFix<7, 8> midi_note) { + carrier_freq = mtof(midi_note); + mod_freq = carrier_freq * mod_to_carrier_ratio; + deviation = mod_freq * mod_index; + aCarrier.setFreq(carrier_freq); + aModulator.setFreq(mod_freq); +} + +void updateControl() { + if (kNoteChangeDelay.ready()) { + if (target_note == note0) + { + note1 = note1 + note_change_step; + target_note = note1; + } + else + { + note0 = note0 + note_change_step; + target_note = note0; + } + if(note0>note_upper_limit) note_change_step = -3; + if(note0 Date: Mon, 19 Feb 2024 23:32:26 +0100 Subject: [PATCH 153/215] Removed volatile in Line.h --- Line.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Line.h b/Line.h index d0c632756..34ae20856 100644 --- a/Line.h +++ b/Line.h @@ -42,8 +42,8 @@ template class Line { private: - volatile T current_value; // volatile because it could be set in control interrupt and updated in audio - volatile T step_size; + T current_value; + T step_size; public: /** Constructor. Use the template parameter to set the type of numbers you @@ -117,7 +117,7 @@ template <> class Line { private: - volatile unsigned char current_value; // volatile because it could be set in control interrupt and updated in audio + unsigned char current_value; char step_size; public: @@ -186,7 +186,7 @@ template <> class Line { private: - volatile unsigned int current_value; // volatile because it could be set in control interrupt and updated in audio + unsigned int current_value; int step_size; public: @@ -258,7 +258,7 @@ template <> class Line { private: - volatile unsigned long current_value; // volatile because it could be set in control interrupt and updated in audio + unsigned long current_value; long step_size; public: From 8d69afca841c5f8cdf740f5a3b6e0f5fb15d43d2 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 24 Feb 2024 22:01:42 +0100 Subject: [PATCH 154/215] Made a more specific template in Oscil for FixMath --- Oscil.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Oscil.h b/Oscil.h index 0e55ec454..4921295b8 100644 --- a/Oscil.h +++ b/Oscil.h @@ -214,11 +214,11 @@ class Oscil @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. @param frequency in UFix fixed-point number format. */ - template + template inline - void setFreq(UFix frequency) + void setFreq(UFix frequency) { - setFreq_Q16n16(UFix<16,16>(frequency).asRaw()); + setFreq_Q16n16(UFix<16,16>(frequency).asRaw()); } From 5f2f36ea78dd20399f062e7b540c7c00445c712a Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sat, 24 Feb 2024 22:02:04 +0100 Subject: [PATCH 155/215] Added Difference_Tone adapted to FixMath Added documentation --- .../Difference_Tone/Difference_Tone.ino | 2 + .../Difference_Tone_FixMath.ino | 71 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 examples/06.Synthesis/Difference_Tone_FixMath/Difference_Tone_FixMath.ino diff --git a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino index 46d2efbc4..9e4028ecd 100644 --- a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino +++ b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino @@ -3,6 +3,8 @@ using Mozzi sonification library. Demonstrates the use of EventDelay(), rand() and fixed-point numbers. + + Note that an example using the newer FixMath paradigm is also available: Difference_Tone_FixMath. Circuit: Audio output on digital pin 9 on a Uno or similar, or DAC/A14 on Teensy 3.1, or diff --git a/examples/06.Synthesis/Difference_Tone_FixMath/Difference_Tone_FixMath.ino b/examples/06.Synthesis/Difference_Tone_FixMath/Difference_Tone_FixMath.ino new file mode 100644 index 000000000..f9648964c --- /dev/null +++ b/examples/06.Synthesis/Difference_Tone_FixMath/Difference_Tone_FixMath.ino @@ -0,0 +1,71 @@ +/* Example using clipping to modify the spectrum of an audio signal + and emphasise a tone generated by the difference in frequency of 2 waves, + using Mozzi sonification library. + + Adaptation of the Difference_Tone example using FixMath. + + Demonstrates the use of EventDelay(), rand() and fixed-point numbers. + + Demonstrates Oscil::phMod() for phase modulation, + Smooth() for smoothing control signals, + and FixMath fixed point number types for fractional frequencies. + This is the same technique than the FMsynth example but + using FixMath instead of mozzi_fixmath. + + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Tim Barras, Thomas Combriat and the Mozzi team 2023, CC by-nc-sa. +*/ + + +#include +#include +#include +#include +#include +#include +#include + + +// use: Oscil oscilName (wavetable), look in .h file of table #included above +Oscil aSin1(SIN2048_DATA); // sine wave sound source +Oscil aSin2(SIN2048_DATA); // sine wave sound source +Oscil aGain(SIN2048_DATA); // to fade audio signal in and out before waveshaping + +// for scheduling note changes +EventDelay kChangeNoteDelay; + +const UFix<8, 0> freq1 = 184; +const auto harmonic_step = freq1 * UFix<8, 0>(12).invAccurate(); // harmonic_step = freq1/12; + +void setup() { + Serial.begin(115200); + aSin1.setFreq(freq1); + aGain.setFreq(0.2f); // use a float for low frequencies, in setup it doesn't need to be fast + kChangeNoteDelay.set(2000); // note duration ms, within resolution of CONTROL_RATE + startMozzi(); // :) +} + +void updateControl() { + if (kChangeNoteDelay.ready()) { + UFix<4, 0> harmonic = rand((byte)12); + auto shimmer = toUFraction(rand((byte)255)); // Creates a UFix<0,8> + auto freq2difference = (harmonic * harmonic_step) + (harmonic_step * shimmer).sR<3>(); // the shimmering is divided by 8 here + auto freq2 = (freq1 - freq2difference).asUFix(); + aSin2.setFreq((freq2)); + kChangeNoteDelay.start(); + } +} + +AudioOutput_t updateAudio() { + auto asig = (toSInt(aSin1.next()) + toSInt(aSin2.next())) * (toSFraction(aGain.next()) + UFix<1, 7>(1.2)); // this is a SFix<9,9> in the end + return MonoOutput::fromAlmostNBit(11, asig.asRaw()).clip(); // TODO, implement smart MonoOutput +} + +void loop() { + audioHook(); // required here +} From a90b93d6c05870c3d87bd8630f9c670f18bbf74f Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 25 Feb 2024 14:17:34 +0100 Subject: [PATCH 156/215] Removed FixMath from Mozzi's sources --- FixMath.h | 1293 -------------------------------------------- library.properties | 1 + 2 files changed, 1 insertion(+), 1293 deletions(-) delete mode 100644 FixMath.h diff --git a/FixMath.h b/FixMath.h deleted file mode 100644 index 221b69c1f..000000000 --- a/FixMath.h +++ /dev/null @@ -1,1293 +0,0 @@ -/* - * FixMath.h - * - * Copyright 2023, Thomas Combriat and the Mozzi team - * - * This file is part of Mozzi. - * - * Mozzi is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. - * - */ - - -/** This file implements two fixed point number classes. These numbers can have a fractional - part but are actually standard integers under the hood which makes calculations with them - efficient on platforms which do not have a FPU like most micro-controllers. These numbers can be - signed (SFix) or unsigned (UFix). - - A fixed point number has its range defined by the number of bits encoding the integer part (NI - in the following) and its precision by the number of bits encoding the fractional part (NF). For UFix types, the integral part can hold values in [0,2^NI-1], for SFix types, the integral part can hold values in [-2^NI,2^NI-1]. The number of bits encoding the fractional can be considered as the precision of the number: given NF, the number of possible values in the [0,1[ range will 2^NF. Hence, given NF, the resolution will be 1/(2^NF). - - Under the hood, these types will keep track of the maximum possible value they might hold (this is the RANGE template parameter), and, if only *SAFE* operations (see below) are used, will automatically adjust there NI and NF to accomodate the result of a operation. It will also try not to promote there internal type when possible, assuming that you use the complete range of a given type. - - The operations possible with these types can be divided into two categories: - - the operations between FixMath types are all safe (aka won't overflow) and are the only one included by default - - the operations between a FixMath and a native C type (int, float) are NOT safe and are not included by default. In order to activate them, you need to `#define MOZZI_FIXMATH_UNSAFE` before including FixMath.h. - - - Like standard C(++) types, the fixed point numbers defined here are following some rules: - - any fixed type can be converted to another *as long as the value can be represented in the destination type*. Casting to a bigger type in term of NI and NF is safe, but reducing NI can lead to an overflow if the new type cannot hold the integer value and reducing NF leads to a loss of precision. - - Fixed types can be constructed from and converted to standard C types. - - all operations between fixed point number is safe (it won't overflow) and preserve the precision. In particular: - - only addition, subtraction and multiplication are implemented (this is a design choice, see below) - - any operation between a signed and an unsigned leads to a signed number - - resulting numbers will be casted to a type big enough to store the expected values. It follows that it is worth starting with types that are as small as possible to hold the initial value. - - all operations between a fixed point number and a native type (int, float, uint) are *not* safe. If the resulting value cannot be represented in the fixed point type it will overflow. Only addition, subtraction, multiplication and right/left shift are implemented. These are only accessible activating the `MOZZI_FIXMATH_UNSAFE` set. - - safe right/left shifts, which return the correct value in the correct type are implemented as .sR() and .sL() respectively, shift being the shifting amount. - - More specifically on the returned types of the operations between fixed point math types: - - Additions: - - UFix + UFix<_NI,_NF> returns UFix at worse - - SFix + SFix<_NI,_NF> returns SFix at worse - - UFix + SFix<_NI,_NF> returns SFix at worse - - UFix + anything_else (signed or not) returns UFix (only available with `MOZZI_FIXMATH_UNSAFE`) - - SFix + anything_else (signed or not) returns SFix (only available with `MOZZI_FIXMATH_UNSAFE`) - - Subtractions: - - UFix - UFix<_NI,_NF> returns SFix at worse - - SFix - SFix<_NI,_NF> returns SFix at worse - - SFix - UFix<_NI,_NF> returns SFix at worse - - UFix - anything_else (signed or not) returns UFix (only available with `MOZZI_FIXMATH_UNSAFE`) - - SFix - anything_else (signed or not) returns SFix (only available with `MOZZI_FIXMATH_UNSAFE`) - - (-)SFix return SFix - - (-)UFix return SFix - - Multiplications: - - UFix * UFix<_NI,_NF> returns UFix at worse - - UFix * SFix<_NI,_NF> returns SFix at worse - - SFix * SFix<_NI,_NF> returns SFix at worse - - UFix * anything_else (signed or not) returns UFix (only available with `MOZZI_FIXMATH_UNSAFE`) - - SFix * anything_else (signed or not) returns SFix (only available with `MOZZI_FIXMATH_UNSAFE`) - - Shifts: - - UFix .sR returns UFix - - UFix .sL returns UFix - - same for SFix. - - Inverse: - - UFix.invFast() returns the inverse of the number as UFix - - SFix.invFast() returns the inverse of the number as SFix - - UFix.invAccurate() returns the inverse of the number as UFix - - SFix.invAccurate() returns the inverse of the number as SFix - - UFix.inv<_NF>() returns the inverse of the number as UFix - - SFix.inv<_NF>() returns the inverse of the number as SFix - - Conversion (should be preferred over casting, when possible): - - UFix.asSFix() returns SFix - - SFix.asUFix() returns UFix - - UFix.asFloat() returns the value as a float. - - SFix.asFloat() returns the value as a float. - - UFix.asRaw() returns the internal value. - - SFix.asRaw() returns the internal value. - - T.toUFraction() returns UFix<0,NF> with NF the number of bits of T (uint8_t leads to NF=8bits). - - T.toSFraction() returns SFix<0,NF> with NF the number of bits of T (int8_t leads to NF=7bits). - - T.toUInt() returns UFix with NI the number of bits of T (uint8_t leads to NI=8bits). - - T.toSInt() returns SFix with NI the number of bits of T (int8_t leads to NI=7bits). - - Note on division: - The division is not implemented. This is a deliberate choice made for two reasons: - - in contrast with all the other fundamental operations, it is not possible to guarantee that precision will be kept (other operations returns *exact* results whenever the operands were also exactly represented. Note that this is actually not the case when using normal floating point numbers. The inverse functions can be used to fake a division, by multiplying by the inverse of a number. - - division are usually very slow operations on MCU, hence there usage is discouraged. The ideal way of doing it is to compute the inverse whenever needed and only when needed. In the context of Mozzi for instance, a good way to do it would be to compute needed inverses in updateControl(), and use them in updateAudio(). - -*/ - - - - -#ifndef FIXMATH2_H_ -#define FIXMATH2_H_ - -#if FOR_DOXYGEN_ONLY -#define MOZZI_FIXMATH_UNSAFE -#endif - - -#include -#include "IntegerType.h" - - -namespace MozziPrivate { - template constexpr T shiftR(T x, int8_t bits) {return (bits > 0 ? (x >> (bits)) : (x << (-bits)));} // shift right with positive values, left with negative - constexpr int8_t sBitsToBytes(int8_t N) { return (((N)>>3)+1);} // conversion between Bits and Bytes for signed - constexpr int8_t uBitsToBytes(int8_t N) { return (((N-1)>>3)+1);} - template constexpr T mozziMax(T N1, T N2) { return (N1) > (N2) ? (N1) : (N2);} - template constexpr T mozziMin(T N1, T N2) { return (N1) > (N2) ? (N2) : (N1);} - constexpr uint64_t sFullRange(int8_t N) { return uint64_t(1)< _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF))));} // returns the RANGE following an addition - constexpr int8_t neededNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (uFullRange(NI+NF)) ? (NI+1) : (RANGE > (uFullRange(NI+NF-1)) ? (NI) : (NI-1)));} // check if RANGE can be hold in the unsigned type defined by NI and NF - constexpr int8_t neededSNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) { return (RANGE > (sFullRange(NI+NF)) ? (NI+1) : (RANGE > (sFullRange(NI+NF-1)) ? (NI) : (NI-1)));} // same for signed - constexpr uint64_t rangeShift(int8_t N, int8_t SH, uint64_t RANGE) { return ((SH < N) ? (RANGE) : (shiftR(RANGE,(N-SH))));} // make sure that NI or NF does not turn negative when safe shifts are used. -} - -// Forward declaration -template -class SFix; - - - -/** Instanciate an unsigned fixed point math number. - @param NI The number of bits encoding the integer part. The integral part can range into [0, 2^NI -1] - @param NF The number of bits encoding the fractional part - @param RANGE A purely internal parameter that keeps track of the range used by the type. Safer to *not* define it. -*/ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. -class UFix -{ - static_assert(NI+NF<=64, "The total width of a UFix cannot exceed 64bits"); - typedef typename IntegerType::unsigned_type internal_type ; // smallest size that fits our internal integer - typedef typename IntegerType::unsigned_type next_greater_type ; // smallest size that fits 1<*/(fl * (next_greater_type(1) << NF));} - - /** Constructor from a floating point value. - @param fl Floating point value - @return An unsigned fixed point number - */ - UFix(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } - - /* Constructor from integer type (as_frac = false) or from fractionnal value (as_frac=true) can be used to emulate the behavior of for instance Q8n0_to_Q8n8 */ - - /** Constructor from an integer value which can be interpreted as both a resulting fixed point - math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number. - @param value Integer value - @param as_raw=false with false value will be interpreted as an integer, with true it will be interpreted as a number with decimals. - @return An unsigned fixed point number - */ - template - UFix(T value,bool as_raw=false) { - - if (as_raw) internal_value = value; - else internal_value = (internal_type(value) << NF); - } - - - /** Set the internal value of the fixed point math number. - @param raw The new internal value. - @return An UFixx - */ - template - static UFix fromRaw(T raw){return UFix(raw,true);} - - - - - - /** Constructor from another UFix. - @param uf An unsigned fixed type number which value can be represented in this type. - @return A unsigned fixed type number - */ - template - UFix(const UFix<_NI,_NF, _RANGE>& uf) { - internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); - } - - - - /** Constructor from a SFix. - @param uf An signed fixed type number which value can be represented in this type: sign is thus discarded. - @return A unsigned fixed type number - */ - template - UFix(const SFix<_NI,_NF, _RANGE>& uf) { - internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); - } - - - //////// ADDITION OVERLOADS - - /** Addition with another UFix. Safe. - @param op The UFix to be added. - @return The result of the addition as a UFix. - */ - template - UFix operator+ (const UFix<_NI,_NF,_RANGE>& op) const - { - constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - typedef typename IntegerType::unsigned_type return_type; - UFix left(*this); - UFix right(op); - - return_type tt = return_type(left.asRaw()) + right.asRaw(); - return UFix(tt,true); - } - - /** Addition with a SFix. Safe. - @param op The UFix to be added. - @return The result of the addition as a SFix. - */ - template - SFix operator+ (const SFix<_NI,_NF,_RANGE>& op) const - { - constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - typedef typename IntegerType::signed_type return_type; - SFix left(*this); - SFix right(op); - - return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFix(tt,true); - } - -#ifdef MOZZI_FIXMATH_UNSAFE - /** Addition with another type. - @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` - @param op The number to be added. - @return The result of the addition as a UFix. - */ - template - UFix operator+ (const T op) const - { - return UFix(internal_value+((internal_type)op< // We do not have the +1 after MozziPrivate::mozziMax(NI, _NI) because the substraction between two UFix should fit in the biggest of the two. - SFix operator- (const UFix<_NI,_NF, _RANGE>& op) const - { - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - typedef typename IntegerType::signed_type return_type; - SFix left(*this); - SFix right(op); - - return_type tt = return_type(left.asRaw()) - right.asRaw(); - return SFix(tt,true); - } - - #ifdef MOZZI_FIXMATH_UNSAFE - /** Subtraction with another type. - @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` - @param op The number to be subtracted. - @return The result of the subtraction as a UFix. - */ - template - UFix operator- (const T op) const - { - return UFix(internal_value-((internal_type)op< operator-() const - { - return SFix( -(typename IntegerType::signed_type)(internal_value),true); - } - - //////// MULTIPLICATION OVERLOADS - - /** Multiplication with another UFix. Safe. - @param op The UFix to be multiplied. - @return The result of the multiplication as a UFix. - */ - template - UFix operator* (const UFix<_NI,_NF,_RANGE>& op) const - { - constexpr int8_t NEW_NI = MozziPrivate::neededNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); - typedef typename IntegerType::unsigned_type return_type ; - return_type tt = return_type(internal_value)*op.asRaw(); - return UFix(tt,true); - } - - /** Multiplication with a SFix. Safe. - @param op The SFix to be multiplied. - @return The result of the multiplication as a SFix. - */ - template - SFix operator* (const SFix<_NI,_NF,_RANGE>& op) const - { - constexpr int8_t NEW_NI = MozziPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); - typedef typename IntegerType::signed_type return_type ; - return_type tt = return_type(internal_value)*op.asRaw(); - return SFix(tt,true); - } - - #ifdef MOZZI_FIXMATH_UNSAFE - /** Multiplication with another type. - @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` - @param op The number to be multiplied. - @return The result of the multiplication as a UFix of identical NI and NF - */ - template - UFix operator* (const T op) const - { - return UFix(internal_value*op,true); - } -#endif - - //////// INVERSE - - /** Compute the inverse of a UFix, as a UFix (not a typo). - This inverse is able to represent accurately the inverse of the smallest and biggest of the initial number, but might lead to a lot of duplicates in between. - Good if precision is not a premium but type conservation and speeds are. - This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. - @return The inverse of the number. - */ - UFix invFast() const - { - static_assert(NI+NF<=63, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); - return UFix((onesbitmask()/internal_value),true); - } - - - /** Compute the inverse of a UFix, as a UFix. - _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invAccurate() (_NF=2*NI+NF) - @return The inverse of the number. - */ - template - UFix inv() const - { - return UFix<_NF,NF>(internal_value,true).invFast(); - } - - - - /** Compute the inverse of a UFix, as a UFix. - This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. - This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. - @return The inverse of the number. - */ - UFix invAccurate() const // The MozziPrivate::mozziMin is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert) - { - static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed for when 2*NI+2*NF>63. Reduce the number of bits."); - return inv(); - } - - - - - - - //////// SHIFTS OVERLOADS - - /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. - Better to use .sR() if possible instead. - @param op The shift number - @return The result of the shift as a UFix. - */ - UFix operator>> (const int8_t op) const - { - return UFix(internal_value>>op,true); - } - - - #ifdef MOZZI_FIXMATH_UNSAFE - /** Left shift. This can overflow if you shift to a value that cannot be represented. - Better to use .sL() if possible instead. - @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` - @param op The shift number - @return The result of the shift as a UFix. - */ - UFix operator<< (const int8_t op) const - { - return UFix(internal_value< - UFix sR() - { - return UFix(internal_value,true); - } - - /** Safe and optimal left shift. The returned type will be adjusted accordingly - @param op The shift number - @return The result of the shift as a UFix of bigger size. - */ - template - UFix sL() - { - return UFix(internal_value,true); - } - - - //////// COMPARISON OVERLOADS - /** Comparison with another UFix. - @param op A UFix - @return true if this is bigger than op, false otherwise - */ - template - bool operator> (const UFix<_NI,_NF>& op) const - { - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - UFix left(*this); - UFix right(op); - return left.asRaw()>right.asRaw(); - } - - /** Comparison with another UFix. - @param op A UFix - @return true if this is smaller than op, false otherwise - */ - template - bool operator< (const UFix<_NI,_NF>& op) const - { - return op > *this; - } - - - /** Comparison with another UFix. - @param op A UFix - @return true if this equal to op, false otherwise - */ - template - bool operator== (const UFix<_NI,_NF>& op) const - { - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - UFix left(*this); - UFix right(op); - return left.asRaw()==right.asRaw(); - } - - /** Comparison with another UFix. - @param op A UFix - @return true if this not equal to op, false otherwise - */ - template - bool operator!= (const UFix<_NI,_NF>& op) const - { - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - UFix left(*this); - UFix right(op); - return left.asRaw()!=right.asRaw(); - } - - /** Returns the number as a SFix of same range and precision. This is more optimized than a cast. - @return a SFix - */ - SFix asSFix() const - { - return SFix(internal_value,true); - } - - /** Returns the value as floating point number. - @return The floating point value. - */ - float asFloat() const { return (static_cast(internal_value)) / (next_greater_type(1)< -inline UFix operator*(uint8_t op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(uint16_t op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(uint32_t op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(uint64_t op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(int8_t op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(int16_t op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(int32_t op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(int64_t op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(float op, const UFix& uf) {return uf*op;} - -template -inline UFix operator*(double op, const UFix& uf) {return uf*op;} - -// Addition -template -inline UFix operator+(uint8_t op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(uint16_t op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(uint32_t op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(uint64_t op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(int8_t op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(int16_t op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(int32_t op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(int64_t op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(float op, const UFix& uf) {return uf+op;} - -template -inline UFix operator+(double op, const UFix& uf) {return uf+op;} - -// Substraction -template -inline SFix operator-(uint8_t op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(uint16_t op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(uint32_t op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(uint64_t op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(int8_t op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(int16_t op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(int32_t op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(int64_t op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(float op, const UFix& uf) {return -uf+op;} - -template -inline SFix operator-(double op, const UFix& uf) {return -uf+op;} -#endif -////// Helper functions to build SFix from a normal type automatically - - -/** Create a *pure* fractional unsigned fixed number (UFix) from an unsigned integer. - The number of fractional bits (NF) is chosen automatically depending on the input - type. Hence toUFraction(255) and toUFraction(uint8_t(255)) *do not* lead to the - same thing: on an AVR, the former will lead to NF=16 - which is overkill and - incorrect if you expect toUFraction(255) = 1 - - whereas the latter will lead to NF=8. Mozzi's objects (Oscil and the like) - returns correct types, hence you can use this function to convert the return - value of a Mozzi's function/class member into a pure fractional number. - @param val The value to be converted into a pure fractional number. - @return A UFix<0,NF> with NF chosen according to the input type -*/ -template -inline UFix<0, sizeof(T)*8> toUFraction(T val) { - return UFix<0, sizeof(T)*8>::fromRaw(val); -} - -/** Create a *pure* integer unsigned fixed number (UFix) from an unsigned integer. - The number of fractional bits (NI) is chosen automatically depending on the input - type. Hence toUInt(255) and toUInt(uint8_t(255)) *do not* lead to the - same thing: on an AVR, the former will lead to NI=16 - which is overkill - - whereas the latter will lead to NI=8. Mozzi's objects (Oscil and the like) - returns correct types, hence you can use this function to convert the return - value of a Mozzi's function/class member into a pure fractional number. - @param val The value to be converted into a pure unsigned integer fixed math number. - @return A UFix with NI chosen according to the input type -*/ -template -inline UFix toUInt(T val) { - return UFix::fromRaw(val); -} - - - -/** Instanciate an signed fixed point math number. - @param NI The number of bits encoding the integer part. The integral part can range into [-2^NI, 2^NI -1] - @param NF The number of bits encoding the fractional part - @param RANGE A purely internal parameter that keeps track of the range used by the type. Safer to *not* define it. - @note The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFix<7,0>. -*/ -template // NI and NF being the number of bits for the integral and the fractionnal parts respectively. -class SFix -{ - static_assert(NI+NF<64, "The total width of a SFix cannot exceed 63bits"); - typedef typename IntegerType::signed_type internal_type ; // smallest size that fits our internal integer - typedef typename IntegerType::signed_type next_greater_type ; // smallest size that fits 1<*/(fl * (next_greater_type(1) << NF));} - - /** Constructor from a floating point value. - @param fl Floating point value - @return An signed fixed point number - */ - SFix(double fl) {internal_value = static_cast (fl * (next_greater_type(1) << NF)); } - - - /** Constructor from an integer value which can be interpreted as both a resulting fixed point - math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number. - @param value Integer value - @param as_raw=false with false value will be interpreted as an integer, with true it will be interpreted as a number with decimals. - @return An signed fixed point number - */ - template - SFix(T value,bool as_raw=false) - { - if (as_raw) internal_value = value; - else internal_value = (internal_type(value) << NF); - } - - /** Set the internal value of the fixed point math number. - @param raw The new internal value. - @return A SFix. - */ - template - static SFix fromRaw(T raw){return SFix(raw,true);} - - - /** Constructor from another SFix. - @param uf A signed fixed type number which value can be represented in this type. - @return A signed fixed type number - */ - template - SFix(const SFix<_NI,_NF, _RANGE>& uf) { - internal_value = MozziPrivate::shiftR((typename IntegerType::signed_type) uf.asRaw(),(_NF-NF)); - - } - - /** Constructor from an UFix. - @param uf A unsigned fixed type number which value can be represented in this type. - @return A signed fixed type number - */ - template - SFix(const UFix<_NI,_NF, _RANGE>& uf) { - internal_value = MozziPrivate::shiftR((typename IntegerType::unsigned_type) uf.asRaw(),(_NF-NF)); - } - - //////// ADDITION OVERLOADS - - /** Addition with another SFix. Safe. - @param op The SFix to be added. - @return The result of the addition as a SFix. - */ - template - SFix operator+ (const SFix<_NI,_NF,_RANGE>& op) const - { - constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - typedef typename IntegerType::signed_type return_type; - SFix left(*this); - SFix right(op); - - return_type tt = return_type(left.asRaw()) + right.asRaw(); - return SFix(tt,true); - } - -#ifdef MOZZI_FIXMATH_UNSAFE - /** Addition with another type. - @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` - @param op The number to be added. - @return The result of the addition as a UFix. - */ - template - SFix operator+ (const T op) const - { - return SFix(internal_value+(op< - SFix operator- (const SFix<_NI,_NF, _RANGE>& op) const - { - constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - typedef typename IntegerType::signed_type return_type; - SFix left(*this); - SFix right(op); - return_type tt = return_type(left.asRaw()) - return_type(right.asRaw()); - return SFix(tt,true); - } - - /** Subtraction with a UFix. Safe. - @param op The SFix to be subtracted. - @return The result of the subtraction as a SFix. - */ - template - SFix operator- (const UFix<_NI,_NF, _RANGE>& op) const - { - constexpr uint64_t new_RANGE = MozziPrivate::rangeAdd(NF,_NF,RANGE,_RANGE); - constexpr int8_t new_NI = MozziPrivate::neededSNIExtra(MozziPrivate::mozziMax(NI,_NI),MozziPrivate::mozziMax(NF,_NF),new_RANGE); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - typedef typename IntegerType::signed_type return_type; - SFix left(*this); - SFix right(op); - return_type tt = return_type(left.asRaw()) - return_type(right.asRaw()); - return SFix(tt,true); - } - - #ifdef MOZZI_FIXMATH_UNSAFE - /** Subtraction with another type. - @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` - @param op The number to be subtracted. - @return The result of the subtraction as a SFix. - */ - template - SFix operator- (const T op) const - { - return SFix(internal_value-(op< operator-() const - { - return SFix(-internal_value,true); - } - - //////// MULTIPLICATION OVERLOADS - - /** Multiplication with another SFix. Safe. - @param op The SFix to be multiplied. - @return The result of the multiplication as a SFix. - */ - template - SFix operator* (const SFix<_NI,_NF,_RANGE>& op) const - { - constexpr int8_t NEW_NI = MozziPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE); - typedef typename IntegerType::signed_type return_type ; - return_type tt = return_type(internal_value)*op.asRaw(); - return SFix(tt,true); - } - - #ifdef MOZZI_FIXMATH_UNSAFE - /** Multiplication with another type. - @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` - @param op The number to be multiplied. - @return The result of the multiplication as a UFix. - */ - template - SFix operator* (const T op) const - { - return SFix(internal_value*op,true); - } -#endif - - - //////// INVERSE - - /** Compute the inverse of a SFix, as a SFix (not a typo). - This inverse is able to represent accurately the inverse of the smallest and biggest of the initial number, but might lead to a lot of duplicates in between. - Good if precision is not a premium but type conservation and speeds are. - This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. - @return The inverse of the number. - */ - - SFix invFast() const - { - static_assert(NI+NF<=62, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits."); - return SFix((onesbitmask()/internal_value),true); - } - - /** Compute the inverse of a SFix, as a SFix. - _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invAccurate() (_NF=2*NI+NF) - @return The inverse of the number. - */ - template - SFix inv() const - { - return SFix<_NF,NF>(internal_value,true).invFast(); - } - - /** Compute the inverse of a SFix, as a SFix. - This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. - This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division. - @return The inverse of the number. - */ - SFix invAccurate() const - { - return inv(); - } - - - //////// SHIFTS OVERLOADS - - /** Right shift. This won't overflow but will not leverage on the bits freed by the shift. - Better to use .sR() if possible instead. - @param op The shift number - @return The result of the shift as a SFix. - */ - SFix operator>> (const int8_t op) const - { - return SFix(internal_value>>op,true); - } - - #ifdef MOZZI_FIXMATH_UNSAFE - /** Left shift. This can overflow if you shift to a value that cannot be represented. - Better to use .sL() if possible instead. - @note Unsafe. Only available with `MOZZI_FIXMATH_UNSAFE` - @param op The shift number - @return The result of the shift as a UFix. - */ - SFix operator<< (const int8_t op) const - { - return SFix(internal_value< - SFix sR() - { - return SFix(internal_value,true); - } - - /** Safe and optimal left shift. The returned type will be adjusted accordingly - @param op The shift number - @return The result of the shift as a UFix of bigger size. - */ -template - SFix sL() - { - return SFix(internal_value,true); - } - - - //////// COMPARISON OVERLOADS - - /** Comparison with another SFix. - @param op A UFix - @return true if this is bigger than op, false otherwise - */ - template - bool operator> (const SFix<_NI,_NF>& op) const - { - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFix left(*this); - SFix right(op); - return left.asRaw()>right.asRaw(); - } - - /** Comparison with another SFix. - @param op A UFix - @return true if this is smaller than op, false otherwise - */ - template - bool operator< (const SFix<_NI,_NF>& op) const - { - return op > *this; - } - - - /** Comparison with another SFix. - @param op A UFix - @return true if this is equal to op, false otherwise - */ - template - bool operator== (const SFix<_NI,_NF>& op) const - { - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFix left(*this); - SFix right(op); - return left.asRaw()==right.asRaw(); - } - - /** Comparison with another SFix. - @param op A UFix - @return true if this is not equal to op, false otherwise - */ - template - bool operator!= (const SFix<_NI,_NF>& op) const - { - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFix left(*this); - SFix right(op); - return left.asRaw()!=right.asRaw(); - } - - - /** Returns the number as a UFix of same (positive) range and precision. The initial value has to be positive to return something correct. This is more optimized than a cast. - @return a UFix - */ - UFix asUFix() const - { - return UFix(internal_value,true); - } - - - /** Returns the value as floating point number. - @return The floating point value. - */ - float asFloat() const {return (static_cast(internal_value)) / (next_greater_type(1)< -inline SFix operator*(uint8_t op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(uint16_t op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(uint32_t op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(uint64_t op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(int8_t op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(int16_t op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(int32_t op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(int64_t op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(float op, const SFix& uf) {return uf*op;} - -template -inline SFix operator*(double op, const SFix& uf) {return uf*op;} - -// Addition -template -inline SFix operator+(uint8_t op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(uint16_t op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(uint32_t op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(uint64_t op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(int8_t op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(int16_t op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(int32_t op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(int64_t op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(float op, const SFix& uf) {return uf+op;} - -template -inline SFix operator+(double op, const SFix& uf) {return uf+op;} - -// Substraction -template -inline SFix operator-(uint8_t op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(uint16_t op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(uint32_t op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(uint64_t op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(int8_t op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(int16_t op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(int32_t op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(int64_t op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(float op, const SFix& uf) {return (-uf)+op;} - -template -inline SFix operator-(double op, const SFix& uf) {return (-uf)+op;} - -#endif - - - - - - -/** Addition between a SFix and a UFix. Safe. - @param op1 A SFix - @param op2 A UFix - @return The result of the addition of op1 and op2. As a SFix -*/ -template -inline SFix operator+ (const SFix& op1, const UFix<_NI,_NF,_RANGE>& op2 ) -{ - return op2+op1; - } - - -/** Subtraction between a UFix and a SFix. Safe. - @param op1 A UFix - @param op2 A SFix - @return The result of the subtraction of op1 by op2. As a SFix -*/ -template -inline SFix operator- (const UFix& op1, const SFix<_NI,_NF, _RANGE>& op2) -{ - return -op2+op1; - } - - -/** Multiplication between a SFix and a UFix. Safe. - @param op1 A SFix - @param op2 A UFix - @return The result of the multiplication of op1 and op2. As a SFix -*/ -template -inline SFix operator* (const SFix<_NI,_NF,_RANGE>& op1, const UFix& op2) -{ - return op2*op1; -} - -// Comparison between SFix and UFixmath - -/** Comparison between a SFix and an UFix. - @param op1 a SFix - @param op2 A UFix - @return true if op1 is bigger than op2, false otherwise -*/ -template -inline bool operator> (const SFix& op1, const UFix<_NI,_NF>& op2 ) -{ - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFix left(op1); - SFix right(op2); - return left.asRaw() > right.asRaw(); -} - -/** Comparison between a UFix and an SFix. - @param op1 a UFix - @param op2 A SFix - @return true if op1 is bigger than op2, false otherwise -*/ -template -inline bool operator> (const UFix& op1, const SFix<_NI,_NF>& op2 ) -{ - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFix left(op1); - SFix right(op2); - return left.asRaw() > right.asRaw(); -} - -/** Comparison between a UFix and an SFix. - @param op1 a UFix - @param op2 A SFix - @return true if op1 is smaller than op2, false otherwise -*/ -template -inline bool operator< (const UFix& op1, const SFix<_NI,_NF>& op2 ) -{ - return op2 > op1; -} - - -/** Comparison between a SFix and an UFix. - @param op1 a SFix - @param op2 A UFix - @return true if op1 is smaller than op2, false otherwise -*/ -template -inline bool operator< (const SFix& op1, const UFix<_NI,_NF>& op2 ) -{ - return op2 > op1; -} - - -/** Comparison between a SFix and an UFix. - @param op1 a SFix - @param op2 A UFix - @return true if op1 is equal to op2, false otherwise -*/ -template -inline bool operator== (const SFix& op1, const UFix<_NI,_NF>& op2 ) -{ - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFix left(op1); - SFix right(op2); - return left.asRaw() == right.asRaw(); -} - - -/** Comparison between a UFix and an SFix. - @param op1 a UFix - @param op2 A SFix - @return true if op1 is equal to op2, false otherwise -*/ -template -inline bool operator== (const UFix& op1, const SFix<_NI,_NF>& op2 ) -{ - return op2 == op1; -} - -/** Comparison between a SFix and an UFix. - @param op1 a SFix - @param op2 A UFix - @return true if op1 is not equal to op2, false otherwise -*/ -template -inline bool operator!= (const SFix& op1, const UFix<_NI,_NF>& op2 ) -{ - constexpr int8_t new_NI = MozziPrivate::mozziMax(NI, _NI); - constexpr int8_t new_NF = MozziPrivate::mozziMax(NF, _NF); - SFix left(op1); - SFix right(op2); - return left.asRaw() != right.asRaw(); -} - - -/** Comparison between a UFix and an SFix. - @param op1 a UFix - @param op2 A SFix - @return true if op1 is not equal to op2, false otherwise -*/ -template -inline bool operator!= (const UFix& op1, const SFix<_NI,_NF>& op2 ) -{ - return op2 != op1; -} - -////// Helper functions to build SFix from a normal type automatically - - -/** Create a *pure* fractional signed fixed number (SFix) from a integer. - The number of fractional bits (NF) is chosen automatically depending on the input - type. Hence toSFraction(127) and toSFraction(int8_t(127)) *do not* lead to the - same thing: on an AVR, the former will lead to NF=15 - which is overkill and - incorrect if you expect toSFraction(127) = 1 - - whereas the latter will lead to NF=7. Mozzi's objects (Oscil and the like) - returns correct types, hence you can use this function to convert the return - value of a Mozzi's function/class member into a pure fractional number. - @param val The value to be converted into a pure fractional number. - @return A SFix<0,NF> with NF chosen according to the input type -*/ -template -inline SFix<0, sizeof(T)*8-1> toSFraction(T val) { - return SFix<0, sizeof(T)*8-1>::fromRaw(val); -} - -/** Create a *pure* integer signed fixed number (SFix) from a integer. - The number of fractional bits (NI) is chosen automatically depending on the input - type. Hence toSInt(127) and toSInt(int8_t(127)) *do not* lead to the - same thing: on an AVR, the former will lead to NI=15 - which is overkill - - whereas the latter will lead to NI=7. Mozzi's objects (Oscil and the like) - returns correct types, hence you can use this function to convert the return - value of a Mozzi's function/class member into a pure fractional number. - @param val The value to be converted into a pure integer fixed math number. - @return A SFix with NI chosen according to the input type -*/ -template -inline SFix toSInt(T val) { - return SFix::fromRaw(val); -} - - - - - - -#endif diff --git a/library.properties b/library.properties index 4cbb8480c..e884d927d 100644 --- a/library.properties +++ b/library.properties @@ -9,3 +9,4 @@ url=https://sensorium.github.io/Mozzi/ architectures=* dot_a_linkage=false includes=Mozzi.h +depends=FixMath From cab6c308c07b09ff0e8fdcdd36aea9fedcde7d11 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 25 Feb 2024 14:27:32 +0100 Subject: [PATCH 157/215] Added FixMath to gh actions --- .github/workflows/compile_examples.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/compile_examples.yml b/.github/workflows/compile_examples.yml index 68454ae72..c8d20feea 100644 --- a/.github/workflows/compile_examples.yml +++ b/.github/workflows/compile_examples.yml @@ -126,6 +126,7 @@ jobs: - name: PinChangeInterrupt - name: MIDI Library - name: Arduino_AdvancedAnalog + - name: FixMath enable-deltas-report: true sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} enable-warnings-report: true From c33a1bda0a10fe7aec31c05fb8af11d716985a9d Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 25 Feb 2024 14:41:55 +0100 Subject: [PATCH 158/215] Spaces, not tab in Yaml actions --- .github/workflows/compile_examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compile_examples.yml b/.github/workflows/compile_examples.yml index c8d20feea..918f82a64 100644 --- a/.github/workflows/compile_examples.yml +++ b/.github/workflows/compile_examples.yml @@ -126,7 +126,7 @@ jobs: - name: PinChangeInterrupt - name: MIDI Library - name: Arduino_AdvancedAnalog - - name: FixMath + - name: FixMath enable-deltas-report: true sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} enable-warnings-report: true From b0886664b69136b100824d3f1c275627dce16f04 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 25 Feb 2024 15:03:09 +0100 Subject: [PATCH 159/215] Adapted Detuned_Beats_Wash example --- .../Detuned_Beats_Wash/Detuned_Beats_Wash.ino | 80 +++++++++++-------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino index 05eb161d1..86d772a14 100644 --- a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino +++ b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino @@ -6,12 +6,12 @@ updateControl(), and the outputs of 12 audio oscillators are summed in updateAudio(). - Demonstrates the use of fixed-point Q16n16 + Demonstrates the use of FixMath fixed point format numbers, mtof() for converting midi note values to frequency, and xorshift96() for random numbers. This sketch is pushing the limits of computing power on the - 8-biit AVR boards. At the time of this writing, you will have + 8-bit AVR boards. At the time of this writing, you will have to manually alter your platform.txt file to use optimization for speed rather than size on Arduino Uno and similar. (Alternatively, remove one of the oscillators) @@ -26,7 +26,7 @@ Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Tim Barrass 2012, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. */ #include @@ -34,7 +34,7 @@ #include #include #include -#include // for Q16n16 fixed-point fractional number type +#include // harmonics Oscil aCos1(COS8192_DATA); @@ -55,13 +55,19 @@ Oscil aCos6b(COS8192_DATA); //Oscil aCos7b(COS8192_DATA); // base pitch frequencies in Q16n16 fixed int format (for speed later) -Q16n16 f1,f2,f3,f4,f5,f6;//,f7; +UFix<12,15> f1,f2,f3,f4,f5,f6;//,f7; -Q16n16 variation() { +/*Q16n16 variation() { // 32 random bits & with 524287 (b111 1111 1111 1111 1111) // gives between 0-8 in Q16n16 format return (Q16n16) (xorshift96() & 524287UL); +}*/ + +UFix<3,16> variation() // changing the return type here enables to easily + // increase or decrease the variation +{ + return UFix<3,16>::fromRaw(xorshift96() & 524287UL); } @@ -69,31 +75,31 @@ void setup(){ startMozzi(); // select base frequencies using mtof (midi to freq) and fixed-point numbers - f1 = Q16n16_mtof(Q16n0_to_Q16n16(48)); - f2 = Q16n16_mtof(Q16n0_to_Q16n16(74)); - f3 = Q16n16_mtof(Q16n0_to_Q16n16(64)); - f4 = Q16n16_mtof(Q16n0_to_Q16n16(77)); - f5 = Q16n16_mtof(Q16n0_to_Q16n16(67)); - f6 = Q16n16_mtof(Q16n0_to_Q16n16(57)); - // f7 = Q16n16_mtof(Q16n0_to_Q16n16(60)); + f1 = mtof(UFix<7,0>(48)); + f2 = mtof(UFix<7,0>(74)); + f3 = mtof(UFix<7,0>(64)); + f4 = mtof(UFix<7,0>(77)); + f5 = mtof(UFix<7,0>(67)); + f6 = mtof(UFix<7,0>(57)); + // f7 = mtof(UFix<7,0>(60)); // set Oscils with chosen frequencies - aCos1.setFreq_Q16n16(f1); - aCos2.setFreq_Q16n16(f2); - aCos3.setFreq_Q16n16(f3); - aCos4.setFreq_Q16n16(f4); - aCos5.setFreq_Q16n16(f5); - aCos6.setFreq_Q16n16(f6); - // aCos7.setFreq_Q16n16(f7); + aCos1.setFreq(f1); + aCos2.setFreq(f2); + aCos3.setFreq(f3); + aCos4.setFreq(f4); + aCos5.setFreq(f5); + aCos6.setFreq(f6); + // aCos7.setFreq(f7); // set frequencies of duplicate oscillators - aCos1b.setFreq_Q16n16(f1+variation()); - aCos2b.setFreq_Q16n16(f2+variation()); - aCos3b.setFreq_Q16n16(f3+variation()); - aCos4b.setFreq_Q16n16(f4+variation()); - aCos5b.setFreq_Q16n16(f5+variation()); - aCos6b.setFreq_Q16n16(f6+variation()); - //aCos7b.setFreq_Q16n16(f7+variation()); + aCos1b.setFreq(f1+variation()); + aCos2b.setFreq(f2+variation()); + aCos3b.setFreq(f3+variation()); + aCos4b.setFreq(f4+variation()); + aCos5b.setFreq(f5+variation()); + aCos6b.setFreq(f6+variation()); + //aCos7b.setFreq(f7+variation()); } @@ -110,31 +116,31 @@ void updateControl(){ switch (lowByte(xorshift96()) & 7){ // 7 is 0111 case 0: - aCos1b.setFreq_Q16n16(f1+variation()); + aCos1b.setFreq(f1+variation()); break; case 1: - aCos2b.setFreq_Q16n16(f2+variation()); + aCos2b.setFreq(f2+variation()); break; case 2: - aCos3b.setFreq_Q16n16(f3+variation()); + aCos3b.setFreq(f3+variation()); break; case 3: - aCos4b.setFreq_Q16n16(f4+variation()); + aCos4b.setFreq(f4+variation()); break; case 4: - aCos5b.setFreq_Q16n16(f5+variation()); + aCos5b.setFreq(f5+variation()); break; case 5: - aCos6b.setFreq_Q16n16(f6+variation()); + aCos6b.setFreq(f6+variation()); break; /* case 6: - aCos7b.setFreq_Q16n16(f7+variation()); + aCos7b.setFreq(f7+variation()); break; */ } @@ -151,6 +157,10 @@ AudioOutput_t updateAudio(){ aCos5.next() + aCos5b.next() + aCos6.next() + aCos6b.next();// + // aCos7.next() + aCos7b.next(); +/* +auto asig = +toSFraction(aCos1.next()) + toSFraction(aCos1b.next()); - return MonoOutput::fromAlmostNBit(12, asig); + return MonoOutput::fromNBit(asig.getNF()+asig.getNI(), asig.asRaw());*/ + return MonoOutput::fromAlmostNBit(12, asig); } From 05ef0f19e40ec6e0f8cca66e7f417e9e41990b45 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 26 Feb 2024 20:46:24 +0100 Subject: [PATCH 160/215] Added outputs from SFix for MonoOutput and StereoOutput BugFix --- AudioOutput.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/AudioOutput.h b/AudioOutput.h index 252a3076c..b4e042083 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -46,6 +46,7 @@ #ifndef AUDIOOUTPUT_H #define AUDIOOUTPUT_H +#include /** The type used to store a single channel of a single frame, internally. For compatibility with earlier versions of Mozzi this is defined as int. * If you do not care about keeping old sketches working, you may be able to save some RAM by using int16_t, instead (on boards where int is larger @@ -123,8 +124,11 @@ struct MonoOutput { /** Construct an audio frame from a zero-centered value known to be in the 8 bit range. On AVR, if MOZZI_OUTPUT_PWM mode, this is effectively the same as calling the * constructor, directly (no scaling gets applied). On platforms/configs using more bits, an appropriate left-shift will be performed. */ static inline MonoOutput from8Bit(int16_t l) { return fromNBit(8, l); } - /** Construct an audio frame a zero-centered value known to be in the 16 bit range. This is jsut a shortcut for fromNBit(16, ...) provided for convenience. */ + /** Construct an audio frame from a zero-centered value known to be in the 16 bit range. This is jsut a shortcut for fromNBit(16, ...) provided for convenience. */ static inline MonoOutput from16Bit(int16_t l) { return fromNBit(16, l); } + /** Construct an audio frame from a SFix type from FixMath. Mozzi will figure out how many bits are in there and performs appropriate shifting to match the output range. */ + template + static inline MonoOutput fromSFix(SFix l) { return MonoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF))) ;} /** Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit range, e.g. at N=8 bits and a litte. On most platforms, this is * exactly the same as fromNBit(), shifting up or down to the platforms' available resolution. * @@ -168,6 +172,9 @@ template static inline StereoOutput fromNBit(uint8_t bits, T l, T r) static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); } /** See @ref MonoOutput::from16Bit(), stereo variant */ static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); } +/** See @ref MonoOutput::fromSFix(), stereo variant. Note that the two channels do not need to have the same number of bits. */ + template + static inline StereoOutput fromSFix(SFix l, SFix<_NI,_NF,_RANGE> r) { return MonoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF)), SCALE_AUDIO(r.asRaw(), (_NI+_NF))); } /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */ template static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); } private: From dbed60aa55f798bec3ef4f3838ce37949a686181 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 26 Feb 2024 20:54:45 +0100 Subject: [PATCH 161/215] Added automatic scaling to DBW example Typo in AudioOutput --- AudioOutput.h | 2 +- .../Detuned_Beats_Wash/Detuned_Beats_Wash.ino | 61 +++++++++++++------ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index b4e042083..0d655aee3 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -174,7 +174,7 @@ template static inline StereoOutput fromNBit(uint8_t bits, T l, T r) static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); } /** See @ref MonoOutput::fromSFix(), stereo variant. Note that the two channels do not need to have the same number of bits. */ template - static inline StereoOutput fromSFix(SFix l, SFix<_NI,_NF,_RANGE> r) { return MonoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF)), SCALE_AUDIO(r.asRaw(), (_NI+_NF))); } + static inline StereoOutput fromSFix(SFix l, SFix<_NI,_NF,_RANGE> r) { return StereoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF)), SCALE_AUDIO(r.asRaw(), (_NI+_NF))); } /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */ template static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); } private: diff --git a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino index e2bc9038b..7960c5971 100644 --- a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino +++ b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino @@ -37,22 +37,22 @@ #include // harmonics -Oscil aCos1(COS8192_DATA); -Oscil aCos2(COS8192_DATA); -Oscil aCos3(COS8192_DATA); -Oscil aCos4(COS8192_DATA); -Oscil aCos5(COS8192_DATA); -Oscil aCos6(COS8192_DATA); -//Oscil aCos7(COS8192_DATA); // used to work smoothly in Arduino 1.05 +Oscil aCos1(COS8192_DATA); +Oscil aCos2(COS8192_DATA); +Oscil aCos3(COS8192_DATA); +Oscil aCos4(COS8192_DATA); +Oscil aCos5(COS8192_DATA); +Oscil aCos6(COS8192_DATA); +//Oscil aCos7(COS8192_DATA); // used to work smoothly in Arduino 1.05 // duplicates but slightly off frequency for adding to originals -Oscil aCos1b(COS8192_DATA); -Oscil aCos2b(COS8192_DATA); -Oscil aCos3b(COS8192_DATA); -Oscil aCos4b(COS8192_DATA); -Oscil aCos5b(COS8192_DATA); -Oscil aCos6b(COS8192_DATA); -//Oscil aCos7b(COS8192_DATA); +Oscil aCos1b(COS8192_DATA); +Oscil aCos2b(COS8192_DATA); +Oscil aCos3b(COS8192_DATA); +Oscil aCos4b(COS8192_DATA); +Oscil aCos5b(COS8192_DATA); +Oscil aCos6b(COS8192_DATA); +//Oscil aCos7b(COS8192_DATA); // base pitch frequencies in Q16n16 fixed int format (for speed later) UFix<12,15> f1,f2,f3,f4,f5,f6;//,f7; @@ -148,8 +148,13 @@ void updateControl(){ AudioOutput updateAudio(){ + /* +The following block is the "classical" way of outputting the sound, from a standard C/C++ type. +You need to know how many bits you are dealing with and can use a reduced number to bring in some +distorsion with .clip() if you want. + */ - int asig = + /* int asig = aCos1.next() + aCos1b.next() + aCos2.next() + aCos2b.next() + aCos3.next() + aCos3b.next() + @@ -157,10 +162,26 @@ AudioOutput updateAudio(){ aCos5.next() + aCos5b.next() + aCos6.next() + aCos6b.next();// + // aCos7.next() + aCos7b.next(); -/* -auto asig = -toSFraction(aCos1.next()) + toSFraction(aCos1b.next()); - - return MonoOutput::fromNBit(asig.getNF()+asig.getNI(), asig.asRaw());*/ return MonoOutput::fromAlmostNBit(12, asig); +*/ + + +/* + This is letting Mozzi compute the number of bits for you. + The syntax is a bit more cumbersome but FixMath will be + clever enough to figure out the exact number of bits needed + to create asig without any overflow, but no more. + This number of bits will be used by Mozzi for right/left shifting + the number to match the capability of the system. +*/ + auto asig = + toSFraction(aCos1.next()) + toSFraction(aCos1b.next()) + + toSFraction(aCos2.next()) + toSFraction(aCos2b.next()) + + toSFraction(aCos3.next()) + toSFraction(aCos3b.next()) + + toSFraction(aCos4.next()) + toSFraction(aCos4b.next()) + + toSFraction(aCos5.next()) + toSFraction(aCos5b.next()) + + toSFraction(aCos6.next()) + toSFraction(aCos6b.next()); /* + +toSFraction(aCos7.next()) + toSFraction(aCos7b.next()) +*/ + return MonoOutput::fromSFix(asig); + } From 672ce218ddda5cd72a656b6bc4a1d22db16e0467 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 26 Feb 2024 21:32:08 +0100 Subject: [PATCH 162/215] More specific templates for Oscil and mozzi_midi --- Oscil.h | 14 ++++++++------ mozzi_midi.h | 29 +++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Oscil.h b/Oscil.h index deeca59ee..636a4adc8 100644 --- a/Oscil.h +++ b/Oscil.h @@ -157,9 +157,9 @@ class Oscil each direction. This fixed point math number is interpreted as a SFix<15,16> internally. @return a sample from the table. */ - template + template inline - int8_t phMod(SFix phmod_proportion) + int8_t phMod(SFix phmod_proportion) { return phMod(SFix<15,16>(phmod_proportion).asRaw()); } @@ -254,8 +254,9 @@ class Oscil less than 64 Hz. @param frequency in UFix<24,8> fixed-point number format. */ + template inline - void setFreq(UFix<24,8> frequency) + void setFreq(UFix<24,8,RANGE> frequency) { setFreq_Q24n8(frequency.asRaw()); } @@ -293,8 +294,9 @@ class Oscil @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. @param frequency in UFix<16,16> fixed-point number format. */ + template inline - void setFreq(UFix<16,16> frequency) + void setFreq(UFix<16,16,RANGE> frequency) { setFreq_Q16n16(frequency.asRaw()); } @@ -307,9 +309,9 @@ class Oscil @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance. @param frequency in SFix<16,16> fixed-point number format. */ - template + template inline - void setFreq(SFix frequency) + void setFreq(SFix frequency) { setFreq_Q16n16(UFix<16,16>(frequency).asRaw()); } diff --git a/mozzi_midi.h b/mozzi_midi.h index 0f51fca38..94dd04e2b 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -113,21 +113,34 @@ inline Q16n16 Q16n16_mtof(Q16n16 midival_fractional) return (Q16n16) (freq1+ diff_fraction); }; -inline UFix<16,16> mtof(UFix<16,16> midival) +/** @ingroup midi +Converts midi note number with speed and accuracy from a UFix<16,16>. +Uses Q16n16_mtof internally. +*/ +template +inline UFix<16,16> mtof(UFix<16,16,RANGE> midival) { return UFix<16,16>::fromRaw(Q16n16_mtof(midival.asRaw())); -} +}; -template - inline UFix<16,16> mtof(UFix midival) +/** @ingroup midi +Converts midi note number with speed and accuracy from any UFix. +Uses Q16n16_mtof internally. +*/ +template +inline UFix<16,16> mtof(UFix midival) { return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw())); -} +}; -template - inline UFix<16,16> mtof(SFix midival) +/** @ingroup midi +Converts midi note number with speed and accuracy from any SFix. +Uses Q16n16_mtof internally. +*/ +template +inline UFix<16,16> mtof(SFix midival) { return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw())); -} +}; #endif /* MOZZI_MIDI_H_ */ From 4b483ddf81df24c48eb523615a330d07da1542b9 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 26 Feb 2024 22:01:18 +0100 Subject: [PATCH 163/215] SFix actual number of bits is one extra compared to said size (which is the range of attainable values) --- AudioOutput.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AudioOutput.h b/AudioOutput.h index 0d655aee3..b2d14a0b6 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -128,7 +128,7 @@ struct MonoOutput { static inline MonoOutput from16Bit(int16_t l) { return fromNBit(16, l); } /** Construct an audio frame from a SFix type from FixMath. Mozzi will figure out how many bits are in there and performs appropriate shifting to match the output range. */ template - static inline MonoOutput fromSFix(SFix l) { return MonoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF))) ;} + static inline MonoOutput fromSFix(SFix l) { return MonoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF+1))) ;} /** Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit range, e.g. at N=8 bits and a litte. On most platforms, this is * exactly the same as fromNBit(), shifting up or down to the platforms' available resolution. * @@ -174,7 +174,7 @@ template static inline StereoOutput fromNBit(uint8_t bits, T l, T r) static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); } /** See @ref MonoOutput::fromSFix(), stereo variant. Note that the two channels do not need to have the same number of bits. */ template - static inline StereoOutput fromSFix(SFix l, SFix<_NI,_NF,_RANGE> r) { return StereoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF)), SCALE_AUDIO(r.asRaw(), (_NI+_NF))); } + static inline StereoOutput fromSFix(SFix l, SFix<_NI,_NF,_RANGE> r) { return StereoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF+1)), SCALE_AUDIO(r.asRaw(), (_NI+_NF+1))); } /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */ template static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); } private: From a52b44eef91062cfe3bf11285027c0703a2d5200 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 28 Feb 2024 21:25:16 +0100 Subject: [PATCH 164/215] Adapted AMSynth example to FixMath --- examples/06.Synthesis/AMsynth/AMsynth.ino | 83 +++++++++++------------ 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/examples/06.Synthesis/AMsynth/AMsynth.ino b/examples/06.Synthesis/AMsynth/AMsynth.ino index b98892600..ebd03e3e3 100644 --- a/examples/06.Synthesis/AMsynth/AMsynth.ino +++ b/examples/06.Synthesis/AMsynth/AMsynth.ino @@ -11,23 +11,25 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: + Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Tim Barrass 2012, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. */ -#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable + +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include -#include // table for Oscils to play -#include +#include // table for Oscils to play #include #include #include +#include + // audio oscils Oscil aCarrier(COS2048_DATA); @@ -35,76 +37,71 @@ Oscil aModulator(COS2048_DATA); Oscil aModDepth(COS2048_DATA); // for scheduling note changes in updateControl() -EventDelay kNoteChangeDelay; +EventDelay kNoteChangeDelay; -// synthesis parameters in fixed point formats -Q8n8 ratio; // unsigned int with 8 integer bits and 8 fractional bits -Q24n8 carrier_freq; // unsigned long with 24 integer bits and 8 fractional bits -Q24n8 mod_freq; // unsigned long with 24 integer bits and 8 fractional bits +UFix<8, 8> ratio; // unsigned int with 8 integer bits and 8 fractional bits +UFix<24, 8> carrier_freq; // unsigned long with 24 integer bits and 8 fractional bits // for random notes -Q8n0 octave_start_note = 42; +const UFix<7, 0> octave_start_note = 42; -void setup(){ - ratio = float_to_Q8n8(3.0f); // define modulation ratio in float and convert to fixed-point - kNoteChangeDelay.set(200); // note duration ms, within resolution of MOZZI_CONTROL_RATE - aModDepth.setFreq(13.f); // vary mod depth to highlight am effects - randSeed(); // reseed the random generator for different results each time the sketch runs +void setup() { + ratio = 3; + kNoteChangeDelay.set(200); // note duration ms, within resolution of MOZZI_CONTROL_RATE + aModDepth.setFreq(13.f); // vary mod depth to highlight am effects + randSeed(); // reseed the random generator for different results each time the sketch runs startMozzi(); } -void updateControl(){ - static Q16n16 last_note = octave_start_note; - if(kNoteChangeDelay.ready()){ +void updateControl() { + static auto last_note = octave_start_note; + + if (kNoteChangeDelay.ready()) { // change octave now and then - if(rand((byte)5)==0){ - last_note = 36+(rand((byte)6)*12); + if (rand((byte)5) == 0) { + last_note = UFix<7, 0>(36 + (rand((byte)6) * 12)); } // change step up or down a semitone occasionally - if(rand((byte)13)==0){ - last_note += 1-rand((byte)3); + if (rand((byte)13) == 0) { + last_note = last_note + SFix<7, 0>(1 - rand((byte)3)); } // change modulation ratio now and then - if(rand((byte)5)==0){ - ratio = ((Q8n8) 1+ rand((byte)5)) <<8; + if (rand((byte)5) == 0) { + ratio = 1 + rand((byte)5); } // sometimes add a fractionto the ratio - if(rand((byte)5)==0){ - ratio += rand((byte)255); + if (rand((byte)5) == 0) { + ratio = ratio + toUFraction(rand((byte)255)); } // step up or down 3 semitones (or 0) - last_note += 3 * (1-rand((byte)3)); + last_note = last_note + SFix<7, 0>(3 * (1 - rand((byte)3))); // convert midi to frequency - Q16n16 midi_note = Q8n0_to_Q16n16(last_note); - carrier_freq = Q16n16_to_Q24n8(Q16n16_mtof(midi_note)); + carrier_freq = mtof(last_note); // calculate modulation frequency to stay in ratio with carrier - mod_freq = (carrier_freq * ratio)>>8; // (Q24n8 Q8n8) >> 8 = Q24n8 + auto mod_freq = carrier_freq * ratio; - // set frequencies of the oscillators - aCarrier.setFreq_Q24n8(carrier_freq); - aModulator.setFreq_Q24n8(mod_freq); + // set frequencies of the oscillators + aCarrier.setFreq(carrier_freq); + aModulator.setFreq(mod_freq); // reset the note scheduler kNoteChangeDelay.start(); } - - } -AudioOutput updateAudio(){ - long mod = (128u+ aModulator.next()) * ((byte)128+ aModDepth.next()); - return MonoOutput::fromNBit(24, mod * aCarrier.next()); +AudioOutput updateAudio() { + auto mod = UFix<8, 0>(128 + aModulator.next()) * UFix<8, 0>(128 + aModDepth.next()); + return MonoOutput::fromSFix(mod * toSFraction(aCarrier.next())); } - -void loop(){ +void loop() { audioHook(); } From 1730643cfec7eaaf881ddce43fc2368d9afe36c1 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 28 Feb 2024 22:12:19 +0100 Subject: [PATCH 165/215] Adapted Waveshapper_Difference_Tone with FixMath --- .../Waveshaper_Difference_Tone.ino | 86 +++++++++++++++++++ .../Waveshaper_Difference_Tone_FixMath.ino | 79 +++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino create mode 100644 examples/06.Synthesis/Waveshaper_Difference_Tone_FixMath/Waveshaper_Difference_Tone_FixMath.ino diff --git a/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino b/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino new file mode 100644 index 000000000..95395e85d --- /dev/null +++ b/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino @@ -0,0 +1,86 @@ +/* Example using waveshaping to modify the spectrum of an audio signal + using Mozzi sonification library. + + Demonstrates the use of WaveShaper(), EventDelay(), Smooth(), + rand(), and fixed-point numbers. + + Note that a similar example but using the newer FixMath + library is also available in Waveshaper_Difference_Tone_FixMath. + + Circuit: Audio output on digital pin 9 on a Uno or similar, or + DAC/A14 on Teensy 3.1, or + check the README or http://sensorium.github.com/Mozzi/ + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Tim Barrass 2012, CC by-nc-sa. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + + +// use #define for CONTROL_RATE, not a constant +#define CONTROL_RATE 64 // powers of 2 please + +// use: Oscil oscilName (wavetable), look in .h file of table #included above +Oscil aSin1(SIN2048_DATA); // sine wave sound source +Oscil aSin2(SIN2048_DATA); // sine wave sound source +Oscil aGain(SIN2048_DATA); // to fade audio signal in and out before waveshaping + +// for scheduling note changes +EventDelay kChangeNoteDelay; + +// audio frequency as Q16n16 fractional number +Q16n16 freq1 = Q8n0_to_Q16n16(300); + + + + +void setup(){ + startMozzi(CONTROL_RATE); // set a control rate of 64 (powers of 2 please) + aSin1.setFreq_Q16n16(freq1); // set the frequency with a Q16n16 fractional number + aGain.setFreq(0.2f); // use a float for low frequencies, in setup it doesn't need to be fast + kChangeNoteDelay.set(2000); // note duration ms, within resolution of CONTROL_RATE +} + + +void updateControl(){ + if(kChangeNoteDelay.ready()){ + // change proportional frequency of second tone + byte harmonic = rand((byte)12); + byte shimmer = rand((byte)255); + Q16n16 harmonic_step = freq1/12; + Q16n16 freq2difference = harmonic*harmonic_step; + freq2difference += (harmonic_step*shimmer)>>11; + Q16n16 freq2 = freq1-freq2difference; + aSin2.setFreq_Q16n16(freq2); // set the frequency with a Q16n16 fractional number + kChangeNoteDelay.start(); + } +} + + +int updateAudio(){ + int asig = (int)((((uint32_t)aSin1.next()+ aSin2.next())*(200u+aGain.next()))>>3); + int clipped = constrain(asig,-244,243); + return clipped; +} + + +void loop(){ + audioHook(); // required here +} + + + + + + + diff --git a/examples/06.Synthesis/Waveshaper_Difference_Tone_FixMath/Waveshaper_Difference_Tone_FixMath.ino b/examples/06.Synthesis/Waveshaper_Difference_Tone_FixMath/Waveshaper_Difference_Tone_FixMath.ino new file mode 100644 index 000000000..9144846cf --- /dev/null +++ b/examples/06.Synthesis/Waveshaper_Difference_Tone_FixMath/Waveshaper_Difference_Tone_FixMath.ino @@ -0,0 +1,79 @@ +/* Example using waveshaping to modify the spectrum of an audio signal + using Mozzi sonification library. + + Nearly verbatim translation from Waveshaper_Difference_Tone example + but using using FixMath instead of mozzi_fixmath. + + Demonstrates the use of WaveShaper(), EventDelay(), Smooth(), + rand(), and fixed-point numbers using FixMath. + + Circuit: Audio output on digital pin 9 on a Uno or similar, or + DAC/A14 on Teensy 3.1, or + check the README or http://sensorium.github.com/Mozzi/ + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Tim Barrass 2012, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// use #define for CONTROL_RATE, not a constant +#define MOZZI_CONTROL_RATE 64 // powers of 2 please + +// use: Oscil oscilName (wavetable), look in .h file of table #included above +Oscil aSin1(SIN2048_DATA); // sine wave sound source +Oscil aSin2(SIN2048_DATA); // sine wave sound source +Oscil aGain(SIN2048_DATA); // to fade audio signal in and out before waveshaping + +// for scheduling note changes +EventDelay kChangeNoteDelay; + +const UFix<6, 0> freq1 = 44; // original example says 300, but overflows to 44; +const auto harmonic_step = freq1 * UFix<8, 0>(12).invAccurate(); // a bit weird way of saying harmonic_step = freq1/12… + + + + +void setup() { + aSin1.setFreq(freq1); // set the frequency with a Q16n16 fractional number + aGain.setFreq(0.2f); // use a float for low frequencies, in setup it doesn't need to be fast + kChangeNoteDelay.set(2000); // note duration ms, within resolution of CONTROL_RATE + startMozzi(); +} + +void updateControl() { + if (kChangeNoteDelay.ready()) { + UFix<4, 0> harmonic = rand((byte)12); + auto shimmer = toSFraction(rand((byte)255)); + auto freq2difference = (harmonic * harmonic_step) + (harmonic_step * shimmer).sR<2>(); + auto freq2 = (freq1 - freq2difference); + aSin2.setFreq(freq2); + kChangeNoteDelay.start(); + } +} + + +/** +@todo Add a constrain for FixMath +*/ +AudioOutput updateAudio() { + int asig = (int)((((uint32_t)aSin1.next() + aSin2.next()) * (200u + aGain.next())) >> 3); + int16_t clipped = constrain(asig, -244, 243); + return clipped; +} + +void loop() { + audioHook(); // required here +} From 5a121dbc5b5c76f3c51d0c37af88655615e3a9d1 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Wed, 28 Feb 2024 22:16:43 +0100 Subject: [PATCH 166/215] Waveshapper_difference_tone to Mozzi2.0 standard (Where is this example coming from??) --- .../Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino b/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino index 95395e85d..acad4dd8c 100644 --- a/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino +++ b/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino @@ -17,7 +17,7 @@ Tim Barrass 2012, CC by-nc-sa. */ -#include +#include #include #include #include @@ -28,7 +28,7 @@ // use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 64 // powers of 2 please +#define MOZZI_CONTROL_RATE 64 // powers of 2 please // use: Oscil oscilName (wavetable), look in .h file of table #included above Oscil aSin1(SIN2048_DATA); // sine wave sound source From 75ad03d42acad28f4788353ef526dc3a394bf12e Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 3 Mar 2024 15:46:57 +0100 Subject: [PATCH 167/215] Corrected Line with FixMath --- Line.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Line.h b/Line.h index 170873155..1aa68cac6 100644 --- a/Line.h +++ b/Line.h @@ -324,7 +324,7 @@ class Line> private: typedef UFix internal_type; internal_type current_value; - internal_type step_size; + SFix step_size; public: /** Constructor. Use the template parameter to set the type of numbers you @@ -361,7 +361,7 @@ class Line> void set(internal_type targetvalue, UFix<_NI,0> num_steps) { if(num_steps.asRaw()) { - internal_type numerator = targetvalue-current_value; + auto numerator = targetvalue-current_value; step_size = numerator*num_steps.invAccurate(); } else { step_size = 0; @@ -378,7 +378,7 @@ class Line> void set(internal_type targetvalue, T num_steps) { if(num_steps) { - internal_type numerator = targetvalue-current_value; + auto numerator = targetvalue-current_value; step_size = internal_type(numerator.asRaw()/num_steps,true); } else { step_size = 0; @@ -407,7 +407,7 @@ class Line> private: typedef SFix internal_type; internal_type current_value; - internal_type step_size; + SFix step_size; public: /** Constructor. Use the template parameter to set the type of numbers you @@ -444,7 +444,7 @@ class Line> void set(internal_type targetvalue, UFix<_NI,0> num_steps) { if(num_steps.asRaw()) { - internal_type numerator = targetvalue-current_value; + auto numerator = targetvalue-current_value; step_size = numerator*num_steps.invAccurate(); } else { step_size = 0; @@ -461,7 +461,7 @@ class Line> void set(internal_type targetvalue, T num_steps) { if(num_steps) { - internal_type numerator = targetvalue-current_value; + auto numerator = targetvalue-current_value; step_size = internal_type(numerator.asRaw()/num_steps,true); } else { step_size = 0; From be74b3bde2cb69fd5474041327b610f66d1df48b Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 3 Mar 2024 16:02:10 +0100 Subject: [PATCH 168/215] Changed Line_vs_Smooth example to FixMath --- .../Line_vs_Smooth/Line_vs_Smooth.ino | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino index 4d88d3c3e..69da1c958 100644 --- a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino +++ b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino @@ -6,7 +6,7 @@ updated in the background while audio generation continues, and the most recent readings can be read anytime from an array. Also demonstrates linear interpolation with Line(), - filtering with Smooth(), and fixed point numbers. + filtering with Smooth(), and fixed point numbers from FixMath Circuit: Audio output on digital pin 9 (for standard output on a Uno or similar), or @@ -22,14 +22,14 @@ Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Tim Barrass 2013, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. */ #define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable #include #include #include // sine table for oscillator -#include +#include #include #include #include @@ -40,13 +40,13 @@ Oscil aSin1(SIN2048_DATA); // Line to interpolate frequency for aSin0. -// Q16n16 is basically (yourNumber << 16) +// UFix<16,16>(yourNumber) is basically encoded in 16bits +// with 16 extra bits for additionnal precision. // Line needs the small analog input integer values of 0-1023 // to be scaled up if the time (the number of steps) is big // enough that distance/time gives a step-size of 0. -// Then you need floats (which are sometimes too slow and create glitches), -// or fixed point. Q16n16: ugly but good. -Line aInterpolate; +// Then you need floats (which are sometimes too slow and create glitches). +Line > aInterpolate; // the number of audio steps the line has to take to reach the next control value const unsigned int AUDIO_STEPS_PER_CONTROL = MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE; @@ -60,8 +60,8 @@ Smooth aSmooth(smoothness); // to smooth frequency for aSin1 void setup(){ - aSin0.setFreq(660.f); - aSin1.setFreq(220.f); + aSin0.setFreq(660); + aSin1.setFreq(220); startMozzi(); } @@ -69,20 +69,21 @@ void setup(){ volatile unsigned int freq1; // global so it can be used in updateAudio, volatile to stop it getting changed while being used void updateControl(){ - Q16n16 freq0 = Q16n0_to_Q16n16(mozziAnalogRead(0)); // 0 to 1023, scaled up to Q16n16 format + UFix<16,16> freq0 = mozziAnalogRead(0); // 0 to 1023, with an additionnal 16bits of precision (which will be used in the interpolation.) freq1 = (unsigned int) mozziAnalogRead(1); // 0 to 1023 - aInterpolate.set(freq0, AUDIO_STEPS_PER_CONTROL); } AudioOutput updateAudio(){ - Q16n16 interpolatedFreq = aInterpolate.next(); // get the next linear interpolated freq - aSin0.setFreq_Q16n16(interpolatedFreq); + UFix<16,16> interpolatedFreq = aInterpolate.next(); // get the next linear interpolated freq + aSin0.setFreq(interpolatedFreq); int smoothedFreq = aSmooth.next(freq1); // get the next filtered frequency aSin1.setFreq(smoothedFreq); - return MonoOutput::fromNBit(9, (int) (aSin0.next() + aSin1.next())); + + // Here we add to SFix numbers, created from the Oscil, for the output. Mozzi knows what is the final range of this allowing for auto-scaling. + return MonoOutput::fromSFix(toSFraction(aSin0.next()) + toSFraction(aSin1.next())); // auto-scaling of the output. } From 7b2b1d3e840b45671db5888152b9f7f423555d2e Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 3 Mar 2024 16:45:46 +0100 Subject: [PATCH 169/215] Modified Waveshaper example to FixMath --- .../06.Synthesis/Waveshaper/Waveshaper.ino | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/06.Synthesis/Waveshaper/Waveshaper.ino b/examples/06.Synthesis/Waveshaper/Waveshaper.ino index dfff9408b..16ad966e5 100644 --- a/examples/06.Synthesis/Waveshaper/Waveshaper.ino +++ b/examples/06.Synthesis/Waveshaper/Waveshaper.ino @@ -2,7 +2,7 @@ using Mozzi sonification library. Demonstrates the use of WaveShaper(), EventDelay(), Smooth(), - rand(), and fixed-point numbers. + rand(), and FixMath. Circuit: Audio output on digital pin 9 on a Uno or similar, or DAC/A14 on Teensy 3.1, or @@ -14,7 +14,7 @@ Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Tim Barrass 2012, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. */ #include @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -43,12 +44,11 @@ WaveShaper aCompress(WAVESHAPE_COMPRESS_512_TO_488_DATA); // to compress i EventDelay kChangeNoteDelay; // for random notes -Q8n0 octave_start_note = 42; -Q24n8 carrier_freq; // unsigned long with 24 integer bits and 8 fractional bits +UFix<7,0> octave_start_note = 42; // smooth transitions between notes -Smooth kSmoothFreq(0.85f); -int target_freq, smoothed_freq; +Smooth > kSmoothFreq(0.85f); +UFix<14,2> target_freq, smoothed_freq; //Optimization to have the frequencies on 16bits only. void setup(){ @@ -88,12 +88,12 @@ void updateControl(){ // change octave to midi 24 or any of 3 octaves above octave_start_note = (rand((byte)4)*12)+36; } - Q16n16 midi_note = Q8n0_to_Q16n16(octave_start_note+rndPentatonic()); - target_freq = Q16n16_to_Q16n0(Q16n16_mtof(midi_note)); // has to be 16 bits for Smooth + auto midi_note = octave_start_note + toUInt(rndPentatonic()); + target_freq = mtof(midi_note); // mtof return a UFix<16,16>, which is casted to UFix<14,2> (could overflow if the frequency is greater than 16kHz) kChangeNoteDelay.start(); } - smoothed_freq = kSmoothFreq.next(target_freq*4); // temporarily scale up target_freq to get better int smoothing at low values - aSin.setFreq(smoothed_freq/4); // then scale it back down after it's smoothed + smoothed_freq = kSmoothFreq.next(target_freq); // temporarily scale up target_freq to get better int smoothing at low values + aSin.setFreq(smoothed_freq); } From 8b760a6d5f753760b75b8cdf28e7f633a6d2a767 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 4 Mar 2024 21:29:38 +0100 Subject: [PATCH 170/215] Put FM_synth_FixMath to Mozzi2.0 Fix FixMath Removed comment --- .../FMsynth_FixMath/FMsynth_FixMath.ino | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino b/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino index 552ec2bba..1cf0e13ac 100644 --- a/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino +++ b/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino @@ -13,10 +13,11 @@ Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Thomas Combriat and the Mozzi team 2023, CC by-nc-sa. + Tim Barrass 2012, Thomas Combriat and the Mozzi team 2023, CC by-nc-sa. */ - +#include +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include @@ -27,11 +28,10 @@ #include -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable -Oscil aCarrier(COS2048_DATA); -Oscil aModulator(COS2048_DATA); -Oscil kModIndex(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); +Oscil kModIndex(COS2048_DATA); UFix<0, 16> mod_index; UFix<16, 16> deviation; @@ -47,7 +47,7 @@ EventDelay kNoteChangeDelay; const UFix<7, 0> note_upper_limit = 50, note_lower_limit = 32; -UFix<7, 0> note0 = note_lower_limit, note1 = note_lower_limit + UFix<7, 0>(5), target_note = note0; +UFix<7, 0> note0 = note_lower_limit, note1 = note_lower_limit + UFix<7, 0>(5), target_note = 0; SFix<2, 0> note_change_step = 3; // will only take +3 or -3, 2bits are enough for that UFix<7,8> smoothed_note; @@ -57,7 +57,7 @@ Smooth> kSmoothNote(0.95f); void setup() { kNoteChangeDelay.set(768); kModIndex.setFreq(.768f); // sync with kNoteChangeDelay - startMozzi(CONTROL_RATE); + startMozzi(); } void setFreqs(UFix<7, 8> midi_note) { @@ -92,7 +92,7 @@ void updateControl() { } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ auto modulation = (deviation * toSFraction(aModulator.next())); return MonoOutput::from8Bit(aCarrier.phMod(modulation)); } From 57f94f42218bbb1d314617437edfd19278c24f1e Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 4 Mar 2024 22:18:17 +0100 Subject: [PATCH 171/215] Modified FMSynth_32k to FixMath Removed comment --- .../FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino | 115 ++++++++---------- .../FMsynth_FixMath/FMsynth_FixMath.ino | 5 + 2 files changed, 57 insertions(+), 63 deletions(-) diff --git a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino index ee7a9bc50..367b3d69c 100644 --- a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino +++ b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino @@ -3,7 +3,7 @@ Demonstrates Oscil::phMod() for phase modulation, Smooth() for smoothing control signals, - and Mozzi's fixed point number types for fractional frequencies. + and FixMath fixed point number types for fractional frequencies. This sketch using HIFI mode is not for Teensy 3.1. @@ -39,93 +39,82 @@ Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Tim Barrass 2012-13, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. */ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM #define MOZZI_AUDIO_RATE 32768 -#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable #include #include -#include // table for Oscils to play +#include // table for Oscils to play #include -#include +#include #include #include + + Oscil aCarrier(COS2048_DATA); Oscil aModulator(COS2048_DATA); Oscil kModIndex(COS2048_DATA); -// The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm ) -// It will vary according to the frequency that is modulating the carrier and the amount of deviation. -// so deviation d = I Fm -// haven't quite worked this out properly yet... +UFix<0, 16> mod_index; +UFix<8, 16> deviation; // 8 so that we do not exceed 32bits in updateAudio -Q8n8 mod_index;// = float_to_Q8n8(2.0f); // constant version -Q16n16 deviation; +UFix<16, 16> carrier_freq, mod_freq; +const UFix<0,16> modulation_amp = 0.001; // how much the modulation index will vary around its mean +const UFix<2,0> mean_modulation_unscaled = 2; // the real mean modulation will be mean_modulation_unscaled * modulation_max + // this one is adding a bias to the oscillator, hence it should be bigger than one. -Q16n16 carrier_freq, mod_freq; - -// FM ratio between oscillator frequencies, stays the same through note range -Q8n8 mod_to_carrier_ratio = float_to_Q8n8(3.f); +const UFix<2, 0> mod_to_carrier_ratio = 3; // 3 fits in UFix<2,0> which has a maximum range of (2^2)-1=3 EventDelay kNoteChangeDelay; -// for note changes -Q7n8 target_note, note0, note1, note_upper_limit, note_lower_limit, note_change_step, smoothed_note; - -// using Smooth on midi notes rather than frequency, -// because fractional frequencies need larger types than Smooth can handle -// Inefficient, but...until there is a better Smooth.... -Smooth kSmoothNote(0.95f); - -void setup(){ - kNoteChangeDelay.set(768); // ms countdown, taylored to resolution of MOZZI_CONTROL_RATE - kModIndex.setFreq(.768f); // sync with kNoteChangeDelay - target_note = note0; - note_change_step = Q7n0_to_Q7n8(3); - note_upper_limit = Q7n0_to_Q7n8(50); - note_lower_limit = Q7n0_to_Q7n8(32); - note0 = note_lower_limit; - note1 = note_lower_limit + Q7n0_to_Q7n8(5); +const UFix<7, 0> note_upper_limit = 50, note_lower_limit = 32; + +UFix<7, 0> note0 = note_lower_limit, note1 = note_lower_limit + UFix<7, 0>(5), target_note = 0; +SFix<2, 0> note_change_step = 3; // will only take +3 or -3, 2bits are enough for that + +UFix<7,8> smoothed_note; + +Smooth> kSmoothNote(0.95f); + +void setup() { + kNoteChangeDelay.set(768); + kModIndex.setFreq(.768f); // sync with kNoteChangeDelay startMozzi(); } -void setFreqs(Q8n8 midi_note){ - carrier_freq = Q16n16_mtof(Q8n8_to_Q16n16(midi_note)); // convert midi note to fractional frequency - mod_freq = ((carrier_freq>>8) * mod_to_carrier_ratio) ; // (Q16n16>>8) Q8n8 = Q16n16, beware of overflow - deviation = ((mod_freq>>16) * mod_index); // (Q16n16>>16) Q8n8 = Q24n8, beware of overflow - aCarrier.setFreq_Q16n16(carrier_freq); - aModulator.setFreq_Q16n16(mod_freq); +void setFreqs(UFix<7, 8> midi_note) { + carrier_freq = mtof(midi_note); + mod_freq = UFix<14,16>(carrier_freq) * mod_to_carrier_ratio; + deviation = ((UFix<16,0>(mod_freq)) * mod_index).sR<8>(); // the sR here cheaply divides the deviation by 256. + + aCarrier.setFreq(carrier_freq); + aModulator.setFreq(mod_freq); } -void updateControl(){ - // change note - if(kNoteChangeDelay.ready()){ - if (target_note==note0){ - note1 += note_change_step; - target_note=note1; - } - else{ - note0 += note_change_step; - target_note=note0; +void updateControl() { + if (kNoteChangeDelay.ready()) { + if (target_note == note0) + { + note1 = note1 + note_change_step; + target_note = note1; + } + else + { + note0 = note0 + note_change_step; + target_note = note0; } - - // change direction - if(note0>note_upper_limit) note_change_step = Q7n0_to_Q7n8(-3); - if(note0note_upper_limit) note_change_step = -3; + if(note0(); // the sR is to scale back in pure fractional range - // vary the modulation index - mod_index = (Q8n8)350+kModIndex.next(); - - // here's where the smoothing happens smoothed_note = kSmoothNote.next(target_note); setFreqs(smoothed_note); @@ -133,11 +122,11 @@ void updateControl(){ AudioOutput updateAudio(){ - Q15n16 modulation = deviation * aModulator.next() >> 8; - return MonoOutput::from8Bit(aCarrier.phMod(modulation)); // Internally still only 8 bits, will be shifted up to 14 bits in HIFI mode +auto modulation = (deviation * toSFraction(aModulator.next())); +return MonoOutput::from8Bit(aCarrier.phMod(modulation)); } -void loop(){ - audioHook(); -} +void loop() { + audioHook(); +} \ No newline at end of file diff --git a/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino b/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino index 1cf0e13ac..0001c27ae 100644 --- a/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino +++ b/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino @@ -7,6 +7,11 @@ This is the same technique than the FMsynth example but using FixMath instead of mozzi_fixmath. + Note that it is slightly less optimized (but runs fine on an + Uno) in order to make the underlying algorithm clearer. + An optimized version, using FixMath can be found in the + example FMsynth_32k_HIFI. + Mozzi documentation/API https://sensorium.github.io/Mozzi/doc/html/index.html From be0a9b0ae7fc8437d22ff6e0fd47d582716a1eed Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Mon, 4 Mar 2024 23:06:23 +0100 Subject: [PATCH 172/215] Attempt to fix the actions --- .../Waveshaper_Difference_Tone.ino | 86 ------------------- .../Waveshaper_Difference_Tone_FixMath.ino | 79 ----------------- 2 files changed, 165 deletions(-) delete mode 100644 examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino delete mode 100644 examples/06.Synthesis/Waveshaper_Difference_Tone_FixMath/Waveshaper_Difference_Tone_FixMath.ino diff --git a/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino b/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino deleted file mode 100644 index acad4dd8c..000000000 --- a/examples/06.Synthesis/Waveshaper_Difference_Tone/Waveshaper_Difference_Tone.ino +++ /dev/null @@ -1,86 +0,0 @@ -/* Example using waveshaping to modify the spectrum of an audio signal - using Mozzi sonification library. - - Demonstrates the use of WaveShaper(), EventDelay(), Smooth(), - rand(), and fixed-point numbers. - - Note that a similar example but using the newer FixMath - library is also available in Waveshaper_Difference_Tone_FixMath. - - Circuit: Audio output on digital pin 9 on a Uno or similar, or - DAC/A14 on Teensy 3.1, or - check the README or http://sensorium.github.com/Mozzi/ - - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users - - Tim Barrass 2012, CC by-nc-sa. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - - -// use #define for CONTROL_RATE, not a constant -#define MOZZI_CONTROL_RATE 64 // powers of 2 please - -// use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin1(SIN2048_DATA); // sine wave sound source -Oscil aSin2(SIN2048_DATA); // sine wave sound source -Oscil aGain(SIN2048_DATA); // to fade audio signal in and out before waveshaping - -// for scheduling note changes -EventDelay kChangeNoteDelay; - -// audio frequency as Q16n16 fractional number -Q16n16 freq1 = Q8n0_to_Q16n16(300); - - - - -void setup(){ - startMozzi(CONTROL_RATE); // set a control rate of 64 (powers of 2 please) - aSin1.setFreq_Q16n16(freq1); // set the frequency with a Q16n16 fractional number - aGain.setFreq(0.2f); // use a float for low frequencies, in setup it doesn't need to be fast - kChangeNoteDelay.set(2000); // note duration ms, within resolution of CONTROL_RATE -} - - -void updateControl(){ - if(kChangeNoteDelay.ready()){ - // change proportional frequency of second tone - byte harmonic = rand((byte)12); - byte shimmer = rand((byte)255); - Q16n16 harmonic_step = freq1/12; - Q16n16 freq2difference = harmonic*harmonic_step; - freq2difference += (harmonic_step*shimmer)>>11; - Q16n16 freq2 = freq1-freq2difference; - aSin2.setFreq_Q16n16(freq2); // set the frequency with a Q16n16 fractional number - kChangeNoteDelay.start(); - } -} - - -int updateAudio(){ - int asig = (int)((((uint32_t)aSin1.next()+ aSin2.next())*(200u+aGain.next()))>>3); - int clipped = constrain(asig,-244,243); - return clipped; -} - - -void loop(){ - audioHook(); // required here -} - - - - - - - diff --git a/examples/06.Synthesis/Waveshaper_Difference_Tone_FixMath/Waveshaper_Difference_Tone_FixMath.ino b/examples/06.Synthesis/Waveshaper_Difference_Tone_FixMath/Waveshaper_Difference_Tone_FixMath.ino deleted file mode 100644 index 9144846cf..000000000 --- a/examples/06.Synthesis/Waveshaper_Difference_Tone_FixMath/Waveshaper_Difference_Tone_FixMath.ino +++ /dev/null @@ -1,79 +0,0 @@ -/* Example using waveshaping to modify the spectrum of an audio signal - using Mozzi sonification library. - - Nearly verbatim translation from Waveshaper_Difference_Tone example - but using using FixMath instead of mozzi_fixmath. - - Demonstrates the use of WaveShaper(), EventDelay(), Smooth(), - rand(), and fixed-point numbers using FixMath. - - Circuit: Audio output on digital pin 9 on a Uno or similar, or - DAC/A14 on Teensy 3.1, or - check the README or http://sensorium.github.com/Mozzi/ - - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users - - Tim Barrass 2012, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// use #define for CONTROL_RATE, not a constant -#define MOZZI_CONTROL_RATE 64 // powers of 2 please - -// use: Oscil oscilName (wavetable), look in .h file of table #included above -Oscil aSin1(SIN2048_DATA); // sine wave sound source -Oscil aSin2(SIN2048_DATA); // sine wave sound source -Oscil aGain(SIN2048_DATA); // to fade audio signal in and out before waveshaping - -// for scheduling note changes -EventDelay kChangeNoteDelay; - -const UFix<6, 0> freq1 = 44; // original example says 300, but overflows to 44; -const auto harmonic_step = freq1 * UFix<8, 0>(12).invAccurate(); // a bit weird way of saying harmonic_step = freq1/12… - - - - -void setup() { - aSin1.setFreq(freq1); // set the frequency with a Q16n16 fractional number - aGain.setFreq(0.2f); // use a float for low frequencies, in setup it doesn't need to be fast - kChangeNoteDelay.set(2000); // note duration ms, within resolution of CONTROL_RATE - startMozzi(); -} - -void updateControl() { - if (kChangeNoteDelay.ready()) { - UFix<4, 0> harmonic = rand((byte)12); - auto shimmer = toSFraction(rand((byte)255)); - auto freq2difference = (harmonic * harmonic_step) + (harmonic_step * shimmer).sR<2>(); - auto freq2 = (freq1 - freq2difference); - aSin2.setFreq(freq2); - kChangeNoteDelay.start(); - } -} - - -/** -@todo Add a constrain for FixMath -*/ -AudioOutput updateAudio() { - int asig = (int)((((uint32_t)aSin1.next() + aSin2.next()) * (200u + aGain.next())) >> 3); - int16_t clipped = constrain(asig, -244, 243); - return clipped; -} - -void loop() { - audioHook(); // required here -} From f7a40f2ef89af5d96495d4ccadda5608df2c7d93 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 5 Mar 2024 21:09:23 +0100 Subject: [PATCH 173/215] Adapted AMsynth_HIFI to FixMath --- .../AMsynth_HIFI/AMsynth_HIFI.ino | 86 +++++++++---------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino index 0ccc9139b..566c5a5a4 100644 --- a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino +++ b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino @@ -7,7 +7,7 @@ values, random numbers with rand(), and EventDelay() for scheduling. - Important: + Important: This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which is not available on all boards (among others, it works on the classic Arduino boards, but not Teensy 3.x and friends). @@ -30,25 +30,26 @@ Alternatively using 39 ohm, 4.99k and 470nF components will work directly with headphones. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: + Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Tim Barrass 2012, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. */ + #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM - #include #include -#include // table for Oscils to play -#include +#include // table for Oscils to play #include #include #include +#include + // audio oscils Oscil aCarrier(COS2048_DATA); @@ -56,76 +57,71 @@ Oscil aModulator(COS2048_DATA); Oscil aModDepth(COS2048_DATA); // for scheduling note changes in updateControl() -EventDelay kNoteChangeDelay; +EventDelay kNoteChangeDelay; -// synthesis parameters in fixed point formats -Q8n8 ratio; // unsigned int with 8 integer bits and 8 fractional bits -Q24n8 carrier_freq; // unsigned long with 24 integer bits and 8 fractional bits -Q24n8 mod_freq; // unsigned long with 24 integer bits and 8 fractional bits +UFix<8, 8> ratio; // unsigned int with 8 integer bits and 8 fractional bits +UFix<24, 8> carrier_freq; // unsigned long with 24 integer bits and 8 fractional bits // for random notes -Q8n0 octave_start_note = 42; - -void setup(){ - ratio = float_to_Q8n8(3.0f); // define modulation ratio in float and convert to fixed-point - kNoteChangeDelay.set(200); // note duration ms, within resolution of MOZZI_CONTROL_RATE - aModDepth.setFreq(13.f); // vary mod depth to highlight am effects - randSeed(); // reseed the random generator for different results each time the sketch runs - startMozzi(); // use default MOZZI_CONTROL_RATE 64 +const UFix<7, 0> octave_start_note = 42; + +void setup() { + ratio = 3; + kNoteChangeDelay.set(200); // note duration ms, within resolution of MOZZI_CONTROL_RATE + aModDepth.setFreq(13.f); // vary mod depth to highlight am effects + randSeed(); // reseed the random generator for different results each time the sketch runs + startMozzi(); } -void updateControl(){ - static Q16n16 last_note = octave_start_note; +void updateControl() { + static auto last_note = octave_start_note; - if(kNoteChangeDelay.ready()){ + if (kNoteChangeDelay.ready()) { // change octave now and then - if(rand((byte)5)==0){ - last_note = 36+(rand((byte)6)*12); + if (rand((byte)5) == 0) { + last_note = UFix<7, 0>(36 + (rand((byte)6) * 12)); } // change step up or down a semitone occasionally - if(rand((byte)13)==0){ - last_note += 1-rand((byte)3); + if (rand((byte)13) == 0) { + last_note = last_note + SFix<7, 0>(1 - rand((byte)3)); } // change modulation ratio now and then - if(rand((byte)5)==0){ - ratio = ((Q8n8) 1+ rand((byte)5)) <<8; + if (rand((byte)5) == 0) { + ratio = 1 + rand((byte)5); } - // sometimes add a fraction to the ratio - if(rand((byte)5)==0){ - ratio += rand((byte)255); + // sometimes add a fractionto the ratio + if (rand((byte)5) == 0) { + ratio = ratio + toUFraction(rand((byte)255)); } // step up or down 3 semitones (or 0) - last_note += 3 * (1-rand((byte)3)); + last_note = last_note + SFix<7, 0>(3 * (1 - rand((byte)3))); // convert midi to frequency - Q16n16 midi_note = Q8n0_to_Q16n16(last_note); - carrier_freq = Q16n16_to_Q24n8(Q16n16_mtof(midi_note)); + carrier_freq = mtof(last_note); // calculate modulation frequency to stay in ratio with carrier - mod_freq = (carrier_freq * ratio)>>8; // (Q24n8 Q8n8) >> 8 = Q24n8 + auto mod_freq = carrier_freq * ratio; // set frequencies of the oscillators - aCarrier.setFreq_Q24n8(carrier_freq); - aModulator.setFreq_Q24n8(mod_freq); + aCarrier.setFreq(carrier_freq); + aModulator.setFreq(mod_freq); // reset the note scheduler kNoteChangeDelay.start(); } } - -AudioOutput updateAudio(){ - unsigned int mod = (128u+ aModulator.next()) * ((byte)128+ aModDepth.next()); - return MonoOutput::fromNBit(24, (long)mod * aCarrier.next()); // 16 bit * 8 bit = 24 bit +AudioOutput updateAudio() { + auto mod = UFix<8, 0>(128 + aModulator.next()) * UFix<8, 0>(128 + aModDepth.next()); + return MonoOutput::fromSFix(mod * toSFraction(aCarrier.next())); } - -void loop(){ +void loop() { audioHook(); } From 74ef27175fae95ef58b43cb637120720b895280d Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Tue, 5 Mar 2024 22:28:06 +0100 Subject: [PATCH 174/215] Updated Shepard tones to FixMath --- .../Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino | 67 +++++++++---------- .../Shepard_Tone_HIFI/triangle512_uint8.h | 41 ------------ 2 files changed, 32 insertions(+), 76 deletions(-) delete mode 100644 examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h diff --git a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino index 2500ea881..2c5e14e5b 100644 --- a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino +++ b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino @@ -29,8 +29,10 @@ Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2018, CC by-nc-sa. + Tim Barrass 2018, Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. */ + + #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM #define MOZZI_CONTROL_RATE 128 @@ -38,29 +40,32 @@ #include #include #include -#include "triangle512_uint8.h" +#include #include #include #include -#include // for fixed-point fractional numbers +#include // reset and sync vol and freq controls each cycle EventDelay kTriggerDelay0; EventDelay kTriggerDelay1; -#define NOTE_CENTRE 60 -#define NOTE_RANGE 12 -#define NOTE_START_FIXEDPOINT float_to_Q16n16(NOTE_CENTRE + NOTE_RANGE) // so Line gliss has enough precision -#define NOTE_END_FIXEDPOINT float_to_Q16n16(NOTE_CENTRE - NOTE_RANGE) // so Line gliss has enough precision +const UFix<7,0> NOTE_CENTRE = 60, NOTE_RANGE = 12; +const UFix<7,0> NOTE_START_FIXEDPOINT = NOTE_CENTRE + NOTE_RANGE; +const UFix<7,0> NOTE_END_FIXEDPOINT = NOTE_CENTRE - NOTE_RANGE; #define GLISS_SECONDS 3.f +//#define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)MOZZI_CONTROL_RATE * GLISS_SECONDS)) #define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)MOZZI_CONTROL_RATE * GLISS_SECONDS)) + // use: Line lineName -// audio oscils -Line kGliss0; // Line to slide frequency -Line kGliss1; // Line to slide frequency +// The lines needs more precision than the notes, as they interpolate in between +// here we optimize by choosing the max precision to stay in 16bits (7+9=16) +// note that for an SFix, we would aim for 15 (plus a sign bit). +Line > kGliss0; // Line to slide frequency +Line > kGliss1; // Line to slide frequency // harmonics Oscil aCos0(SIN8192_DATA); @@ -71,12 +76,12 @@ Oscil kVol0(TRIANGLE512_DATA); Oscil kVol1(TRIANGLE512_DATA); // audio volumes updated each control interrupt and reused in audio -long v0, v1; +SFix<0,14> v0, v1; +//SFix<0,7> v0, v1; // micro-optimization void setup() { - //Serial.begin(115200); +//Serial.begin(115200); - // set volume change frequencies kVol0.setFreq(0.5f / GLISS_SECONDS); kVol1.setFreq(0.5f / GLISS_SECONDS); @@ -89,9 +94,8 @@ void setup() { startMozzi(); } - -void updateControl() { - +void updateControl() +{ if (kTriggerDelay0.ready()) { kGliss0.set(NOTE_START_FIXEDPOINT, NOTE_END_FIXEDPOINT, CONTROL_STEPS_PER_GLISS); kVol0.setPhase(0); @@ -99,39 +103,32 @@ void updateControl() { Serial.println("gliss1"); } - if (kTriggerDelay1.ready()) { + if (kTriggerDelay1.ready()) { kGliss1.set(NOTE_START_FIXEDPOINT, NOTE_END_FIXEDPOINT, CONTROL_STEPS_PER_GLISS); kVol1.setPhase(0); kTriggerDelay1.start((int)(GLISS_SECONDS * 1000.f)); // milliseconds Serial.println("\t gliss2"); } - // set harmonic frequencies - Q16n16 gliss0 = kGliss0.next(); // fixed point - float freq0 = Q16n16_to_float(Q16n16_mtof(gliss0)); // convert fixed point to floating point - - Q16n16 gliss1 = kGliss1.next(); // fixed point - float freq1 = Q16n16_to_float(Q16n16_mtof(gliss1)); // convert fixed point to floating point + auto gliss0 = kGliss0.next(); // fixed point + auto gliss1 = kGliss1.next(); // fixed point - aCos0.setFreq(freq0); - aCos1.setFreq(freq1); + aCos0.setFreq(mtof(gliss0)); + aCos1.setFreq(mtof(gliss1)); - v0 = kVol0.next(); - v1 = kVol1.next(); - // Serial.print((byte)v0); Serial.print("\t"); Serial.println((byte)v1); + v0 = toSFraction(kVol0.next()); // convert as a pure fractionnal between -1 and 1 + v1 = toSFraction(kVol1.next()); - // square for perceptual volume - v0 *= v0; - v1 *= v1; + // square for perceptual volume (also makes it positive...) + v0 = v0 * v0; + v1 = v1 * v1; } AudioOutput updateAudio() { - long asig = ((v0 * aCos0.next()) >> 8) + - ((v1 * aCos1.next()) >> 8); - return AudioOutput::fromNBit(17, asig); + auto asig = v0 * toSInt(aCos0.next()) + v1 * toSInt(aCos1.next()); + return AudioOutput::fromSFix(asig); // auto-scaling of the output with SFix } - void loop() { audioHook(); } diff --git a/examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h b/examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h deleted file mode 100644 index bd3d3e7c4..000000000 --- a/examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef TRIANGLE512_H_ -#define TRIANGLE512_H_ - -#include -#include "mozzi_pgmspace.h" - -#define TRIANGLE512_NUM_CELLS 512 -#define TRIANGLE512_SAMPLERATE 512 - -CONSTTABLE_STORAGE(uint8_t) TRIANGLE512_DATA [] = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, -50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, -70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, -108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, -124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, -156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, -172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, -188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, -204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, -220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, -236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, -252, 253, 254, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, -242, 241, 240, 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, -226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, -210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 195, -194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, -178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, -162, 161, 160, 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, -146, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, -130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, -114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, -98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, -78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, -58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, -38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, -18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, }; - - #endif /* TRIANGLE512_H_ */ From 273f2c044449a2020d824990b3156a8cba5368e6 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 10 Mar 2024 16:58:08 +0100 Subject: [PATCH 175/215] Corrected Line_vs_Smooth example --- .../05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino index 69da1c958..d7ed21df2 100644 --- a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino +++ b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino @@ -66,16 +66,17 @@ void setup(){ } -volatile unsigned int freq1; // global so it can be used in updateAudio, volatile to stop it getting changed while being used +unsigned int freq1; // global so it can be used in updateAudio void updateControl(){ UFix<16,16> freq0 = mozziAnalogRead(0); // 0 to 1023, with an additionnal 16bits of precision (which will be used in the interpolation.) freq1 = (unsigned int) mozziAnalogRead(1); // 0 to 1023 + aInterpolate.set(freq0, AUDIO_STEPS_PER_CONTROL); } AudioOutput updateAudio(){ - UFix<16,16> interpolatedFreq = aInterpolate.next(); // get the next linear interpolated freq + auto interpolatedFreq = aInterpolate.next(); // get the next linear interpolated freq aSin0.setFreq(interpolatedFreq); int smoothedFreq = aSmooth.next(freq1); // get the next filtered frequency From e8376db995e3429196e73dfd3d0f6d2d9f8f0e61 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 10 Mar 2024 17:02:24 +0100 Subject: [PATCH 176/215] Changed Detuned beats examples to Mozzi2 --- .../Detuned_Beats_Wash/Detuned_Beats_Wash.ino | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino index 7960c5971..cc3881db1 100644 --- a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino +++ b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino @@ -37,22 +37,22 @@ #include // harmonics -Oscil aCos1(COS8192_DATA); -Oscil aCos2(COS8192_DATA); -Oscil aCos3(COS8192_DATA); -Oscil aCos4(COS8192_DATA); -Oscil aCos5(COS8192_DATA); -Oscil aCos6(COS8192_DATA); -//Oscil aCos7(COS8192_DATA); // used to work smoothly in Arduino 1.05 +Oscil aCos1(COS8192_DATA); +Oscil aCos2(COS8192_DATA); +Oscil aCos3(COS8192_DATA); +Oscil aCos4(COS8192_DATA); +Oscil aCos5(COS8192_DATA); +Oscil aCos6(COS8192_DATA); +//Oscil aCos7(COS8192_DATA); // used to work smoothly in Arduino 1.05 // duplicates but slightly off frequency for adding to originals -Oscil aCos1b(COS8192_DATA); -Oscil aCos2b(COS8192_DATA); -Oscil aCos3b(COS8192_DATA); -Oscil aCos4b(COS8192_DATA); -Oscil aCos5b(COS8192_DATA); -Oscil aCos6b(COS8192_DATA); -//Oscil aCos7b(COS8192_DATA); +Oscil aCos1b(COS8192_DATA); +Oscil aCos2b(COS8192_DATA); +Oscil aCos3b(COS8192_DATA); +Oscil aCos4b(COS8192_DATA); +Oscil aCos5b(COS8192_DATA); +Oscil aCos6b(COS8192_DATA); +//Oscil aCos7b(COS8192_DATA); // base pitch frequencies in Q16n16 fixed int format (for speed later) UFix<12,15> f1,f2,f3,f4,f5,f6;//,f7; From 574fb90a932bc3f7f3c2d3ca68c12c83fee524e1 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 10 Mar 2024 17:34:35 +0100 Subject: [PATCH 177/215] Optimization of mtof for non fractionnal FixMath midi values. --- mozzi_midi.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/mozzi_midi.h b/mozzi_midi.h index 94dd04e2b..5e9d49abc 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -13,6 +13,12 @@ class MidiToFreqPrivate { friend int mtof(uint8_t); friend int mtof(int); friend Q16n16 Q16n16_mtof(Q16n16); + template + friend UFix<16,16> mtof(UFix); + + template + friend UFix<16,16> mtof(SFix); + static CONSTTABLE_STORAGE(uint32_t) midiToFreq[128]; }; @@ -143,4 +149,22 @@ inline UFix<16,16> mtof(SFix midival) return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw())); }; +/** @ingroup midi +Converts *whole* midi note number with speed and accuracy (more accurate that mtof(uint8_t)) +*/ +template +inline UFix<16,16> mtof(UFix midival) +{ + return UFix<16,16>::fromRaw((FLASH_OR_RAM_READ(MidiToFreqPrivate::midiToFreq + midival.asRaw()))); +}; + +/** @ingroup midi +Converts *whole* midi note number with speed and accuracy (more accurate that mtof(uint8_t)) +*/ +template +inline UFix<16,16> mtof(SFix midival) +{ + return UFix<16,16>::fromRaw((FLASH_OR_RAM_READ(MidiToFreqPrivate::midiToFreq + midival.asUFix().asRaw()))); +}; + #endif /* MOZZI_MIDI_H_ */ From c3f2e54020c22cceaba3536eb1d5a9fdabcba4f0 Mon Sep 17 00:00:00 2001 From: "mr.sensorium" Date: Tue, 12 Mar 2024 23:13:29 +1100 Subject: [PATCH 178/215] add note about python 2 --- extras/python/audio2huff.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/extras/python/audio2huff.py b/extras/python/audio2huff.py index 3eb55cd49..d6723b65d 100644 --- a/extras/python/audio2huff.py +++ b/extras/python/audio2huff.py @@ -17,7 +17,10 @@ # purehuff: https://grrrr.org/data/dev/purehuff/ # pylab / matplotlib (only for plotting): http://matplotlib.sourceforge.net/ # -# For help on options invoke with: +# NOTE: the scikits.audiolab dependency requires Python 2! +# see https://github.com/Roger-random/mozzi_wilhelm/issues/1#issuecomment-770141226 +# +#For help on options invoke with: # audio2huff --help import sys,os.path From 7cffcba9355f464df6e173ff089776499d375b2c Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Mon, 25 Mar 2024 17:59:29 +0100 Subject: [PATCH 179/215] Switch to LPGL (mockup commit, which would have to be incorpated in all source files) --- ADSR.h | 6 +- LICENCE.LPGL | 502 ++++++++++++++++++ LICENSE.TXT | 438 +-------------- .../01.Basics/Control_Gain/Control_Gain.ino | 10 +- 4 files changed, 515 insertions(+), 441 deletions(-) create mode 100644 LICENCE.LPGL diff --git a/ADSR.h b/ADSR.h index 2e38a3548..5f2388cf0 100644 --- a/ADSR.h +++ b/ADSR.h @@ -1,11 +1,11 @@ /* * ADSR.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/LICENCE.LPGL b/LICENCE.LPGL new file mode 100644 index 000000000..4362b4915 --- /dev/null +++ b/LICENCE.LPGL @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/LICENSE.TXT b/LICENSE.TXT index 8f65f5df4..aaad592aa 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,437 +1,7 @@ -Attribution-NonCommercial-ShareAlike 4.0 International +Mozzi - Sound Synthesis Library for Arduino -======================================================================= +Copyright 2012-2024 Tim Barrass and the Mozzi Team -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. +Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. A full copy of this licence is included in these sources as LICENCE.LPGL. -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International -Public License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution-NonCommercial-ShareAlike 4.0 International Public License -("Public License"). To the extent this Public License may be -interpreted as a contract, You are granted the Licensed Rights in -consideration of Your acceptance of these terms and conditions, and the -Licensor grants You such rights in consideration of benefits the -Licensor receives from making the Licensed Material available under -these terms and conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. BY-NC-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - e. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - f. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution, NonCommercial, and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - i. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - k. NonCommercial means not primarily intended for or directed towards - commercial advantage or monetary compensation. For purposes of - this Public License, the exchange of the Licensed Material for - other material subject to Copyright and Similar Rights by digital - file-sharing or similar means is NonCommercial provided there is - no payment of monetary compensation in connection with the - exchange. - - l. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - m. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - n. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part, for NonCommercial purposes only; and - - b. produce, reproduce, and Share Adapted Material for - NonCommercial purposes only. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties, including when - the Licensed Material is used other than for NonCommercial - purposes. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-NC-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database for NonCommercial purposes - only; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, - including for purposes of Section 3(b); and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. +Note that some of the provided code examples show the use of separate third-party libraries, which may come with different licences. diff --git a/examples/01.Basics/Control_Gain/Control_Gain.ino b/examples/01.Basics/Control_Gain/Control_Gain.ino index 7cf5d5236..fadc6aa02 100644 --- a/examples/01.Basics/Control_Gain/Control_Gain.ino +++ b/examples/01.Basics/Control_Gain/Control_Gain.ino @@ -8,13 +8,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: + Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include From f817af65f4830b234c8d5e83f7c0ca9ae3d39001 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 28 Mar 2024 12:22:40 +0100 Subject: [PATCH 180/215] Mass-adjust licence header in examples --- examples/01.Basics/Sinewave/Sinewave.ino | 8 +++-- .../01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino | 8 +++-- .../Skeleton_Multi/Skeleton_Multi.ino | 21 ++++++++--- .../Table_Resolution/Table_Resolution.ino | 23 +++++++----- examples/01.Basics/Vibrato/Vibrato.ino | 12 ++++--- .../Vibrato_Midi_Note/Vibrato_Midi_Note.ino | 22 ++++++------ .../Control_Echo_Theremin.ino | 36 ++++++++++--------- .../Control_Oscil_Wash/Control_Oscil_Wash.ino | 12 ++++--- .../Control_Tremelo/Control_Tremelo.ino | 12 ++++--- examples/02.Control/EventDelay/EventDelay.ino | 12 ++++--- examples/02.Control/Line_Gliss/Line_Gliss.ino | 12 ++++--- .../Line_Gliss_Double_32k_HIFI.ino | 12 ++++--- .../Metronome_SampleHuffman.ino | 24 +++++++------ examples/02.Control/Stop_Start/Stop_Start.ino | 12 ++++--- .../Knob_LDR_x2_WavePacket.ino | 12 ++++--- .../Knob_LightLevel_FMsynth.ino | 12 ++++--- .../Knob_LightLevel_x2_FMsynth.ino | 12 ++++--- .../Light_Temperature_Detuned.ino | 12 ++++--- .../Light_Temperature_Multi_Oscil.ino | 12 ++++--- .../Piezo_Frequency/Piezo_Frequency.ino | 12 ++++--- .../Piezo_SampleScrubber.ino | 12 ++++--- .../Piezo_SampleTrigger.ino | 13 +++---- .../Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino | 12 ++++--- examples/03.Sensors/RCpoll/RCpoll.ino | 13 ++++--- .../Sinewave_Pinchange_Interrupt.ino | 12 ++++--- .../03.Sensors/Volume_Knob/Volume_Knob.ino | 14 ++++---- .../Volume_Knob_LightLevel_Frequency.ino | 12 ++++--- .../Audio_Input/Audio_Input.ino | 11 ++++-- .../Audio_Input_with_Knob_Filter.ino | 11 +++--- .../Audio_and_Control_Input.ino | 13 ++++--- .../05.Control_Filters/DCfilter/DCfilter.ino | 11 +++--- .../Line_vs_Smooth/Line_vs_Smooth.ino | 12 ++++--- .../MIDI_portamento/MIDI_portamento.ino | 12 ++++--- .../RollingAverage/RollingAverage.ino | 12 ++++--- examples/05.Control_Filters/Smooth/Smooth.ino | 12 ++++--- .../Smooth_Frequency/Smooth_Frequency.ino | 12 ++++--- .../Thermistor_OverSample.ino | 12 ++++--- examples/06.Synthesis/AMsynth/AMsynth.ino | 12 ++++--- .../AMsynth_HIFI/AMsynth_HIFI.ino | 12 ++++--- .../Brown_Noise_Realtime.ino | 12 ++++--- .../Detuned_Beats_Wash/Detuned_Beats_Wash.ino | 12 ++++--- .../Difference_Tone/Difference_Tone.ino | 12 ++++--- examples/06.Synthesis/FMsynth/FMsynth.ino | 12 ++++--- .../FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino | 12 ++++--- .../NonAlias_MetaOscil/NonAlias_MetaOscil.ino | 12 ++++--- .../06.Synthesis/PDresonant/PDresonant.ino | 12 ++++--- .../06.Synthesis/PWM_Phasing/PWM_Phasing.ino | 12 ++++--- .../06.Synthesis/WaveFolder/WaveFolder.ino | 12 ++++--- .../WavePacket_Double/WavePacket_Double.ino | 12 ++++--- .../WavePacket_Sample/WavePacket_Sample.ino | 12 ++++--- .../WavePacket_Single/WavePacket_Single.ino | 12 ++++--- .../06.Synthesis/Waveshaper/Waveshaper.ino | 12 ++++--- .../ADSR_Audio_Rate_Envelope.ino | 12 ++++--- .../ADSR_Audio_Rate_Envelope_Long.ino | 12 ++++--- .../ADSR_Audio_Rate_Envelope_x2.ino | 12 ++++--- .../ADSR_Control_Rate_Envelope.ino | 10 +++++- .../Ead_Envelope/Ead_Envelope.ino | 23 +++++++----- .../Phasemod_Envelope/Phasemod_Envelope.ino | 12 ++++--- examples/08.Samples/Sample/Sample.ino | 12 ++++--- .../SampleHuffman_Umpah.ino | 11 ++++-- .../Sample_Loop_Points/Sample_Loop_Points.ino | 13 ++++--- .../08.Samples/Sample_Scrub/Sample_Scrub.ino | 10 ++++-- examples/08.Samples/Samples/Samples.ino | 12 ++++--- .../Samples_Tables_Arrays.ino | 12 ++++--- .../Wavetable_Swap/Wavetable_Swap.ino | 10 +++++- examples/09.Delays/AudioDelay/AudioDelay.ino | 12 ++++--- .../AudioDelayFeedback/AudioDelayFeedback.ino | 12 ++++--- .../AudioDelayFeedbackAllpass.ino | 12 ++++--- .../AudioDelayFeedbackX2.ino | 12 ++++--- .../AudioDelayFeedback_HIFI.ino | 12 ++++--- .../ReverbTank_HIFI/ReverbTank_HIFI.ino | 12 ++++--- .../ReverbTank_STANDARD.ino | 12 ++++--- .../LowPassFilterX2/LowPassFilterX2.ino | 12 ++++--- .../MultiResonantFilter.ino | 13 +++---- .../ResonantFilter/ResonantFilter.ino | 12 ++++--- .../ResonantFilter16/ResonantFilter16.ino | 12 ++++--- .../StateVariableFilter.ino | 12 ++++--- .../StateVariableFilter_HIFI.ino | 12 ++++--- .../Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino | 12 ++++--- .../Mozzi_Processing_Serial.ino | 11 +++++- .../Sinewave_PWM_leds_HIFI.ino | 12 ++++--- .../Teensy_USB_MIDI_Input.ino | 12 ++++--- .../TwoWire_Read_ADXL345.ino | 14 ++++---- examples/12.Misc/IntMap_test/IntMap_test.ino | 17 +++++---- .../12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino | 11 ++++-- .../Risset_Beat_HIFI/Risset_Beat_HIFI.ino | 12 ++++--- .../Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino | 12 ++++--- examples/12.Misc/Stereo/Stereo.ino | 32 +++++++++-------- examples/12.Misc/Stereo_Pan/Stereo_Pan.ino | 13 +++---- .../ESP32_Bluetooth/ESP32_Bluetooth.ino | 13 +++---- .../FMsynth_MCP4921_mono_12bits.ino | 11 ++++-- .../MCP4922_mono_24bits.ino | 13 +++---- .../PT8211_stereo_16bits.ino | 13 +++---- .../PT8211_stereo_16bits_STM32_SPI2.ino | 13 +++---- .../Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino | 13 +++---- .../Sinewave_R2R_DAC_74HC595.ino | 13 +++---- .../Stereo_Pan_MCP4922_stereo_12bits.ino | 13 +++---- 97 files changed, 751 insertions(+), 511 deletions(-) diff --git a/examples/01.Basics/Sinewave/Sinewave.ino b/examples/01.Basics/Sinewave/Sinewave.ino index 1f9ada35b..a0dedeb42 100644 --- a/examples/01.Basics/Sinewave/Sinewave.ino +++ b/examples/01.Basics/Sinewave/Sinewave.ino @@ -8,12 +8,14 @@ check the README or http://sensorium.github.io/Mozzi/ Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: + Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable; 64 Hz is actually the default, but shown here, for clarity diff --git a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino index 945fddf3c..9573334c0 100644 --- a/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino +++ b/examples/01.Basics/Sinewave_HIFI/Sinewave_HIFI.ino @@ -27,12 +27,14 @@ work directly with headphones. Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: + Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino index bc32f74f5..9d7264b1b 100644 --- a/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino @@ -1,8 +1,19 @@ -/** This example shows how to set up a sketch where Mozzi-related functions are called - * from more than one .cpp source file (which will be compiled, separately). - * - * Unless you have good reason to do this, it is recommended to base your sketch on the - * single-file "Skeleton" example, instead. */ +/* This example shows how to set up a sketch where Mozzi-related functions are called + from more than one .cpp source file (which will be compiled, separately). + + Unless you have good reason to do this, it is recommended to base your sketch on the + single-file "Skeleton" example, instead. + + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. +*/ #include // at the top of your sketch diff --git a/examples/01.Basics/Table_Resolution/Table_Resolution.ino b/examples/01.Basics/Table_Resolution/Table_Resolution.ino index 4c6e0804e..8bca80d38 100644 --- a/examples/01.Basics/Table_Resolution/Table_Resolution.ino +++ b/examples/01.Basics/Table_Resolution/Table_Resolution.ino @@ -1,17 +1,22 @@ /* Example playing sine tables of different sizes - with Mozzi sonification library. + with Mozzi sonification library. - Demonstrates the audible quality of different length tables - played with Oscil and scheduling with EventDelay. + Demonstrates the audible quality of different length tables + played with Oscil and scheduling with EventDelay. - Circuit: Audio output on digital pin 9 on a Uno or similar, or - DAC/A14 on Teensy 3.1, or - check the README or http://sensorium.github.io/Mozzi/ + Circuit: Audio output on digital pin 9 on a Uno or similar, or + DAC/A14 on Teensy 3.1, or + check the README or http://sensorium.github.io/Mozzi/ - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Tim Barrass 2012, CC by-nc-sa. + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 diff --git a/examples/01.Basics/Vibrato/Vibrato.ino b/examples/01.Basics/Vibrato/Vibrato.ino index 8849db1fa..e3402c0fd 100644 --- a/examples/01.Basics/Vibrato/Vibrato.ino +++ b/examples/01.Basics/Vibrato/Vibrato.ino @@ -7,13 +7,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable diff --git a/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino b/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino index 17a20f183..ae711d161 100644 --- a/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino +++ b/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino @@ -1,17 +1,19 @@ -/* Example playing a sinewave with vibrato, - using Mozzi sonification library. +/* Example playing a sinewave with vibrato, + using Mozzi sonification library. - Demonstrates how to use fixed point arithmetics and midi notes to make an easy-to-adjust vibrato effect. - This is probably less efficient than the Vibrato example, but is also easier to understand the amount - of modulation + Demonstrates how to use fixed point arithmetics and midi notes to make an easy-to-adjust vibrato effect. + This is probably less efficient than the Vibrato example, but is also easier to understand the amount + of modulation - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Thomas Combriat and the Mozzi team 2024, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino index 47d1626e6..451b0b82a 100644 --- a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino +++ b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino @@ -1,28 +1,30 @@ /* Example of a simple light-sensing theremin-like - instrument with long echoes, - using Mozzi sonification library. + instrument with long echoes, + using Mozzi sonification library. - Demonstrates ControlDelay() for echoing control values, - and smoothing an analog input from a sensor - signal with RollingAverage(). + Demonstrates ControlDelay() for echoing control values, + and smoothing an analog input from a sensor + signal with RollingAverage(). - The circuit: + The circuit: - Audio output on digital pin 9 on a Uno or similar, or - DAC/A14 on Teensy 3.1, or - check the README or http://sensorium.github.io/Mozzi/ + Audio output on digital pin 9 on a Uno or similar, or + DAC/A14 on Teensy 3.1, or + check the README or http://sensorium.github.io/Mozzi/ - Light dependent resistor (LDR) and 5.1k resistor on analog pin 1: - LDR from analog pin to +5V (3.3V on Teensy 3.1) - 5.1k resistor from analog pin to ground + Light dependent resistor (LDR) and 5.1k resistor on analog pin 1: + LDR from analog pin to +5V (3.3V on Teensy 3.1) + 5.1k resistor from analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 diff --git a/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino b/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino index a5e8c5f0e..73ffa3f26 100644 --- a/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino +++ b/examples/02.Control/Control_Oscil_Wash/Control_Oscil_Wash.ino @@ -12,13 +12,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 128 diff --git a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino index aa2576107..a93267a53 100644 --- a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino +++ b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino @@ -12,13 +12,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable diff --git a/examples/02.Control/EventDelay/EventDelay.ino b/examples/02.Control/EventDelay/EventDelay.ino index f3c3dc74a..9db063bba 100644 --- a/examples/02.Control/EventDelay/EventDelay.ino +++ b/examples/02.Control/EventDelay/EventDelay.ino @@ -11,13 +11,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 diff --git a/examples/02.Control/Line_Gliss/Line_Gliss.ino b/examples/02.Control/Line_Gliss/Line_Gliss.ino index 6914a5d85..3295a4748 100644 --- a/examples/02.Control/Line_Gliss/Line_Gliss.ino +++ b/examples/02.Control/Line_Gliss/Line_Gliss.ino @@ -16,13 +16,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable diff --git a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino index 198f3276e..d5af0d227 100644 --- a/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino +++ b/examples/02.Control/Line_Gliss_Double_32k_HIFI/Line_Gliss_Double_32k_HIFI.ino @@ -41,13 +41,15 @@ Alternatively using 39 ohm, 4.99k and 470nF components will work directly with headphones. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino b/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino index a3664d628..a49bbafb3 100644 --- a/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino +++ b/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino @@ -1,19 +1,21 @@ -/* Example using Metronome to playing samples encoded with Huffman compression. +/* Example using Metronome to playing samples encoded with Huffman compression. - Demonstrates Metronome start, stop and ready, and the the SampleHuffman class. + Demonstrates Metronome start, stop and ready, and the the SampleHuffman class. - Circuit: - Audio output on digital pin 9 on a Uno or similar, or - DAC/A14 on Teensy 3.1, or - check the README or http://sensorium.github.io/Mozzi/ + Circuit: + Audio output on digital pin 9 on a Uno or similar, or + DAC/A14 on Teensy 3.1, or + check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/02.Control/Stop_Start/Stop_Start.ino b/examples/02.Control/Stop_Start/Stop_Start.ino index 6fe0b2af6..651656111 100644 --- a/examples/02.Control/Stop_Start/Stop_Start.ino +++ b/examples/02.Control/Stop_Start/Stop_Start.ino @@ -12,13 +12,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino b/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino index 4be6ea6b8..dfabe015a 100644 --- a/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino +++ b/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino @@ -28,13 +28,15 @@ LDR from analog pin to +5V (3.3V on Teensy 3.1) 5.1k resistor from analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino index 0ac2b9ab0..67d2fdcd8 100644 --- a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino @@ -24,13 +24,15 @@ LDR from analog pin to +5V (3.3V on Teensy 3.1) 5.1k resistor from analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino index 6aba9b6cf..7c781f7ec 100644 --- a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino @@ -27,13 +27,15 @@ LDR from analog pin to +5V (3.3V on Teensy 3.1) 5.1k resistor from analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino index 5d051071b..4b46b7661 100644 --- a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino +++ b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino @@ -21,13 +21,15 @@ LDR from analog pin to +5V (3.3V on Teensy 3.1) 5.1k resistor from analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino index 48b84aafb..c7691a9da 100644 --- a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino +++ b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino @@ -20,13 +20,15 @@ LDR from analog pin to +5V (3.3V on Teensy 3.1) 5.1k resistor from analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 256 diff --git a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino index 8a0aed82d..5d5c6421b 100644 --- a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino +++ b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino @@ -17,13 +17,15 @@ - connection of the piezo attached to ground 1-megohm resistor between the analog pin and ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // increase the rate of updateControl from the default of 64, to catch the piezo's rapid transients diff --git a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino index bcbfddc4c..1117a9cc8 100644 --- a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino +++ b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino @@ -19,13 +19,15 @@ - connection of the piezo attached to ground 1-megOhm resistor attached from the analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino index 2adffe0ef..9f7091608 100644 --- a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino +++ b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino @@ -22,14 +22,15 @@ - connection of the piezo attached to ground 1-megohm resistor between the analog pin and ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013. - CC by-nc-sa + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino index 4dded0b8f..7db8bf4e8 100644 --- a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino +++ b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino @@ -23,13 +23,15 @@ button between the digital pin and +5V 10K resistor from the digital pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/RCpoll/RCpoll.ino b/examples/03.Sensors/RCpoll/RCpoll.ino index 9ed0741b6..e5578dd96 100644 --- a/examples/03.Sensors/RCpoll/RCpoll.ino +++ b/examples/03.Sensors/RCpoll/RCpoll.ino @@ -30,13 +30,16 @@ sPin ---\/\/\/-----. ___ _ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - */ + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. +*/ #define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable #include diff --git a/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino b/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino index fb75a7f74..3deb02371 100644 --- a/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino +++ b/examples/03.Sensors/Sinewave_Pinchange_Interrupt/Sinewave_Pinchange_Interrupt.ino @@ -18,13 +18,15 @@ 6.8nf capacitor from the digital pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino index fd21e715f..924230d21 100644 --- a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino +++ b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino @@ -22,13 +22,15 @@ / GND ---| - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users - - Tim Barrass 2013, CC by-nc-sa. + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino index 98a9d7bd2..c9b42dc44 100644 --- a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino +++ b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino @@ -27,13 +27,15 @@ LDR from analog pin to +5V (3.3V on Teensy 3.1) 5.1k resistor from analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino index a0dba9cce..1327aa2dc 100644 --- a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino +++ b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino @@ -11,10 +11,15 @@ Audio output on DAC/A14 on Teensy 3.0, 3.1, or digital pin 9 on a Uno or similar, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Tim Barrass 2013, CC by-nc-sa. + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino index 8c87b88ef..720b5b33d 100644 --- a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino +++ b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino @@ -17,12 +17,15 @@ Center pin of the potentiometer goes to the analog pin. Side pins of the potentiometer go to +5V and ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino index a7bf65823..421988e90 100644 --- a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino +++ b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino @@ -18,14 +18,17 @@ The serial printing might cause glitches, so try commenting them out to test if this is a problem. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ + #include #define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD #define MOZZI_AUDIO_INPUT_PIN 0 diff --git a/examples/05.Control_Filters/DCfilter/DCfilter.ino b/examples/05.Control_Filters/DCfilter/DCfilter.ino index 7569cfd6b..1d8f5f2e7 100644 --- a/examples/05.Control_Filters/DCfilter/DCfilter.ino +++ b/examples/05.Control_Filters/DCfilter/DCfilter.ino @@ -7,14 +7,15 @@ If the input changes, the filter output swings to track the change and eventually settles back to 0. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino index 4d88d3c3e..dc11b49d6 100644 --- a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino +++ b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino @@ -16,13 +16,15 @@ connected to analog pins 0, 1 and 2, and outside leads to ground and +5V. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable diff --git a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino index 2d0d5ffeb..d21df6ecf 100644 --- a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino +++ b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino @@ -12,13 +12,15 @@ (midi has to be disconnected from rx for sketch to upload) Audio output on digital pin 9 on a Uno or similar. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino index a9d58d7f0..ccb5e6968 100644 --- a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino +++ b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino @@ -10,13 +10,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/05.Control_Filters/Smooth/Smooth.ino b/examples/05.Control_Filters/Smooth/Smooth.ino index 118f11960..0c03eae21 100644 --- a/examples/05.Control_Filters/Smooth/Smooth.ino +++ b/examples/05.Control_Filters/Smooth/Smooth.ino @@ -9,13 +9,15 @@ DAC/A14 on Teensy 3.1, or your board check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 128 diff --git a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino index 31b1a5293..9de8eb81e 100644 --- a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino +++ b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino @@ -7,13 +7,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // this is a high value to avoid zipper noise diff --git a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino index 8ca4aa52f..1ec5adf13 100644 --- a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino +++ b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino @@ -20,13 +20,15 @@ Thermistor from analog pin to +5V (3.3V on Teensy 3.1) 5.1k resistor from analog pin to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/AMsynth/AMsynth.ino b/examples/06.Synthesis/AMsynth/AMsynth.ino index b98892600..0c1a5ed17 100644 --- a/examples/06.Synthesis/AMsynth/AMsynth.ino +++ b/examples/06.Synthesis/AMsynth/AMsynth.ino @@ -11,13 +11,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable diff --git a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino index 0ccc9139b..953c05294 100644 --- a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino +++ b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino @@ -30,13 +30,15 @@ Alternatively using 39 ohm, 4.99k and 470nF components will work directly with headphones. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino b/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino index d8d61e210..642b95784 100644 --- a/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino +++ b/examples/06.Synthesis/Brown_Noise_Realtime/Brown_Noise_Realtime.ino @@ -9,13 +9,15 @@ Circuit: Audio output on digital pin 9 on a Uno or similar. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 20118, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino index e2691238a..b54832c4b 100644 --- a/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino +++ b/examples/06.Synthesis/Detuned_Beats_Wash/Detuned_Beats_Wash.ino @@ -20,13 +20,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino index c9d53c769..9a7e22449 100644 --- a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino +++ b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino @@ -8,13 +8,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/FMsynth/FMsynth.ino b/examples/06.Synthesis/FMsynth/FMsynth.ino index c3425186b..bde18a0a2 100644 --- a/examples/06.Synthesis/FMsynth/FMsynth.ino +++ b/examples/06.Synthesis/FMsynth/FMsynth.ino @@ -13,13 +13,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable diff --git a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino index ee7a9bc50..ef8f34034 100644 --- a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino +++ b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino @@ -33,13 +33,15 @@ Alternatively using 39 ohm, 4.99k and 470nF components will work directly with headphones. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino index f352e1869..87244ffb1 100644 --- a/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino +++ b/examples/06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino @@ -26,13 +26,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, Combriat T. 2021, CC by-nc-sa. + Copyright 2021-2024 Tom Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // use #define for MOZZI_CONTROL_RATE, not a constant diff --git a/examples/06.Synthesis/PDresonant/PDresonant.ino b/examples/06.Synthesis/PDresonant/PDresonant.ino index 3b78b47d8..2983e36ef 100644 --- a/examples/06.Synthesis/PDresonant/PDresonant.ino +++ b/examples/06.Synthesis/PDresonant/PDresonant.ino @@ -17,13 +17,15 @@ (midi has to be disconnected from rx for sketch to upload) Audio output on digital pin 9 on a Uno or similar. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013-14, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ //#include may be needed on some systems/versions diff --git a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino index ebfeac61a..2501deb3f 100644 --- a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino +++ b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino @@ -12,13 +12,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/WaveFolder/WaveFolder.ino b/examples/06.Synthesis/WaveFolder/WaveFolder.ino index 4846a0987..773468d66 100644 --- a/examples/06.Synthesis/WaveFolder/WaveFolder.ino +++ b/examples/06.Synthesis/WaveFolder/WaveFolder.ino @@ -7,13 +7,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Combriat Thomas 2022, CC by-nc-sa. + Copyright 2022-2024 Tom Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ diff --git a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino index 4d1638599..a8ff943f4 100644 --- a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino +++ b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino @@ -20,13 +20,15 @@ Center pin of the potentiometer goes to the analog pin. Side pins of the potentiometer go to +5V and ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino index d85114b07..7f8f84256 100644 --- a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino +++ b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino @@ -23,13 +23,15 @@ Center pin of the potentiometer goes to the analog pin. Side pins of the potentiometer go to +5V and ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino index 6e58e4d7b..1c06c7b5f 100644 --- a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino +++ b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino @@ -20,13 +20,15 @@ Center pin of the potentiometer goes to the analog pin. Side pins of the potentiometer go to +5V and ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/06.Synthesis/Waveshaper/Waveshaper.ino b/examples/06.Synthesis/Waveshaper/Waveshaper.ino index dfff9408b..5cf7df376 100644 --- a/examples/06.Synthesis/Waveshaper/Waveshaper.ino +++ b/examples/06.Synthesis/Waveshaper/Waveshaper.ino @@ -8,13 +8,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino index aa6399814..143455ef8 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope/ADSR_Audio_Rate_Envelope.ino @@ -10,13 +10,15 @@ Demonstrates a simple ADSR object being controlled with noteOn() and noteOff() instructions. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino index 25a99fc98..5037e3ed8 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_Long/ADSR_Audio_Rate_Envelope_Long.ino @@ -13,13 +13,15 @@ Demonstrates a simple ADSR object being controlled with noteOn() and noteOff() instructions. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino index c2ddb70dc..bb9b83842 100644 --- a/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino +++ b/examples/07.Envelopes/ADSR_Audio_Rate_Envelope_x2/ADSR_Audio_Rate_Envelope_x2.ino @@ -8,13 +8,15 @@ which is more efficient, but MOZZI_AUDIO_RATE updates shown in this example enable faster envelope transitions. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino index 23d4d239f..5cf0db0ae 100644 --- a/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino +++ b/examples/07.Envelopes/ADSR_Control_Rate_Envelope/ADSR_Control_Rate_Envelope.ino @@ -8,7 +8,15 @@ Demonstrates a simple ADSR object being controlled with noteOn() and noteOff() instructions. - Tim Barrass 2013-14, CC by-nc-sa. + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 128 // faster than usual to help smooth MOZZI_CONTROL_RATE adsr interpolation (next()) diff --git a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino index 2fa6c7282..7578be9d5 100644 --- a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino +++ b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino @@ -1,16 +1,21 @@ -/* Example playing an enveloped noise source - using Mozzi sonification library. +/* Example playing an enveloped noise source + using Mozzi sonification library. - Demonstrates Ead (exponential attack decay). + Demonstrates Ead (exponential attack decay). - Circuit: Audio output on digital pin 9 on a Uno or similar, or - DAC/A14 on Teensy 3.1, or - check the README or http://sensorium.github.io/Mozzi/ + Circuit: Audio output on digital pin 9 on a Uno or similar, or + DAC/A14 on Teensy 3.1, or + check the README or http://sensorium.github.io/Mozzi/ - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Tim Barrass 2012, CC by-nc-sa + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable diff --git a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino index 91112482a..f7626cff4 100644 --- a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino +++ b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino @@ -5,13 +5,15 @@ Demonstrates phase modulation and modifying the volume of a sound with an envelope setd in a table. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth diff --git a/examples/08.Samples/Sample/Sample.ino b/examples/08.Samples/Sample/Sample.ino index f173846d8..15c69cd64 100644 --- a/examples/08.Samples/Sample/Sample.ino +++ b/examples/08.Samples/Sample/Sample.ino @@ -8,13 +8,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino b/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino index eb2606e43..b76c57eb7 100644 --- a/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino +++ b/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino @@ -35,10 +35,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Tim Barrass 2013, CC by-nc-sa. + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino index f765bd863..b14ba6c36 100644 --- a/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino +++ b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino @@ -11,13 +11,16 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. - Tim Barrass 2012, CC by-nc-sa. */ #define MOZZI_CONTROL_RATE 128 diff --git a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino index 5f04f8060..84826c80c 100644 --- a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino +++ b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino @@ -8,11 +8,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi help/discussion/announcements: + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13. - CC by-nc-sa + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/08.Samples/Samples/Samples.ino b/examples/08.Samples/Samples/Samples.ino index 832de43ea..ae34db505 100644 --- a/examples/08.Samples/Samples/Samples.ino +++ b/examples/08.Samples/Samples/Samples.ino @@ -9,13 +9,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino index e5083a68c..1f546dbd7 100644 --- a/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino +++ b/examples/08.Samples/Samples_Tables_Arrays/Samples_Tables_Arrays.ino @@ -13,13 +13,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino b/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino index 4f64f6283..4400cf00e 100644 --- a/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino +++ b/examples/08.Samples/Wavetable_Swap/Wavetable_Swap.ino @@ -4,7 +4,15 @@ Demonstrates declaring an Oscil without a table, and Oscil::setTable() method. - Tim Barrass 2012, CC by-nc-sa. + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/09.Delays/AudioDelay/AudioDelay.ino b/examples/09.Delays/AudioDelay/AudioDelay.ino index 1c4b3ec5b..1f3255ee4 100644 --- a/examples/09.Delays/AudioDelay/AudioDelay.ino +++ b/examples/09.Delays/AudioDelay/AudioDelay.ino @@ -7,13 +7,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable diff --git a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino index 1d4342beb..ced34152d 100644 --- a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino +++ b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino @@ -7,13 +7,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable diff --git a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino index 739c3ff24..715e62c7b 100644 --- a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino +++ b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino @@ -9,13 +9,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable diff --git a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino index 902a2e861..a452807bd 100644 --- a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino +++ b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino @@ -8,13 +8,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable diff --git a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino index 04244e36b..1d047832b 100644 --- a/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino +++ b/examples/09.Delays/AudioDelayFeedback_HIFI/AudioDelayFeedback_HIFI.ino @@ -30,13 +30,15 @@ Alternatively using 39 ohm, 4.99k and 470nF components will work directly with headphones. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino index b623f6aed..4558c3319 100644 --- a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino +++ b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino @@ -13,13 +13,15 @@ Circuit: Audio output on digital pin 9 for STANDARD output on a Uno or similar, or see the readme.md file for others. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth diff --git a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino index 8b30f6f10..3d7055b6b 100644 --- a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino +++ b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino @@ -13,13 +13,15 @@ Circuit: Audio output on digital pin 9 for STANDARD output on a Uno or similar, or see the readme.md file for others. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth diff --git a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino index 4cf2cfa6d..04ad5ea99 100644 --- a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino +++ b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino @@ -7,13 +7,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino index 93cf0f698..5f1726eef 100644 --- a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino +++ b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino @@ -13,14 +13,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - Thomas Combriat 2023, CC by-nc-sa. + Copyright 2023-2024 Tom Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino index c0e6299f8..c0ec4241c 100644 --- a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino +++ b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino @@ -11,13 +11,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino index 63baff038..de6bd858e 100644 --- a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino +++ b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino @@ -13,13 +13,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino index d34746d1d..ca65731c3 100644 --- a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino +++ b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino @@ -7,13 +7,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino index a498c45ad..c07f10dde 100644 --- a/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino +++ b/examples/10.Audio_Filters/StateVariableFilter_HIFI/StateVariableFilter_HIFI.ino @@ -28,13 +28,15 @@ Alternatively using 39 ohm, 4.99k and 470nF components will work directly with headphones. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino index 92839b042..114c1c4ae 100644 --- a/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino +++ b/examples/11.Communication/Mozzi_MIDI_Input/Mozzi_MIDI_Input.ino @@ -10,13 +10,15 @@ Midi has to be disconnected from rx for sketch to upload. Audio output on digital pin 9 on a Uno or similar. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013-14, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino b/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino index 30de4e825..179fa2da3 100644 --- a/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino +++ b/examples/11.Communication/Mozzi_Processing_Serial/Mozzi_Processing_Serial.ino @@ -16,7 +16,16 @@ This example code is in the public domain. http://www.arduino.cc/en/Tutorial/Dimmer - + + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino index 225fe286c..636f91add 100644 --- a/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino +++ b/examples/11.Communication/Sinewave_PWM_leds_HIFI/Sinewave_PWM_leds_HIFI.ino @@ -42,13 +42,15 @@ Green led from pin 4 through a 1.5k resistor to ground Blue led from pin 5 through a 1.5k resistor to ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012-13, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM diff --git a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino index 2a5069416..eb9572304 100644 --- a/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino +++ b/examples/11.Communication/Teensy_USB_MIDI_Input/Teensy_USB_MIDI_Input.ino @@ -12,13 +12,15 @@ Circuit: On the Teensy2++, audio output is on pin B5. Midi input on usb. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2013, CC by-nc-sa. + Copyright 2013-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino index 48b293610..4d79c4826 100644 --- a/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino +++ b/examples/11.Communication/TwoWire_Read_ADXL345/TwoWire_Read_ADXL345.ino @@ -9,15 +9,15 @@ Circuit: Audio output on digital pin 9. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Marije Baalman 2012. - Small modifications by TIm Barrass to retain Mozzi compatibility. - This example code is in the public domain. + Copyright 2012-2024 Marije Baalman and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable diff --git a/examples/12.Misc/IntMap_test/IntMap_test.ino b/examples/12.Misc/IntMap_test/IntMap_test.ino index c51ebd09d..0e4e7e43d 100644 --- a/examples/12.Misc/IntMap_test/IntMap_test.ino +++ b/examples/12.Misc/IntMap_test/IntMap_test.ino @@ -1,14 +1,19 @@ /* Maps a range of input numbers to an output range, comparing - the results of Mozzi's IntMap object with Arduino map(). + the results of Mozzi's IntMap object with Arduino map(). - Demonstrates IntMap, a fast integer replacement for map(). + Demonstrates IntMap, a fast integer replacement for map(). - Circuit: not required + Circuit: not required - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Tim Barrass 2014, CC by-nc-sa. + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2014-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include diff --git a/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino b/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino index 561f50676..38b9da0b7 100644 --- a/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino +++ b/examples/12.Misc/MozziByte_HIFI/MozziByte_HIFI.ino @@ -25,10 +25,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Tim Barrass 2018, CC by-nc-sa. + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2018-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM diff --git a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino index 2079be8cc..28938b564 100644 --- a/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino +++ b/examples/12.Misc/Risset_Beat_HIFI/Risset_Beat_HIFI.ino @@ -26,13 +26,15 @@ DAC/A14 on Teensy 3.1, or check the README or http://sensorium.github.io/Mozzi/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2018, CC by-nc-sa. + Copyright 2018-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM diff --git a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino index 2500ea881..e3b3b71a2 100644 --- a/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino +++ b/examples/12.Misc/Shepard_Tone_HIFI/Shepard_Tone_HIFI.ino @@ -23,13 +23,15 @@ | ground - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2018, CC by-nc-sa. + Copyright 2018-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM diff --git a/examples/12.Misc/Stereo/Stereo.ino b/examples/12.Misc/Stereo/Stereo.ino index 14cfcd562..52d10b13d 100644 --- a/examples/12.Misc/Stereo/Stereo.ino +++ b/examples/12.Misc/Stereo/Stereo.ino @@ -1,17 +1,21 @@ -/* Example crudely panning noise to test stereo output, - * using Mozzi sonification library. - * - * Tests stereo output. - * - * NOTE: Stereo output is not supported on all platforms / configurations! - * - * Circuit: Audio outputs on digital pins 9 and 10 (on classic Arduino). - * - * Mozzi help/discussion/announcements: - * https://groups.google.com/forum/#!forum/mozzi-users - * - * Tim Barrass 2012. - * This example code is in the public domain. +/* Example crudely panning noise to test stereo output, + using Mozzi sonification library. + + Tests stereo output. + + NOTE: Stereo output is not supported on all platforms / configurations! + + Circuit: Audio outputs on digital pins 9 and 10 (on classic Arduino). + + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2012-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // Configure Mozzi for Stereo output. This must be done before #include diff --git a/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino index 42f454d1d..c320f9660 100644 --- a/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino +++ b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino @@ -7,14 +7,15 @@ Circuit: Audio outputs on digital pins 9 and 10 (on classic Arduino). - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2017. - This example code is in the public domain. + Copyright 2017-2024 Tim Barrass and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // Configure Mozzi for Stereo output. This must be done before #include diff --git a/examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino b/examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino index 7ce1b6611..cf5adab0e 100644 --- a/examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino +++ b/examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino @@ -32,14 +32,15 @@ and Phil's ESP32-A2DP library does a great job of managing all the scary details. - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - T. Friedrichsmeier 2024, CC by-nc-sa. + Copyright 2024-2024 Thomas Friedrichsmeier and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // before including Mozzi.h, configure external audio output mode: diff --git a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino index 5d16b2c52..e340beecb 100644 --- a/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino +++ b/examples/13.External_Audio_Output/FMsynth_MCP4921_mono_12bits/FMsynth_MCP4921_mono_12bits.ino @@ -23,8 +23,15 @@ Mozzi help/discussion/announcements: https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + Copyright 2020-2024 T. Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // before including Mozzi.h, configure external audio output mode: diff --git a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino index d49ed5bed..de6bf4d2e 100644 --- a/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino +++ b/examples/13.External_Audio_Output/MCP4922_mono_24bits/MCP4922_mono_24bits.ino @@ -37,14 +37,15 @@ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Copyright 2020-2024 T. Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // before including Mozzi.h, configure external audio output mode: diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino index b481cd5c7..dd8c5de22 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino @@ -16,14 +16,15 @@ GND GND L/R to audio outputs - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Copyright 2020-2024 T. Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ // before including Mozzi.h, configure external audio output mode: diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino index 2a901d90e..3b557eae0 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino @@ -15,14 +15,15 @@ GND GND L/R to audio outputs - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Copyright 2020-2024 T. Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include "MozziConfigValues.h" // for named option values #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino index b438cb57f..465e876f9 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC/Sinewave_R2R_DAC.ino @@ -29,14 +29,15 @@ For more details on the R/2R DAC see: https://hackaday.com/2015/11/05/logic-noise-digital-to-analog-with-an-r-2r-dac/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Copyright 2020-2024 T. Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include "MozziConfigValues.h" // for named option values diff --git a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino index 9fdb979ab..c35ba56bb 100644 --- a/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino +++ b/examples/13.External_Audio_Output/Sinewave_R2R_DAC_74HC595/Sinewave_R2R_DAC_74HC595.ino @@ -34,14 +34,15 @@ For more details on the R/2R DAC see: https://hackaday.com/2015/11/05/logic-noise-digital-to-analog-with-an-r-2r-dac/ - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Copyright 2020-2024 T. Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include "MozziConfigValues.h" // for named option values diff --git a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino index f6fb405b9..ca26ab4a9 100644 --- a/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino +++ b/examples/13.External_Audio_Output/Stereo_Pan_MCP4922_stereo_12bits/Stereo_Pan_MCP4922_stereo_12bits.ino @@ -16,14 +16,15 @@ LDAC to GND - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Mozzi documentation/API + https://sensorium.github.io/Mozzi/doc/html/index.html - Mozzi help/discussion/announcements: - https://groups.google.com/forum/#!forum/mozzi-users + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Copyright 2020-2024 T. Combriat and the Mozzi Team + + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ #include "MozziConfigValues.h" // for named option values From 5678b04097b7b2e765e2d8bd5b49c02d0ee147d3 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 28 Mar 2024 13:34:22 +0100 Subject: [PATCH 181/215] Mass-adjust licence/copyright header in source files --- AudioDelay.h | 6 ++--- AudioDelayFeedback.h | 6 ++--- AudioOutput.h | 11 +++++++++ AutoMap.h | 8 ++++--- AutoRange.h | 7 +++--- CapPoll.h | 11 +++++++++ CircularBuffer.h | 11 +++++++++ ControlDelay.h | 6 ++--- DCfilter.h | 6 ++--- Ead.h | 9 ++++---- EventDelay.h | 6 ++--- FixMath.h | 7 +++--- IntMap.h | 7 +++--- IntegerType.h | 11 +++++++++ Line.h | 7 +++--- LowPassFilter.h | 10 ++++---- MetaOscil.h | 6 +++++ Metronome.h | 7 +++--- Mozzi.h | 8 +++---- MozziConfigValues.h | 20 ++++++++++++---- MozziGuts.h | 6 ++--- MozziHeadersOnly.h | 7 +++--- Oscil.h | 8 ++++--- OverSample.h | 14 +++++------ PDResonant.h | 8 +++---- Phasor.h | 6 ++--- Portamento.h | 6 ++--- RCpoll.h | 11 +++++++++ README.md | 16 ++++++------- ResonantFilter.h | 7 +++--- ReverbTank.h | 12 +++++----- RollingAverage.h | 23 +++++++++---------- RollingStat.h | 15 ++++++------ Sample.h | 6 ++--- SampleHuffman.h | 7 +++--- Smooth.h | 6 ++--- Stack.h | 6 ++--- StateVariable.h | 7 +++--- WaveFolder.h | 9 ++++---- WavePacket.h | 6 ++--- WavePacketSample.h | 7 +++--- WaveShaper.h | 6 ++--- extras/NEWS.txt | 1 + hardware_defines.h | 12 ++++++++++ internal/MozziGuts.hpp | 12 +++++----- internal/MozziGuts_impl_AVR.hpp | 11 ++++----- internal/MozziGuts_impl_ESP32.hpp | 11 ++++----- internal/MozziGuts_impl_ESP8266.hpp | 11 ++++----- internal/MozziGuts_impl_MBED.hpp | 11 ++++----- internal/MozziGuts_impl_RENESAS.hpp | 11 ++++----- internal/MozziGuts_impl_RENESAS_ADC.hpp | 7 ++++++ internal/MozziGuts_impl_RENESAS_analog.hpp | 9 ++++++++ internal/MozziGuts_impl_RP2040.hpp | 11 ++++----- internal/MozziGuts_impl_SAMD.hpp | 11 ++++----- internal/MozziGuts_impl_STM32.hpp | 11 ++++----- internal/MozziGuts_impl_STM32duino.hpp | 11 ++++----- internal/MozziGuts_impl_STM32duino_analog.hpp | 13 ++++++++++- internal/MozziGuts_impl_TEENSY.hpp | 11 ++++----- internal/MozziGuts_impl_template.hpp | 11 ++++----- internal/config_checks_avr.h | 11 +++++++++ internal/config_checks_esp32.h | 11 +++++++++ internal/config_checks_esp8266.h | 11 +++++++++ internal/config_checks_generic.h | 11 +++++++++ internal/config_checks_mbed.h | 11 +++++++++ internal/config_checks_renesas.h | 11 +++++++++ internal/config_checks_rp2040.h | 11 +++++++++ internal/config_checks_samd21.h | 11 +++++++++ internal/config_checks_stm32duino.h | 11 +++++++++ internal/config_checks_stm32maple.h | 11 +++++++++ internal/config_checks_teensy.h | 11 +++++++++ internal/config_checks_template.h | 12 ++++++++++ internal/mozzi_macros.h | 11 +++++++++ internal/mozzi_rand_p.h | 11 +++++++++ internal/teensyPinMap.h | 8 +++---- meta.h | 11 +++++++++ mozzi_analog.h | 7 +++--- mozzi_fixmath.cpp | 11 +++++++++ mozzi_fixmath.h | 6 ++--- mozzi_midi.h | 11 +++++++++ mozzi_pgmspace.h | 11 +++++++++ mozzi_rand.h | 11 +++++++++ mozzi_utils.h | 10 ++++++++ primes.h | 8 +++---- twi_nonblock.cpp | 6 ++++- twi_nonblock.h | 7 +++++- 85 files changed, 568 insertions(+), 238 deletions(-) diff --git a/AudioDelay.h b/AudioDelay.h index 695c4e0b6..aad01aeae 100644 --- a/AudioDelay.h +++ b/AudioDelay.h @@ -1,11 +1,11 @@ /* * AudioDelay.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/AudioDelayFeedback.h b/AudioDelayFeedback.h index a5f3a01b0..ad1ea53d2 100644 --- a/AudioDelayFeedback.h +++ b/AudioDelayFeedback.h @@ -1,11 +1,11 @@ /* * AudioDelayFeedback.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/AudioOutput.h b/AudioOutput.h index 252a3076c..fa5b8e889 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -1,3 +1,14 @@ +/* + * AudioOutput.h + * + * This file is part of Mozzi. + * + * Copyright 2021-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + /** @defgroup audio_output Audio Output and Buffering * * @details Documentation on basic Mozzi architecture and output modes */ diff --git a/AutoMap.h b/AutoMap.h index c58e19989..7f602d4a3 100644 --- a/AutoMap.h +++ b/AutoMap.h @@ -1,11 +1,13 @@ /* * AutoMap.h - * - * Copyright 2012 Tim Barrass. +/* + * AutoMap.h * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/AutoRange.h b/AutoRange.h index 8154460cf..d84a55121 100644 --- a/AutoRange.h +++ b/AutoRange.h @@ -1,13 +1,14 @@ /* * AutoRange.h * - * Copyright 2013 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef AUTORANGE_H #define AUTORANGE_H diff --git a/CapPoll.h b/CapPoll.h index a4af24778..26c70fa44 100644 --- a/CapPoll.h +++ b/CapPoll.h @@ -1,3 +1,14 @@ +/* + * CapPoll.h + * + * This file is part of Mozzi. + * + * Copyright 2015-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + #ifndef RCPOLL_H #define RCPOLL_H diff --git a/CircularBuffer.h b/CircularBuffer.h index a71ccb4ce..e8c164a5b 100644 --- a/CircularBuffer.h +++ b/CircularBuffer.h @@ -1,3 +1,14 @@ +/* + * CircularBuffer.h + * + * This file is part of Mozzi. + * + * Copyright 2014-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + /* Modified from https://en.wikipedia.org/wiki/Circular_buffer Mirroring version diff --git a/ControlDelay.h b/ControlDelay.h index cb6472628..cf98c2fdc 100644 --- a/ControlDelay.h +++ b/ControlDelay.h @@ -1,11 +1,11 @@ /* * ControlDelay.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/DCfilter.h b/DCfilter.h index 2b2dde713..7e6e157d4 100644 --- a/DCfilter.h +++ b/DCfilter.h @@ -1,11 +1,11 @@ /* * DCfilter.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/Ead.h b/Ead.h index ec59ef1c2..f9d1a3dbe 100644 --- a/Ead.h +++ b/Ead.h @@ -2,13 +2,14 @@ * Ead.h * * Adapted from ead~.c puredata external (creb library) - * Copyright (c) 2000-2003 by Tom Schouten - * - * Copyright 2012 Tim Barrass, 2000-2003 Tom Schouten * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright (c) 2000-2003 by Tom Schouten + * Copyright 2012 Tim Barrass + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/EventDelay.h b/EventDelay.h index 4c049dd31..2966f2615 100644 --- a/EventDelay.h +++ b/EventDelay.h @@ -1,11 +1,11 @@ /* * EventDelay.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/FixMath.h b/FixMath.h index 221b69c1f..5e127e226 100644 --- a/FixMath.h +++ b/FixMath.h @@ -1,12 +1,11 @@ /* * FixMath.h * - * Copyright 2023, Thomas Combriat and the Mozzi team - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2023-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/IntMap.h b/IntMap.h index 8783b61a0..e8ca09fa5 100644 --- a/IntMap.h +++ b/IntMap.h @@ -1,14 +1,15 @@ /* * IntMap.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef INTMAP_H_ #define INTMAP_H_ diff --git a/IntegerType.h b/IntegerType.h index 47c944a0f..49be01847 100644 --- a/IntegerType.h +++ b/IntegerType.h @@ -1,3 +1,14 @@ +/* + * IntegerType.h + * + * This file is part of Mozzi. + * + * Copyright 2021-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + #ifndef INTTYPE_H_ #define INTTYPE_H_ diff --git a/Line.h b/Line.h index e330b73df..203293239 100644 --- a/Line.h +++ b/Line.h @@ -1,14 +1,15 @@ /* * Line.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef LINE_H_ #define LINE_H_ diff --git a/LowPassFilter.h b/LowPassFilter.h index e66cbe037..330f3ad4b 100644 --- a/LowPassFilter.h +++ b/LowPassFilter.h @@ -1,15 +1,15 @@ /* - * LowPassFilter.h - * - * Copyright 2012 Tim Barrass + * LowPassfilter.h * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef LOWPASS_H_ #define LOWPASS_H_ diff --git a/MetaOscil.h b/MetaOscil.h index dfd7deaf3..f855039a2 100644 --- a/MetaOscil.h +++ b/MetaOscil.h @@ -4,8 +4,14 @@ * A wrap-up to swap between different oscillators seemlessly, allowing to produce non-aliased sounds by automatically switching between oscillators. * * This file is part of Mozzi. + * + * Copyright 2021-2024 T. Combriat and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * */ + #ifndef META_OSCIL_H #define META_OSCIL_H diff --git a/Metronome.h b/Metronome.h index a7a84ebdc..a30299ff7 100644 --- a/Metronome.h +++ b/Metronome.h @@ -1,14 +1,15 @@ /* * Metronome.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef METRO_H_ #define METRO_H_ diff --git a/Mozzi.h b/Mozzi.h index 38bfcf71e..a48dec3e4 100644 --- a/Mozzi.h +++ b/Mozzi.h @@ -1,15 +1,15 @@ /* * Mozzi.h * - * Copyright 2024, Tim Barrass and the Mozzi team - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + /** @ingroup core * @file Mozzi.h * diff --git a/MozziConfigValues.h b/MozziConfigValues.h index 8470158d4..47116847c 100644 --- a/MozziConfigValues.h +++ b/MozziConfigValues.h @@ -1,8 +1,18 @@ -/** This file keeps a list of named configuration values. - -Note that these are all given as defines, instead of e.g. const ints or enum values, because they need to be usable at preprocessor level, in order to control conditional compilation. - -TODO: Fix documentation +/* + * MozziConfigValues.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + +/** @file MozziConfigValues.h + * This file keeps a list of named configuration values. + * + * Note that these are all given as defines, instead of e.g. const ints or enum values, because they need to be usable at preprocessor level, in order to control conditional compilation. */ #ifndef MOZZICONFIG_VALUES_H diff --git a/MozziGuts.h b/MozziGuts.h index 4453ab6fe..f8db388b3 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -1,11 +1,11 @@ /* * MozziGuts.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/MozziHeadersOnly.h b/MozziHeadersOnly.h index 5d28041b3..afb122d23 100644 --- a/MozziHeadersOnly.h +++ b/MozziHeadersOnly.h @@ -1,12 +1,11 @@ /* * MozziHeadersOnly.h * - * Copyright 2024, Tim Barrass and the Mozzi team - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2023-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/Oscil.h b/Oscil.h index ee3b003ad..531bf190a 100644 --- a/Oscil.h +++ b/Oscil.h @@ -3,14 +3,16 @@ * * Oscil.h owes much to AF_precision_synthesis.pde, 2009, Adrian Freed. * - * Copyright 2012 Tim Barrass, 2009 Adrian Freed. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 20009 Arian Freed + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef OSCIL_H_ #define OSCIL_H_ diff --git a/OverSample.h b/OverSample.h index 282d92cfc..7e05fabc1 100644 --- a/OverSample.h +++ b/OverSample.h @@ -1,18 +1,18 @@ -#ifndef OVERSAMPLE_H -#define OVERSAMPLE_H - /* * OverSample.h * - * Copyright 2013 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ - #include "RollingAverage.h" +#ifndef OVERSAMPLE_H +#define OVERSAMPLE_H + +#include "RollingAverage.h" /** @ingroup sensortools diff --git a/PDResonant.h b/PDResonant.h index 89e88d6d6..2fdfd7eac 100644 --- a/PDResonant.h +++ b/PDResonant.h @@ -1,16 +1,14 @@ /* * PDResonant.h * - * This implementation copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ - - #include #include #include diff --git a/Phasor.h b/Phasor.h index 32ea15e27..dcf4b0f61 100644 --- a/Phasor.h +++ b/Phasor.h @@ -1,11 +1,11 @@ /* * Phasor.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/Portamento.h b/Portamento.h index c22e5b205..e822cfbd1 100644 --- a/Portamento.h +++ b/Portamento.h @@ -1,11 +1,11 @@ /* * Portamento.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/RCpoll.h b/RCpoll.h index 3be2fd97c..8de4a5b70 100644 --- a/RCpoll.h +++ b/RCpoll.h @@ -1,3 +1,14 @@ +/* + * RCpoll.h + * + * This file is part of Mozzi. + * + * Copyright 2014-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + #ifndef RCPOLL_H #define RCPOLL_H diff --git a/README.md b/README.md index bf9d131ca..2a51a7c64 100644 --- a/README.md +++ b/README.md @@ -215,16 +215,14 @@ applicable to your hardware. *** ## Use and Remix -Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License, which is detailed in LICENSE.txt +Mozzi is licensed under a the LGPL version 2.1 or (at your option) any later version of the license. Disclaimer: This is a human-readable summary of (and not a substitute for) the license. +- You may copy, distribute and modify the Mozzi library itself provided that you state modifications and license them under LGPL-2.1. -You are free to: - - Share — copy and redistribute the material in any medium or format - - Adapt — remix, transform, and build upon the material +- You may distribute *your own* source code which merely *uses* the Mozzi-API under any licence that you wish. -The licensor cannot revoke these freedoms as long as you follow the license terms. -Under the following terms: - - Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - - NonCommercial — You may not use the material for commercial purposes. - - No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. +- Regarding distribution of *binaries* (also inside a hardware project) that include Mozzi, the Arduino FAQ sums up the situation as follows: + "Using the Arduino core and libraries for the firmware of a commercial product does not require you to release the source code for the firmware. The LGPL does, however, require you to make available object files that allow for the relinking of the firmware against updated versions of the Arduino core and libraries. Any modifications to the core and libraries must be released under the LGPL." + +- Note that using third-party libraries/code - including as shown in some of the Mozzi examples - may introduce additional restrictions. diff --git a/ResonantFilter.h b/ResonantFilter.h index 8cbe9454c..1f0fb2d00 100644 --- a/ResonantFilter.h +++ b/ResonantFilter.h @@ -1,12 +1,11 @@ /* * ResonantFilter.h * - * Copyright 2012 Tim Barrass - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/ReverbTank.h b/ReverbTank.h index e4b2d3b10..17ac9b6b0 100644 --- a/ReverbTank.h +++ b/ReverbTank.h @@ -1,17 +1,17 @@ -#ifndef REVERBTANK_H -#define REVERBTANK_H - /* * ReverbTank.h * - * Copyright 2013 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ +#ifndef REVERBTANK_H +#define REVERBTANK_H + #include "AudioDelay.h" /** A reverb which sounds like the inside of a tin can. diff --git a/RollingAverage.h b/RollingAverage.h index ec04497f1..a05c4fec0 100644 --- a/RollingAverage.h +++ b/RollingAverage.h @@ -1,24 +1,23 @@ -#ifndef ROLLINGAVERAGE_H -#define ROLLINGAVERAGE_H - /* * RollingAverage.h * - * Copyright 2013 Tim Barrass. - * - * This file is part of Mozzi. - * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. - * - */ -/* Draws on Arduino Smoothing example, Created 22 April 2007 By David A. Mellis modified 9 Apr 2012 by Tom Igoe http://www.arduino.cc/en/Tutorial/Smoothing -*/ + + * This file is part of Mozzi. + * + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + +#ifndef ROLLINGAVERAGE_H +#define ROLLINGAVERAGE_H #include "mozzi_utils.h" // for trailingZeros() diff --git a/RollingStat.h b/RollingStat.h index f4fd30dba..085c612b5 100644 --- a/RollingStat.h +++ b/RollingStat.h @@ -1,19 +1,18 @@ -#ifndef ROLLINGSTAT_H -#define ROLLINGSTAT_H - /* * RollingStat.h * - * WARNING: this code is incomplete, it doesn't work yet - * - * Copyright 2013 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + * WARNING: this code is incomplete, it doesn't work yet */ +#ifndef ROLLINGSTAT_H +#define ROLLINGSTAT_H + #include "RollingAverage.h" #include "mozzi_fixmath.h" diff --git a/Sample.h b/Sample.h index ea2206d58..30a2d60ef 100644 --- a/Sample.h +++ b/Sample.h @@ -1,11 +1,11 @@ /* * Sample.h * - * Copyright 2012 Tim Barrass - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/SampleHuffman.h b/SampleHuffman.h index 5a58a7d6a..a04e8fc04 100644 --- a/SampleHuffman.h +++ b/SampleHuffman.h @@ -1,13 +1,14 @@ /* * SampleHuffman.h * - * Copyright 2013 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef SAMPLEHUFFMAN_H #define SAMPLEHUFFMAN_H diff --git a/Smooth.h b/Smooth.h index 0ef02593f..3802ca6f8 100644 --- a/Smooth.h +++ b/Smooth.h @@ -1,11 +1,11 @@ /* * Smooth.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/Stack.h b/Stack.h index d3c671345..a789c8e1d 100644 --- a/Stack.h +++ b/Stack.h @@ -1,11 +1,11 @@ /* * Stack.h * - * Copyright 2013 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/StateVariable.h b/StateVariable.h index bfe52e77b..9c2b077b1 100644 --- a/StateVariable.h +++ b/StateVariable.h @@ -1,12 +1,11 @@ /* * StateVariable.h * - * This implementation copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/WaveFolder.h b/WaveFolder.h index 1bf5215b5..f69314c6a 100644 --- a/WaveFolder.h +++ b/WaveFolder.h @@ -1,12 +1,11 @@ /* - * Wavefolder.h - * - * Copyright 2022 Thomas Combriat + * WaveFolder.h * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2022-2024 Thomas Combriat and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/WavePacket.h b/WavePacket.h index d663870cc..ad3a3f300 100644 --- a/WavePacket.h +++ b/WavePacket.h @@ -1,11 +1,11 @@ /* * WavePacket.h * - * Copyright 2013 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/WavePacketSample.h b/WavePacketSample.h index 3508cf04d..1066a3c2d 100644 --- a/WavePacketSample.h +++ b/WavePacketSample.h @@ -1,13 +1,14 @@ /* * WavePacketSample.h * - * Copyright 2013 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef WAVEPACKETSAMPLE_H #define WAVEPACKETSAMPLE_H diff --git a/WaveShaper.h b/WaveShaper.h index a96d22346..3b700245b 100644 --- a/WaveShaper.h +++ b/WaveShaper.h @@ -1,11 +1,11 @@ /* * WaveShaper.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/extras/NEWS.txt b/extras/NEWS.txt index 47bf201fa..79db6ac93 100644 --- a/extras/NEWS.txt +++ b/extras/NEWS.txt @@ -6,6 +6,7 @@ get the latest version from https://sensorium.github.io/Mozzi/ NOT YET RELEASED (github version): Mozzi 2.0 - explicitly specify bit depth for "int" or "long" in several places, for better cross-platform consistency - restructured configuration options for more consistency across platforms, and easier customization +- changed licence to LGPL version 2.1 or later release v1.1.2 - new partial port of the Arduino Uno R4 diff --git a/hardware_defines.h b/hardware_defines.h index 1cd708c0d..7d61adf46 100644 --- a/hardware_defines.h +++ b/hardware_defines.h @@ -1,3 +1,15 @@ +/* + * hardware_defines.h.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + + #ifndef HARDWARE_DEFINES_H_ #define HARDWARE_DEFINES_H_ diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 53b7251ae..899d7a972 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -1,14 +1,14 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ + #include #include "CircularBuffer.h" diff --git a/internal/MozziGuts_impl_AVR.hpp b/internal/MozziGuts_impl_AVR.hpp index a217f6b08..10c82109c 100644 --- a/internal/MozziGuts_impl_AVR.hpp +++ b/internal/MozziGuts_impl_AVR.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_AVR.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #include "utility/FrequencyTimer2.h" #include "utility/TimerOne.h" diff --git a/internal/MozziGuts_impl_ESP32.hpp b/internal/MozziGuts_impl_ESP32.hpp index 71baaa983..4a4d35378 100644 --- a/internal/MozziGuts_impl_ESP32.hpp +++ b/internal/MozziGuts_impl_ESP32.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_ESP32.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2020-2024 Dieter Vandoren, Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #if !(IS_ESP32()) # error "Wrong implementation included for this platform" diff --git a/internal/MozziGuts_impl_ESP8266.hpp b/internal/MozziGuts_impl_ESP8266.hpp index 573dea1ef..f4623c96d 100644 --- a/internal/MozziGuts_impl_ESP8266.hpp +++ b/internal/MozziGuts_impl_ESP8266.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_ESP8266.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2020-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #if !(IS_ESP8266()) # error "Wrong implementation included for this platform" diff --git a/internal/MozziGuts_impl_MBED.hpp b/internal/MozziGuts_impl_MBED.hpp index 6f7d064e3..c4611bce4 100644 --- a/internal/MozziGuts_impl_MBED.hpp +++ b/internal/MozziGuts_impl_MBED.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_MBED.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2023-2024 T. Combriat and the Mozzi Team * - */ + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ #if !(IS_MBED()) # error "Wrong implementation included for this platform" diff --git a/internal/MozziGuts_impl_RENESAS.hpp b/internal/MozziGuts_impl_RENESAS.hpp index 4ad924c50..7ba7afda4 100644 --- a/internal/MozziGuts_impl_RENESAS.hpp +++ b/internal/MozziGuts_impl_RENESAS.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_RENESAS.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2023-2024 T. Combriat and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #if !(IS_RENESAS()) # error "Wrong implementation included for this platform" diff --git a/internal/MozziGuts_impl_RENESAS_ADC.hpp b/internal/MozziGuts_impl_RENESAS_ADC.hpp index 9b7afa97e..4f12b9596 100644 --- a/internal/MozziGuts_impl_RENESAS_ADC.hpp +++ b/internal/MozziGuts_impl_RENESAS_ADC.hpp @@ -1,4 +1,11 @@ /* + * MozziGuts_impl_ADC.hpp + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 T. Combriat and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. Parts of this file are drawn from Arduino's source code for analogRead() (https://github.com/arduino/ArduinoCore-renesas/blob/main/cores/arduino/analog.cpp) and part from Renesas' documentation (https://renesas.github.io/fsp/group___a_d_c.html), among other things. It contains functions to interact with the ADC in order to implement async ADC reads, aka mozziAnalogRead(). diff --git a/internal/MozziGuts_impl_RENESAS_analog.hpp b/internal/MozziGuts_impl_RENESAS_analog.hpp index 80caffdd6..0d1f58139 100644 --- a/internal/MozziGuts_impl_RENESAS_analog.hpp +++ b/internal/MozziGuts_impl_RENESAS_analog.hpp @@ -1,4 +1,13 @@ /* + * MozziGuts_impl_RENESAS_analog.hpp + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 T. Combriat and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + Most of this file is drawn, more or less adapted from the AnalogWave example for Renesas board from Arduino. It contains functions to create and start the on-board DAC (and associate timer). diff --git a/internal/MozziGuts_impl_RP2040.hpp b/internal/MozziGuts_impl_RP2040.hpp index edae67ffe..e7d34542c 100644 --- a/internal/MozziGuts_impl_RP2040.hpp +++ b/internal/MozziGuts_impl_RP2040.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_RP2040.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2022-2024 Thomas Friedrichsmeier and the Mozzi Team * - */ + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ // The main point of this check is to document, what platform & variants this implementation file is for. #if !(IS_RP2040()) diff --git a/internal/MozziGuts_impl_SAMD.hpp b/internal/MozziGuts_impl_SAMD.hpp index 37bfdb658..c1183ec91 100644 --- a/internal/MozziGuts_impl_SAMD.hpp +++ b/internal/MozziGuts_impl_SAMD.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_SAMD21.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2020-2024 Adrian Freed and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #if !(IS_SAMD21()) # error "Wrong implementation included for this platform" diff --git a/internal/MozziGuts_impl_STM32.hpp b/internal/MozziGuts_impl_STM32.hpp index 15d48b77d..6a90cc466 100644 --- a/internal/MozziGuts_impl_STM32.hpp +++ b/internal/MozziGuts_impl_STM32.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_STM32.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2020-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #include "HardwareTimer.h" diff --git a/internal/MozziGuts_impl_STM32duino.hpp b/internal/MozziGuts_impl_STM32duino.hpp index 57a9f9ac2..6d983caba 100644 --- a/internal/MozziGuts_impl_STM32duino.hpp +++ b/internal/MozziGuts_impl_STM32duino.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_STM32duino.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #include "HardwareTimer.h" diff --git a/internal/MozziGuts_impl_STM32duino_analog.hpp b/internal/MozziGuts_impl_STM32duino_analog.hpp index f6c986582..782237356 100644 --- a/internal/MozziGuts_impl_STM32duino_analog.hpp +++ b/internal/MozziGuts_impl_STM32duino_analog.hpp @@ -1,5 +1,16 @@ -namespace MozziPrivate { +/* + * MozziGuts_impl_STM32duino_analog.hpp + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * // NOTE: The contents of this file are copied mostly verbatim from Arduino_Core_STM32, (c) STMicroelectronics, BSD 3-clause license. +*/ + +namespace MozziPrivate { static PinName g_current_pin = NC; #ifndef ADC_SAMPLINGTIME diff --git a/internal/MozziGuts_impl_TEENSY.hpp b/internal/MozziGuts_impl_TEENSY.hpp index ddb8daf25..46b846f29 100644 --- a/internal/MozziGuts_impl_TEENSY.hpp +++ b/internal/MozziGuts_impl_TEENSY.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_STM32duino.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2013-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #if !(IS_TEENSY3() || IS_TEENSY4()) # error "Wrong implementation included for this platform" diff --git a/internal/MozziGuts_impl_template.hpp b/internal/MozziGuts_impl_template.hpp index b997e3cd3..4d99b04f3 100644 --- a/internal/MozziGuts_impl_template.hpp +++ b/internal/MozziGuts_impl_template.hpp @@ -1,14 +1,13 @@ /* - * MozziGuts.cpp - * - * Copyright 2012 Tim Barrass. + * MozziGuts_impl_template.hpp * * This file is part of Mozzi. * - * Mozzi by Tim Barrass is licensed under a Creative Commons - * Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team * - */ + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ /** README! * This file is meant to be used as a template when adding support for a new platform. Please read these instructions, first. diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index a5033c760..92bf0d424 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -1,3 +1,14 @@ +/* + * config_checks_avr.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + /* For Mozzi-internal use: Apply hardware specific config defaults and config checks: AVR */ /** @defgroup hardware diff --git a/internal/config_checks_esp32.h b/internal/config_checks_esp32.h index 2108bde9c..8bd0e9a0b 100644 --- a/internal/config_checks_esp32.h +++ b/internal/config_checks_esp32.h @@ -1,3 +1,14 @@ +/* + * config_checks_esp32.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECK_ESP32_H #define CONFIG_CHECK_ESP32_H diff --git a/internal/config_checks_esp8266.h b/internal/config_checks_esp8266.h index 3e6ab227b..8a0f826a0 100644 --- a/internal/config_checks_esp8266.h +++ b/internal/config_checks_esp8266.h @@ -1,3 +1,14 @@ +/* + * config_checks_esp8266.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECK_ESP8266_H #define CONFIG_CHECK_ESP8266_H diff --git a/internal/config_checks_generic.h b/internal/config_checks_generic.h index 42ee55774..731c1e3a0 100644 --- a/internal/config_checks_generic.h +++ b/internal/config_checks_generic.h @@ -1,3 +1,14 @@ +/* + * config_checks_generic.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + /** For Mozzi-internal use: Check configuration options for (some) invalid settings, and apply default for options that have not been set, so far. * */ diff --git a/internal/config_checks_mbed.h b/internal/config_checks_mbed.h index 46c26a288..dd74c015e 100644 --- a/internal/config_checks_mbed.h +++ b/internal/config_checks_mbed.h @@ -1,3 +1,14 @@ +/* + * config_checks_mbed.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECK_MBED_H #define CONFIG_CHECK_MBED_H diff --git a/internal/config_checks_renesas.h b/internal/config_checks_renesas.h index 59f88f94e..6296e37e6 100644 --- a/internal/config_checks_renesas.h +++ b/internal/config_checks_renesas.h @@ -1,3 +1,14 @@ +/* + * config_checks_renesas.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECK_RENESAS_H #define CONFIG_CHECK_RENESAS_H diff --git a/internal/config_checks_rp2040.h b/internal/config_checks_rp2040.h index 270e1af49..53fb8d6e6 100644 --- a/internal/config_checks_rp2040.h +++ b/internal/config_checks_rp2040.h @@ -1,3 +1,14 @@ +/* + * config_checks_rp2040.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECK_RP2040_H #define CONFIG_CHECK_RP2040_H diff --git a/internal/config_checks_samd21.h b/internal/config_checks_samd21.h index 225771ead..89e2394ba 100644 --- a/internal/config_checks_samd21.h +++ b/internal/config_checks_samd21.h @@ -1,3 +1,14 @@ +/* + * config_checks_samd21.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECK_SAMD21_H #define CONFIG_CHECK_SAMD21_H diff --git a/internal/config_checks_stm32duino.h b/internal/config_checks_stm32duino.h index 2efbbdd5d..35280184a 100644 --- a/internal/config_checks_stm32duino.h +++ b/internal/config_checks_stm32duino.h @@ -1,3 +1,14 @@ +/* + * config_checks_stm32duino.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECKS_STM32DUINO_H #define CONFIG_CHECKS_STM32DUINO_H diff --git a/internal/config_checks_stm32maple.h b/internal/config_checks_stm32maple.h index 507f93b31..b38dc34ec 100644 --- a/internal/config_checks_stm32maple.h +++ b/internal/config_checks_stm32maple.h @@ -1,3 +1,14 @@ +/* + * config_checks_stm32maple.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECKS_STM32MAPLE_H #define CONFIG_CHECKS_STM32MAPLE_H diff --git a/internal/config_checks_teensy.h b/internal/config_checks_teensy.h index 3358363f5..790892684 100644 --- a/internal/config_checks_teensy.h +++ b/internal/config_checks_teensy.h @@ -1,3 +1,14 @@ +/* + * config_checks_teensy.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef CONFIG_CHECK_TEENSY_H #define CONFIG_CHECK_TEENSY_H diff --git a/internal/config_checks_template.h b/internal/config_checks_template.h index 8227934a7..58570cf8e 100644 --- a/internal/config_checks_template.h +++ b/internal/config_checks_template.h @@ -9,6 +9,18 @@ * 3) Document some details of your port */ +/* + * config_checks_template.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * NOTE: In your port, don't forget to update the above copyright notice! + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + /** NOTE: If your port doesn't support MOZZI_OUTPUT_2PIN_PWM, add this include to make compilation of HIFI examples pass on the github runner */ #include "disable_2pinmode_on_github_workflow.h" /** NOTE: All ports need to provide a default for this */ diff --git a/internal/mozzi_macros.h b/internal/mozzi_macros.h index 51c2af075..e3b14085e 100644 --- a/internal/mozzi_macros.h +++ b/internal/mozzi_macros.h @@ -1,3 +1,14 @@ +/* + * mozzi_macros.h + * + * This file is part of Mozzi. + * + * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + /** This file contains some macros used internally inside Mozzi. These are not meant to be useful in user code. */ #ifndef MOZZI_MACROS_H diff --git a/internal/mozzi_rand_p.h b/internal/mozzi_rand_p.h index 02674bd36..64b62a5ed 100644 --- a/internal/mozzi_rand_p.h +++ b/internal/mozzi_rand_p.h @@ -1,3 +1,14 @@ +/* + * mozzi_rand_p.h + * + * This file is part of Mozzi. + * + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * +*/ + #ifndef MOZZI_RAND_P_H #define MOZZI_RAND_P_H diff --git a/internal/teensyPinMap.h b/internal/teensyPinMap.h index 1f028115e..bacfb15d7 100644 --- a/internal/teensyPinMap.h +++ b/internal/teensyPinMap.h @@ -1,13 +1,13 @@ /* * teensyPinMap.h * - * Copyright 2021 T. Combriat. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2021-2024 T. Combriat and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * - */ +*/ #ifndef TEENSYPINMAP_H_ #define TEENSYPINMAP_H diff --git a/meta.h b/meta.h index 0682bb6a6..b2609d18a 100644 --- a/meta.h +++ b/meta.h @@ -1,3 +1,14 @@ +/* + * meta.h + * + * This file is part of Mozzi. + * + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + /* http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Int-To-Type Template meta-programming extras. diff --git a/mozzi_analog.h b/mozzi_analog.h index fae9221c7..1e3bcca5d 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -1,14 +1,15 @@ /* * mozzi_analog.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef MOZZI_ANALOG_H_ #define MOZZI_ANALOG_H_ diff --git a/mozzi_fixmath.cpp b/mozzi_fixmath.cpp index 4ff110e59..c086756be 100644 --- a/mozzi_fixmath.cpp +++ b/mozzi_fixmath.cpp @@ -1,3 +1,14 @@ +/* + * mozzi_fixmath.cpp + * + * This file is part of Mozzi. + * + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + #include "mozzi_fixmath.h" /** @ingroup fixmath diff --git a/mozzi_fixmath.h b/mozzi_fixmath.h index b6c6da905..89f345e0c 100644 --- a/mozzi_fixmath.h +++ b/mozzi_fixmath.h @@ -1,11 +1,11 @@ /* * mozzi_fixmath.h * - * Copyright 2012 Tim Barrass. - * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/mozzi_midi.h b/mozzi_midi.h index 0f51fca38..8f1a15573 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -1,3 +1,14 @@ +/* + * mozzi_midi.h + * + * This file is part of Mozzi. + * + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + #ifndef MOZZI_MIDI_H_ #define MOZZI_MIDI_H_ diff --git a/mozzi_pgmspace.h b/mozzi_pgmspace.h index 87cafb680..9ef52cb91 100644 --- a/mozzi_pgmspace.h +++ b/mozzi_pgmspace.h @@ -1,3 +1,14 @@ +/* + * mozzi_pgmspace.h + * + * This file is part of Mozzi. + * + * Copyright 2018-2024 Thomas Friedrichsmeier and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + #ifndef MOZZI_PGMSPACE_H #define MOZZI_PGMSPACE_H diff --git a/mozzi_rand.h b/mozzi_rand.h index ef83de745..ca47784cd 100644 --- a/mozzi_rand.h +++ b/mozzi_rand.h @@ -1,3 +1,14 @@ +/* + * mozzi_rand.h + * + * This file is part of Mozzi. + * + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ + #ifndef MOZZI_RAND_H_ #define MOZZI_RAND_H_ diff --git a/mozzi_utils.h b/mozzi_utils.h index 018f91e5e..d275b95ff 100644 --- a/mozzi_utils.h +++ b/mozzi_utils.h @@ -1,3 +1,13 @@ +/* + * mozzi_utils.h + * + * This file is part of Mozzi. + * + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. + * + */ #ifndef UTILS_H_ #define UTILS_H_ diff --git a/primes.h b/primes.h index ca239cd64..4238c30a5 100644 --- a/primes.h +++ b/primes.h @@ -1,11 +1,11 @@ /* - * Primes.h - * - * Copyright 2012 Tim Barrass. + * primes.h * * This file is part of Mozzi. * - * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * Copyright 2012-2024 Tim Barrass and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/twi_nonblock.cpp b/twi_nonblock.cpp index b2af78880..084b88cfe 100644 --- a/twi_nonblock.cpp +++ b/twi_nonblock.cpp @@ -1,7 +1,11 @@ /* * twi_nonblock.cpp * - * Copyright 2012 Marije Baalman. + * This file is part of Mozzi. + * + * Copyright 2012-2024 Marije Baalman and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ diff --git a/twi_nonblock.h b/twi_nonblock.h index 6bc894079..a2c95ce2d 100644 --- a/twi_nonblock.h +++ b/twi_nonblock.h @@ -1,10 +1,15 @@ /* * twi_nonblock.h * - * Copyright 2012 Marije Baalman. + * This file is part of Mozzi. + * + * Copyright 2012-2024 Marije Baalman and the Mozzi Team + * + * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. * */ + #ifndef TWI_NONBLOCK_H_ #define TWI_NONBLOCK_H_ From 3cf33d04385b1a60c676f5b2b8dfa147d9a54bde Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 24 Mar 2024 13:48:33 +0100 Subject: [PATCH 182/215] Make mozziAnalogRead() portable (see https://github.com/sensorium/Mozzi/issues/232) --- internal/MozziGuts.hpp | 8 +++++--- internal/config_checks_avr.h | 2 ++ internal/config_checks_esp32.h | 2 ++ internal/config_checks_esp8266.h | 2 ++ internal/config_checks_mbed.h | 3 +++ internal/config_checks_renesas.h | 2 ++ internal/config_checks_rp2040.h | 2 ++ internal/config_checks_samd21.h | 2 ++ internal/config_checks_stm32duino.h | 15 +++++++++++++++ internal/config_checks_stm32maple.h | 4 +++- internal/config_checks_teensy.h | 3 +++ internal/config_checks_template.h | 10 ++++++++++ mozzi_analog.h | 30 +++++++++++++++++++++++++---- 13 files changed, 77 insertions(+), 8 deletions(-) diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 53b7251ae..596f0ed18 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -126,7 +126,7 @@ __attribute__((noinline)) void adcStartReadCycle() { } } -int mozziAnalogRead(uint8_t pin) { +int16_t mozziAnalogRead(uint8_t pin) { pin = adcPinToChannelNum(pin); // allow for channel or pin numbers; on most platforms other than AVR this has no effect. See note on pins/channels adc_channels_to_read.push(pin); return analog_readings[channelNumToIndex(pin)]; @@ -190,7 +190,7 @@ inline void advanceADCStep() { #else MOZZI_ASSERT_EQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) -int mozziAnalogRead(uint8_t pin) { +int16_t mozziAnalogRead(uint8_t pin) { return analogRead(pin); } @@ -289,7 +289,9 @@ uint32_t MozziRandPrivate::z=521288629; unsigned long audioTicks() { return MozziPrivate::audioTicks(); }; void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); }; void stopMozzi() { MozziPrivate::stopMozzi(); }; -int mozziAnalogRead(uint8_t pin) { return MozziPrivate::mozziAnalogRead(pin); }; +template int16_t mozziAnalogRead(uint8_t pin) { return (RES > MOZZI__INTERNAL_ANALOG_READ_RESOLUTION) ? MozziPrivate::mozziAnalogRead(pin) << (RES - MOZZI__INTERNAL_ANALOG_READ_RESOLUTION) : + (RES < MOZZI__INTERNAL_ANALOG_READ_RESOLUTION) ? MozziPrivate::mozziAnalogRead(pin) >> (RES - MOZZI__INTERNAL_ANALOG_READ_RESOLUTION) : + MozziPrivate::mozziAnalogRead(pin);}; #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) AudioOutputStorage_t getAudioInput() { return MozziPrivate::getAudioInput(); }; #endif diff --git a/internal/config_checks_avr.h b/internal/config_checks_avr.h index a5033c760..25f59c0f7 100644 --- a/internal/config_checks_avr.h +++ b/internal/config_checks_avr.h @@ -133,6 +133,8 @@ #define MOZZI_AUDIO_BITS (2*MOZZI_AUDIO_BITS_PER_CHANNEL) #endif +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10 + // Step 2: Check // NOTE: This step is not technically required, but a good idea in any port diff --git a/internal/config_checks_esp32.h b/internal/config_checks_esp32.h index 2108bde9c..5a01959df 100644 --- a/internal/config_checks_esp32.h +++ b/internal/config_checks_esp32.h @@ -131,4 +131,6 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) # define BYPASS_MOZZI_OUTPUT_BUFFER true #endif +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12 + #endif // #ifndef CONFIG_CHECK_ESP32_H diff --git a/internal/config_checks_esp8266.h b/internal/config_checks_esp8266.h index 3e6ab227b..ffa0a20aa 100644 --- a/internal/config_checks_esp8266.h +++ b/internal/config_checks_esp8266.h @@ -105,4 +105,6 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16) #define BYPASS_MOZZI_OUTPUT_BUFFER true #endif +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10 + #endif // #ifndef CONFIG_CHECK_ESP8266_H diff --git a/internal/config_checks_mbed.h b/internal/config_checks_mbed.h index 46c26a288..e57543b49 100644 --- a/internal/config_checks_mbed.h +++ b/internal/config_checks_mbed.h @@ -111,4 +111,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INP # define BYPASS_MOZZI_OUTPUT_BUFFER true #endif +// TODO: This value is correct for Arduino Giga and Arduino Portenta, but not necessarily everywhere else +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 16 + #endif // #ifndef CONFIG_CHECK_MBED_H diff --git a/internal/config_checks_renesas.h b/internal/config_checks_renesas.h index 59f88f94e..c4ece446b 100644 --- a/internal/config_checks_renesas.h +++ b/internal/config_checks_renesas.h @@ -67,4 +67,6 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_RE MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) #endif +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 14 + #endif // #ifndef CONFIG_CHECK_RENESAS_H diff --git a/internal/config_checks_rp2040.h b/internal/config_checks_rp2040.h index 270e1af49..fa51bf67e 100644 --- a/internal/config_checks_rp2040.h +++ b/internal/config_checks_rp2040.h @@ -108,6 +108,8 @@ MOZZI_CHECK_SUPPORTED(MOZZI_I2S_FORMAT, MOZZI_I2S_FORMAT_PLAIN, MOZZI_I2S_FORMAT # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD #endif +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12 + MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_ANALOG_READ_STANDARD) diff --git a/internal/config_checks_samd21.h b/internal/config_checks_samd21.h index 225771ead..f94abd5c0 100644 --- a/internal/config_checks_samd21.h +++ b/internal/config_checks_samd21.h @@ -66,4 +66,6 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) #endif +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12 + #endif // #ifndef CONFIG_CHECK_SAMD21_H diff --git a/internal/config_checks_stm32duino.h b/internal/config_checks_stm32duino.h index 2efbbdd5d..72960a457 100644 --- a/internal/config_checks_stm32duino.h +++ b/internal/config_checks_stm32duino.h @@ -129,5 +129,20 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD #endif +#if defined(ADC_RESOLUTION_16B) +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 16 +#elif defined(ADC_RESOLUTION_14B) +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 14 +#elif defined(ADC_RESOLUTION_12B) +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12 +#elif defined(ADC_RESOLUTION_10B) +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10 +#elif defined(ADC_RESOLUTION_8B) +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 8 +#elif defined(ADC_RESOLUTION_6B) +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 6 +#else +#error This should not happen. HAL not included? +#endif #endif // #ifndef CONFIG_CHECKS_STM32DUINO_H diff --git a/internal/config_checks_stm32maple.h b/internal/config_checks_stm32maple.h index 507f93b31..cd5118d86 100644 --- a/internal/config_checks_stm32maple.h +++ b/internal/config_checks_stm32maple.h @@ -13,7 +13,7 @@ * * @section stm32_maple_status Status and peculiarities of this port * Compiles for and runs on a STM32F103C8T6 blue pill board, with a bunch of caveats (see below), i.e. on a board _without_ a - * real DAC. Should probably run on any other board supported by [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32) (although this theory is untested). + * real DAC. Should probably run on any other board supported by [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Ardu0ino_STM32) (although this theory is untested). * * @note that at the time of this writing, [Stev Strong's slightliy more recent fork of this core](https://github.com/stevstrong/Arduino_STM32/) does *not* work with * Mozzi, apparently due to a bug in pwmWrite(). @@ -120,5 +120,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD #endif +// TODO: This probably isn't correct for all boards! +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12 #endif // #ifndef CONFIG_CHECKS_STM32MAPLE_H diff --git a/internal/config_checks_teensy.h b/internal/config_checks_teensy.h index 3358363f5..a4d70c996 100644 --- a/internal/config_checks_teensy.h +++ b/internal/config_checks_teensy.h @@ -138,4 +138,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) # endif #endif +//TODO: Not 100% sure this is correct in all cases. +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10 + #endif // #ifndef CONFIG_CHECK_TEENSY_H diff --git a/internal/config_checks_template.h b/internal/config_checks_template.h index 8227934a7..1e00d2c5e 100644 --- a/internal/config_checks_template.h +++ b/internal/config_checks_template.h @@ -31,6 +31,15 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_ /** NOTE: *Otherwise* you may additionally document that as not-yet-supported like so: */ // MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ) +/** NOTE: This should be set to whichever resolution (in bits) mozziAnalogRead() returns values in by default in your implementation. + * mozziAnalogRead() will shift the return value accordingly. + * + * Generally you will set this to the default hardware resolution for this platform, but of course it's also possible - for instance - + * to set this to the user configurable MOZZI_ANALOG_READ_RESOLUTION (if it has been defined), and configure your ADC reads, accordingly, + * avoiding the extra shift operation. +*/ +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10 + /** NOTE: Example for additional config options depending on a specific output mode: */ #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_INTERNAL_DAC) # if !defined(MOZZI_AUDIO_PIN_1) @@ -45,6 +54,7 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO) #endif + /** NOTE: You may also set further, implementation-specific defines, here. E.g. BYPASS_MOZZI_OUTPUT_BUFFER. Defines that are purely * specific to your port (i.e. only needed inside MozziGuts_impt_YOURPLATFORM.h, should be #undef'ed at the end of that file. */ diff --git a/mozzi_analog.h b/mozzi_analog.h index fae9221c7..735487f9f 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -134,19 +134,41 @@ Use adcPinToChannelNum() to convert the pin number to its channel number. */ void adcStartConversion(uint8_t channel); +/** @ingroup analog +See mozziAnalogRead(). The template parameter RES specifies the number of bits to return. +*/ +template int16_t mozziAnalogRead(uint8_t pin); +/** @ingroup analog +See mozziAnalogRead() but always returns the value shifted to 16 bit range. THis is exactly +equivalent to mozziAnalogRead<16>(pin); +*/ +int16_t mozziAnalogRead16(uint8_t pin) { return mozziAnalogRead<16>(pin); }; +#if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION) /** @ingroup analog Reads the analog input of a chosen channel, without blocking other operations from running. It actually returns the most recent analog reading and puts the chosen pin or channel on the stack of channels to be read in the background before the next control interrupt. + +@note Analog reads have different hardware resolution on different platforms. E.g. an analog read + on an Arduino Uno R3 will return a value in the range 0-1023 (10 bits), on a Raspberry Pi Pico + it will return 0-4095 (12 bits). For portable code, it is thus necessary to specify the desired + resolution of reads. This can be done by setting MOZZI_ANALOG_READ_RESOLUTION to the resolution + in bits, near the top of your sketch. All reads will then be adjusted to that range, automatically + (using a simple bit-shift). Alternatively, the templated version of mozziAanalogRead() allows + to specifiy the target resolution per read. + If MOZZI_ANALOG_READ_RESOLUTION is not defined, this (non-templated) function returns a value + in the default hardware resolution, with a warning. + @param pin_or_channel the analog pin or channel number. -@return the digitised value of the voltage on the chosen channel, in the range 0-1023. @Note that non-AVR -hardware may return a different range, e.g. 0-4095 on STM32 boards. +@return the digitised value of the voltage on the chosen channel. See the note above regarding the output range! */ -int mozziAnalogRead(uint8_t pin); - +int16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } +#else +MOZZI_DEPRECATED("2.0", "This use of mozziAnalogRead() is not portable.") int16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } +#endif uint8_t adcPinToChannelNum(uint8_t pin); From fb26588d6518763423d2f44370758a3276228004 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 24 Mar 2024 14:28:10 +0100 Subject: [PATCH 183/215] Add portable getAudioInput(), too. --- MozziGuts.h | 21 +++++++++++++++++++-- internal/MozziGuts.hpp | 13 ++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/MozziGuts.h b/MozziGuts.h index 4453ab6fe..420b5faaf 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -136,7 +136,15 @@ are called. */ void audioHook(); +/** @ingroup analog + +See getAudioInput(). The template parameter specifies the desired value range in bits. */ +template int16_t getAudioInput(); + +/** @ingroup analog +See getAudioInput(). Equivalent to getAudioInput<16>(). */ +template int16_t getAudioInput16() { return getAudioInput<16>(); } /** @ingroup analog This returns audio input from the input buffer, if @@ -150,10 +158,19 @@ and http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/ . A circuit and instructions for amplifying and biasing a microphone signal can be found at http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS + +@note The value range returned by this function follows the same rules as detailed in the documentation + for mozziAnalogRead(): For portable code, define MOZZI_ANALGO_READ_RESOLUTION at the top of your + sketch, or use the templated version of this function. + @return audio data from the input buffer */ -#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) -int getAudioInput(); +#if defined(FOR_DOXYGEN_ONLY) || (!MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)) +#if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION) +int16_t getAudioInput() { return getAudioInput(); }; +#else +MOZZI_DEPRECATED("2.0", "This use of getAudioInput() is not portable") int16_t getAudioInput() { return getAudioInput(); }; +#endif #endif diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 596f0ed18..a7b1421c3 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -27,6 +27,11 @@ static void advanceADCStep(); // to be provided by platfor static void startSecondADCReadOnCurrentChannel(); // to be provided by platform implementation static uint8_t adc_count = 0; // needed below #endif + +// TODO: make this helper public? +template constexpr T smartShift(T value) { + return (BITS_IN > BITS_OUT) ? value >> (BITS_IN - BITS_OUT) : (BITS_IN < BITS_OUT) ? value << (BITS_OUT - BITS_IN) : value; +} } // Include the appropriate implementation @@ -134,7 +139,7 @@ int16_t mozziAnalogRead(uint8_t pin) { #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) static AudioOutputStorage_t audio_input; // holds the latest audio from input_buffer -AudioOutputStorage_t getAudioInput() { return audio_input; } +int16_t getAudioInput() { return audio_input; } #endif #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) @@ -289,11 +294,9 @@ uint32_t MozziRandPrivate::z=521288629; unsigned long audioTicks() { return MozziPrivate::audioTicks(); }; void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); }; void stopMozzi() { MozziPrivate::stopMozzi(); }; -template int16_t mozziAnalogRead(uint8_t pin) { return (RES > MOZZI__INTERNAL_ANALOG_READ_RESOLUTION) ? MozziPrivate::mozziAnalogRead(pin) << (RES - MOZZI__INTERNAL_ANALOG_READ_RESOLUTION) : - (RES < MOZZI__INTERNAL_ANALOG_READ_RESOLUTION) ? MozziPrivate::mozziAnalogRead(pin) >> (RES - MOZZI__INTERNAL_ANALOG_READ_RESOLUTION) : - MozziPrivate::mozziAnalogRead(pin);}; +template int16_t mozziAnalogRead(uint8_t pin) { return MozziPrivate::smartShift(MozziPrivate::mozziAnalogRead(pin));}; #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) -AudioOutputStorage_t getAudioInput() { return MozziPrivate::getAudioInput(); }; +template int16_t getAudioInput() { return MozziPrivate::smartShift(MozziPrivate::getAudioInput()); }; #endif #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) void setupMozziADC(int8_t speed) { MozziPrivate::setupMozziADC(speed); }; From 1073619055be9388281ead6a6a51284de3ddf54a Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sun, 24 Mar 2024 14:32:28 +0100 Subject: [PATCH 184/215] Fix compilation --- MozziGuts.h | 6 +++--- internal/config_checks_stm32duino.h | 16 +--------------- mozzi_analog.h | 6 +++--- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/MozziGuts.h b/MozziGuts.h index 420b5faaf..17fe8a399 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -144,7 +144,7 @@ template int16_t getAudioInput(); /** @ingroup analog See getAudioInput(). Equivalent to getAudioInput<16>(). */ -template int16_t getAudioInput16() { return getAudioInput<16>(); } +template inline int16_t getAudioInput16() { return getAudioInput<16>(); } /** @ingroup analog This returns audio input from the input buffer, if @@ -167,9 +167,9 @@ A circuit and instructions for amplifying and biasing a microphone signal can be */ #if defined(FOR_DOXYGEN_ONLY) || (!MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)) #if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION) -int16_t getAudioInput() { return getAudioInput(); }; +inline int16_t getAudioInput() { return getAudioInput(); }; #else -MOZZI_DEPRECATED("2.0", "This use of getAudioInput() is not portable") int16_t getAudioInput() { return getAudioInput(); }; +MOZZI_DEPRECATED("2.0", "This use of getAudioInput() is not portable") inline int16_t getAudioInput() { return getAudioInput(); }; #endif #endif diff --git a/internal/config_checks_stm32duino.h b/internal/config_checks_stm32duino.h index 72960a457..06597b91a 100644 --- a/internal/config_checks_stm32duino.h +++ b/internal/config_checks_stm32duino.h @@ -129,20 +129,6 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD #endif -#if defined(ADC_RESOLUTION_16B) -#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 16 -#elif defined(ADC_RESOLUTION_14B) -#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 14 -#elif defined(ADC_RESOLUTION_12B) -#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12 -#elif defined(ADC_RESOLUTION_10B) -#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10 -#elif defined(ADC_RESOLUTION_8B) -#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 8 -#elif defined(ADC_RESOLUTION_6B) -#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 6 -#else -#error This should not happen. HAL not included? -#endif +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION ADC_RESOLUTION #endif // #ifndef CONFIG_CHECKS_STM32DUINO_H diff --git a/mozzi_analog.h b/mozzi_analog.h index 735487f9f..52005491a 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -143,7 +143,7 @@ template int16_t mozziAnalogRead(uint8_t pin); See mozziAnalogRead() but always returns the value shifted to 16 bit range. THis is exactly equivalent to mozziAnalogRead<16>(pin); */ -int16_t mozziAnalogRead16(uint8_t pin) { return mozziAnalogRead<16>(pin); }; +inline int16_t mozziAnalogRead16(uint8_t pin) { return mozziAnalogRead<16>(pin); }; #if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION) /** @ingroup analog @@ -165,9 +165,9 @@ interrupt. @param pin_or_channel the analog pin or channel number. @return the digitised value of the voltage on the chosen channel. See the note above regarding the output range! */ -int16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } +inline int16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } #else -MOZZI_DEPRECATED("2.0", "This use of mozziAnalogRead() is not portable.") int16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } +MOZZI_DEPRECATED("2.0", "This use of mozziAnalogRead() is not portable.") inline int16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } #endif uint8_t adcPinToChannelNum(uint8_t pin); From 13185b3ca6da50a7c41abc528025be981a9d2b79 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Wed, 27 Mar 2024 23:31:23 +0100 Subject: [PATCH 185/215] Formally return unsigned for analog reads --- MozziGuts.h | 4 ++-- internal/MozziGuts.hpp | 6 +++--- mozzi_analog.h | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/MozziGuts.h b/MozziGuts.h index 17fe8a399..b18b5fe98 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -167,9 +167,9 @@ A circuit and instructions for amplifying and biasing a microphone signal can be */ #if defined(FOR_DOXYGEN_ONLY) || (!MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)) #if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION) -inline int16_t getAudioInput() { return getAudioInput(); }; +inline uint16_t getAudioInput() { return getAudioInput(); }; #else -MOZZI_DEPRECATED("2.0", "This use of getAudioInput() is not portable") inline int16_t getAudioInput() { return getAudioInput(); }; +MOZZI_DEPRECATED("2.0", "This use of getAudioInput() is not portable. Refer to the API documentation for suggested alternatives") inline uint16_t getAudioInput() { return getAudioInput(); }; #endif #endif diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index a7b1421c3..90e2d1b8c 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -195,7 +195,7 @@ inline void advanceADCStep() { #else MOZZI_ASSERT_EQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) -int16_t mozziAnalogRead(uint8_t pin) { +uint16_t mozziAnalogRead(uint8_t pin) { return analogRead(pin); } @@ -294,9 +294,9 @@ uint32_t MozziRandPrivate::z=521288629; unsigned long audioTicks() { return MozziPrivate::audioTicks(); }; void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); }; void stopMozzi() { MozziPrivate::stopMozzi(); }; -template int16_t mozziAnalogRead(uint8_t pin) { return MozziPrivate::smartShift(MozziPrivate::mozziAnalogRead(pin));}; +template uint16_t mozziAnalogRead(uint8_t pin) { return MozziPrivate::smartShift(MozziPrivate::mozziAnalogRead(pin));}; #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) -template int16_t getAudioInput() { return MozziPrivate::smartShift(MozziPrivate::getAudioInput()); }; +template uint16_t getAudioInput() { return MozziPrivate::smartShift(MozziPrivate::getAudioInput()); }; #endif #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) void setupMozziADC(int8_t speed) { MozziPrivate::setupMozziADC(speed); }; diff --git a/mozzi_analog.h b/mozzi_analog.h index 52005491a..d6a274339 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -137,13 +137,13 @@ void adcStartConversion(uint8_t channel); /** @ingroup analog See mozziAnalogRead(). The template parameter RES specifies the number of bits to return. */ -template int16_t mozziAnalogRead(uint8_t pin); +template uint16_t mozziAnalogRead(uint8_t pin); /** @ingroup analog See mozziAnalogRead() but always returns the value shifted to 16 bit range. THis is exactly equivalent to mozziAnalogRead<16>(pin); */ -inline int16_t mozziAnalogRead16(uint8_t pin) { return mozziAnalogRead<16>(pin); }; +inline uint16_t mozziAnalogRead16(uint8_t pin) { return mozziAnalogRead<16>(pin); }; #if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION) /** @ingroup analog @@ -165,9 +165,9 @@ interrupt. @param pin_or_channel the analog pin or channel number. @return the digitised value of the voltage on the chosen channel. See the note above regarding the output range! */ -inline int16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } +inline uint16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } #else -MOZZI_DEPRECATED("2.0", "This use of mozziAnalogRead() is not portable.") inline int16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } +MOZZI_DEPRECATED("2.0", "This use of mozziAnalogRead() is not portable. Refer to the API documentation for suggested alternatives.") inline uint16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } #endif uint8_t adcPinToChannelNum(uint8_t pin); From 8944cf62f3ff1ab11cc2750c95ce9a5002ae4383 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 28 Mar 2024 00:07:34 +0100 Subject: [PATCH 186/215] Adjust examples to scalable analog reads. I ended up keeping most readings at 10 bits. --- .../Control_Echo_Theremin/Control_Echo_Theremin.ino | 2 +- .../Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino | 2 ++ .../Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino | 4 ++-- .../Knob_LightLevel_x2_FMsynth.ino | 1 + .../Light_Temperature_Detuned.ino | 4 ++-- .../Light_Temperature_Multi_Oscil.ino | 4 ++-- examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino | 6 +++--- .../Piezo_SampleScrubber/Piezo_SampleScrubber.ino | 2 +- .../Piezo_SampleTrigger/Piezo_SampleTrigger.ino | 4 ++-- .../03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino | 2 +- examples/03.Sensors/Volume_Knob/Volume_Knob.ino | 8 +++----- .../Volume_Knob_LightLevel_Frequency.ino | 9 +++------ .../Audio_Input_with_Knob_Filter.ino | 3 +-- .../Audio_and_Control_Input/Audio_and_Control_Input.ino | 2 +- examples/05.Control_Filters/DCfilter/DCfilter.ino | 4 ++-- .../05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino | 6 +++--- .../05.Control_Filters/RollingAverage/RollingAverage.ino | 2 +- .../Thermistor_OverSample/Thermistor_OverSample.ino | 2 +- examples/06.Synthesis/PDresonant/PDresonant.ino | 8 ++++---- .../06.Synthesis/WavePacket_Double/WavePacket_Double.ino | 6 +++--- .../06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino | 6 +++--- .../06.Synthesis/WavePacket_Single/WavePacket_Single.ino | 6 +++--- 22 files changed, 45 insertions(+), 48 deletions(-) diff --git a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino index 47d1626e6..96b874063 100644 --- a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino +++ b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino @@ -57,7 +57,7 @@ void setup(){ void updateControl(){ - int bumpy_input = mozziAnalogRead(INPUT_PIN); + int bumpy_input = mozziAnalogRead<10>(INPUT_PIN); // request reading at 10-bit resolution, i.e. 0-1023 averaged = kAverage.next(bumpy_input); aSin0.setFreq(averaged); aSin1.setFreq(kDelay.next(averaged)); diff --git a/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino b/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino index 4be6ea6b8..2dc1e569a 100644 --- a/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino +++ b/examples/03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino @@ -37,6 +37,8 @@ Tim Barrass 2013, CC by-nc-sa. */ +#define MOZZI_ANALOG_READ_RESOLUTION 10 // code below assumes readings to be in the classic 10-bit (0-1023) range +#include #include #include #include diff --git a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino index 0ac2b9ab0..bd60891ed 100644 --- a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino @@ -68,7 +68,7 @@ void setup(){ void updateControl(){ // read the knob - int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023 + int knob_value = mozziAnalogRead<10>(KNOB_PIN); // value is 0-1023 // map the knob to carrier frequency int carrier_freq = kMapCarrierFreq(knob_value); @@ -81,7 +81,7 @@ void updateControl(){ aModulator.setFreq(mod_freq); // read the light dependent resistor on the Analog input pin - int light_level= mozziAnalogRead(LDR_PIN); // value is 0-1023 + int light_level= mozziAnalogRead<10>(LDR_PIN); // value is 0-1023 // print the value to the Serial monitor for debugging Serial.print("light_level = "); diff --git a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino index 6aba9b6cf..364cca099 100644 --- a/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_x2_FMsynth/Knob_LightLevel_x2_FMsynth.ino @@ -36,6 +36,7 @@ Tim Barrass 2013, CC by-nc-sa. */ +#define MOZZI_ANALOG_READ_RESOLUTION 10 // code below assumes readings to be in the classic 10-bit (0-1023) range #include #include // oscillator #include // table for Oscils to play diff --git a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino index 5d051071b..20f30ec0f 100644 --- a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino +++ b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino @@ -102,8 +102,8 @@ void loop(){ void updateControl(){ // read analog inputs - int temperature = mozziAnalogRead(THERMISTOR_PIN); // not calibrated to degrees! - int light_input = mozziAnalogRead(LDR_PIN); + int temperature = mozziAnalogRead<10>(THERMISTOR_PIN); // not calibrated to degrees! Simply a 10-bit voltage reading (0-1023) + int light_input = mozziAnalogRead<10>(LDR_PIN); float base_freq_offset = OFFSET_SCALE*temperature; float divergence = DIVERGENCE_SCALE*light_input; diff --git a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino index 48b84aafb..663b6d866 100644 --- a/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino +++ b/examples/03.Sensors/Light_Temperature_Multi_Oscil/Light_Temperature_Multi_Oscil.ino @@ -94,8 +94,8 @@ void updateControl(){ static float previous_pulse_freq; // read analog inputs - int temperature = mozziAnalogRead(THERMISTOR_PIN); // not calibrated to degrees! - int light = mozziAnalogRead(LDR_PIN); + int temperature = mozziAnalogRead<10>(THERMISTOR_PIN); // not calibrated to degrees! + int light = mozziAnalogRead<10>(LDR_PIN); // map light reading to volume pulse frequency float pulse_freq = (float)light/256; diff --git a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino index 8a0aed82d..dcf4fd51b 100644 --- a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino +++ b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino @@ -47,7 +47,9 @@ void setup(){ void updateControl(){ - // read the piezo + // read the piezo. We request 12-bits resolution, here, for values of 0-4095. Some boards + // will actually provide that much accuracy, for others the readings are simply shifted to a + // larger range. int piezo_value = mozziAnalogRead(PIEZO_PIN); // value is 0-1023 // print the value to the Serial monitor for debugging @@ -55,8 +57,6 @@ void updateControl(){ Serial.print(piezo_value); Serial.print("\t \t"); // prints 2 tabs - int frequency = piezo_value*3; // calibrate - // print the frequency to the Serial monitor for debugging Serial.print("frequency = "); Serial.print(frequency); diff --git a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino index bcbfddc4c..3ddf9c7ff 100644 --- a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino +++ b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino @@ -59,7 +59,7 @@ void setup(){ void updateControl(){ // read the pot - int sensor_value = mozziAnalogRead(INPUT_PIN); // value is 0-1023 + int sensor_value = mozziAnalogRead<10>(INPUT_PIN); // value is 0-1023 // map it to an 8 bit range for efficient calculations in updateAudio int target = ((long) sensor_value * BLAHBLAH4B_NUM_CELLS) >> 10; // >> 10 is / 1024 diff --git a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino index 2adffe0ef..d218fdc3f 100644 --- a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino +++ b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino @@ -55,7 +55,7 @@ void setup(){ void updateControl(){ // read the knob - int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023 + int knob_value = mozziAnalogRead<10>(KNOB_PIN); // value is 0-1023 // map it to values between 0.1 and about double the recorded pitch float pitch = (recorded_pitch * (float) knob_value / 512.f) + 0.1f; @@ -64,7 +64,7 @@ void updateControl(){ aSample.setFreq(pitch); // read the piezo - int piezo_value = mozziAnalogRead(PIEZO_PIN); // value is 0-1023 + int piezo_value = mozziAnalogRead<10>(PIEZO_PIN); // value is 0-1023 // print the value to the Serial monitor for debugging Serial.print("piezo value = "); diff --git a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino index 4dded0b8f..b63a6c7a2 100644 --- a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino +++ b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino @@ -79,7 +79,7 @@ void buttonChangePitch(){ void updateControl(){ // read the piezo - int piezo_value = mozziAnalogRead(PIEZO_PIN); // value is 0-1023 + int piezo_value = mozziAnalogRead<10>(PIEZO_PIN); // value is 0-1023 // print the value to the Serial monitor for debugging Serial.print("piezo value = "); diff --git a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino index fd21e715f..7863d53f9 100644 --- a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino +++ b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino @@ -53,11 +53,9 @@ void setup(){ void updateControl(){ - // read the variable resistor for volume - int sensor_value = mozziAnalogRead(INPUT_PIN); // value is 0-1023 - - // map it to an 8 bit range for efficient calculations in updateAudio - volume = map(sensor_value, 0, 1023, 0, 255); + // read the variable resistor for volume. We specifically request only 8 bits of resolution, here, which + // is less than the default on most platforms, but a convenient range to work with, where accuracy is not too important. + volume = mozziAnalogRead<8>(INPUT_PIN); // print the value to the Serial monitor for debugging Serial.print("volume = "); diff --git a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino index 98a9d7bd2..3edcc2f91 100644 --- a/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino +++ b/examples/03.Sensors/Volume_Knob_LightLevel_Frequency/Volume_Knob_LightLevel_Frequency.ino @@ -56,11 +56,8 @@ void setup(){ void updateControl(){ - // read the potentiometer - int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023 - - // map it to an 8 bit volume range for efficient calculations in updateAudio - volume = knob_value >> 2; // 10 bits (0->1023) shifted right by 2 bits to give 8 bits (0->255) + // read the potentiometer as only 8 bit volume range for efficient calculations in updateAudio + volume = mozziAnalogRead<8>(KNOB_PIN); // value is 0-255 // print the value to the Serial monitor for debugging Serial.print("volume = "); @@ -68,7 +65,7 @@ void updateControl(){ Serial.print("\t"); // prints a tab // read the light dependent resistor - int light_level = mozziAnalogRead(LDR_PIN); // value is 0-1023 + int light_level = mozziAnalogRead<10>(LDR_PIN); // We request 10 bits, here, however. Value is 0-1023 // print the value to the Serial monitor for debugging Serial.print("light level = "); diff --git a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino index 8c87b88ef..c78ccc8bc 100644 --- a/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino +++ b/examples/04.Audio_Input/Audio_Input_with_Knob_Filter/Audio_Input_with_Knob_Filter.ino @@ -44,8 +44,7 @@ void setup(){ void updateControl(){ - int knob = mozziAnalogRead(KNOB_PIN); - byte cutoff_freq = knob>>2; // range 0-255 + byte cutoff_freq = mozziAnalogRead<8>(KNOB_PIN); // range 0-255 lpf.setCutoffFreq(cutoff_freq); } diff --git a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino index a7bf65823..f56764127 100644 --- a/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino +++ b/examples/04.Audio_Input/Audio_and_Control_Input/Audio_and_Control_Input.ino @@ -44,7 +44,7 @@ void setup() { void updateControl(){ for (int i=1;i(sensorPin); Serial.print(sensorValue); Serial.print(" Filtered = "); Serial.println(dcFiltered.next(sensorValue)); diff --git a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino index 4d88d3c3e..76d42c0de 100644 --- a/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino +++ b/examples/05.Control_Filters/Line_vs_Smooth/Line_vs_Smooth.ino @@ -69,9 +69,9 @@ void setup(){ volatile unsigned int freq1; // global so it can be used in updateAudio, volatile to stop it getting changed while being used void updateControl(){ - Q16n16 freq0 = Q16n0_to_Q16n16(mozziAnalogRead(0)); // 0 to 1023, scaled up to Q16n16 format - freq1 = (unsigned int) mozziAnalogRead(1); // 0 to 1023 - aInterpolate.set(freq0, AUDIO_STEPS_PER_CONTROL); + Q16n16 freq0 = Q16n0_to_Q16n16(mozziAnalogRead<10>(0)); // 0 to 1023, scaled up to Q16n16 format + freq1 = (unsigned int) mozziAnalogRead<10>(1); // 0 to 1023 + aInterpolate.set(freq0, AUDIO_STEPS_PER_CONTROL); } diff --git a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino index a9d58d7f0..e5993973b 100644 --- a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino +++ b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino @@ -42,7 +42,7 @@ void setup(){ void updateControl(){ - int bumpy_input = mozziAnalogRead(INPUT_PIN); + int bumpy_input = mozziAnalogRead<10>(INPUT_PIN); averaged = kAverage.next(bumpy_input); Serial.print("bumpy \t"); diff --git a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino index 8ca4aa52f..c8a3147ef 100644 --- a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino +++ b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino @@ -69,7 +69,7 @@ void updateControl(){ static int counter, old_oversampled; // read the variable resistor - int sensor_value = mozziAnalogRead(INPUT_PIN); // value is 0-1023 + int sensor_value = mozziAnalogRead<10>(INPUT_PIN); // value is 0-1023 // get the next oversampled sensor value int oversampled = overSampler.next(sensor_value); diff --git a/examples/06.Synthesis/PDresonant/PDresonant.ino b/examples/06.Synthesis/PDresonant/PDresonant.ino index 3b78b47d8..436f80cae 100644 --- a/examples/06.Synthesis/PDresonant/PDresonant.ino +++ b/examples/06.Synthesis/PDresonant/PDresonant.ino @@ -120,13 +120,13 @@ void updateControl(){ //MIDI.read(); // analog joystick for controlling speed of modulation: assigned to attack, decay times and sustain level - //x_axis = mozziAnalogRead(X); - //y_axis = mozziAnalogRead(Y); + //x_axis = mozziAnalogRead<10>(X); + //y_axis = mozziAnalogRead<10>(Y); // for testing/demo without external input fakeMidiRead(); - x_axis = 512; //mozziAnalogRead(X); - y_axis = 512; // mozziAnalogRead(Y); + x_axis = 512; //mozziAnalogRead<10>(X); + y_axis = 512; // mozziAnalogRead<10>(Y); voice.update(); } diff --git a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino index 4d1638599..850248468 100644 --- a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino +++ b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino @@ -52,9 +52,9 @@ void setup(){ void updateControl(){ - wavey.set(kAverageF.next(mozziAnalogRead(FUNDAMENTAL_PIN))+1, - kAverageBw.next(mozziAnalogRead(BANDWIDTH_PIN)), - kAverageCf.next(2*mozziAnalogRead(CENTREFREQ_PIN))); + wavey.set(kAverageF.next(mozziAnalogRead<10>(FUNDAMENTAL_PIN))+1, // 1-1024 + kAverageBw.next(mozziAnalogRead<10>(BANDWIDTH_PIN)), // 0-1023 + kAverageCf.next(mozziAnalogRead<11>(CENTREFREQ_PIN))); // 0-2047 } diff --git a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino index d85114b07..88bf4d545 100644 --- a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino +++ b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino @@ -60,9 +60,9 @@ void setup(){ void updateControl(){ - int f = kAverageF.next(mozziAnalogRead(FUNDAMENTAL_PIN))+1; - int b = kAverageBw.next(mozziAnalogRead(BANDWIDTH_PIN)); - int cf = kAverageCf.next(2*mozziAnalogRead(CENTREFREQ_PIN)); + int f = kAverageF.next(mozziAnalogRead<10>(FUNDAMENTAL_PIN))+1; + int b = kAverageBw.next(mozziAnalogRead<10>(BANDWIDTH_PIN)); + int cf = kAverageCf.next(mozziAnalogRead<11>(CENTREFREQ_PIN)); wavey.set(f, b, cf); } diff --git a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino index 6e58e4d7b..16a0a32b0 100644 --- a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino +++ b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino @@ -53,9 +53,9 @@ void setup(){ void updateControl(){ - wavey.set(kAverageF.next(mozziAnalogRead(FUNDAMENTAL_PIN))+1, - kAverageBw.next(mozziAnalogRead(BANDWIDTH_PIN)), - kAverageCf.next(2*mozziAnalogRead(CENTREFREQ_PIN))); + wavey.set(kAverageF.next(mozziAnalogRead<10>(FUNDAMENTAL_PIN))+1, + kAverageBw.next(mozziAnalogRead<10>(BANDWIDTH_PIN)), + kAverageCf.next(mozziAnalogRead<11>(CENTREFREQ_PIN))); } From 8cc36a291a7d795e1a3d4c3c11b86b4538ca32e2 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 28 Mar 2024 00:22:30 +0100 Subject: [PATCH 187/215] Clarify, and fix accidental comment. --- internal/MozziGuts.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 90e2d1b8c..454b38cbd 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -287,10 +287,11 @@ uint32_t MozziRandPrivate::z=521288629; #undef MOZZI__LEGACY_AUDIO_INPUT_IMPL // "export" publicly accessible functions defined in this file -// NOTE: unfortunately, we cannot just write using MozziPrivate::mozziMicros(), and that will conflict with, rather than define mozziMicros() -// we might want to rethink how this is done. What matters is that these functions are user accessible, though, while most of what we +// NOTE: unfortunately, we cannot just write "using MozziPrivate::mozziMicros()", etc. as that would conflict with, rather than define mozziMicros(). +// Instead, for now, we forward the global-scope functions to their implementations inside MozziPrivate. +// We might want to rethink how this is done. What matters is that these functions are user accessible, though, while most of what we // now keep in MozziPrivate is hidden away. -//unsigned long mozziMicros() { return MozziPrivate::mozziMicros(); }; +unsigned long mozziMicros() { return MozziPrivate::mozziMicros(); }; unsigned long audioTicks() { return MozziPrivate::audioTicks(); }; void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); }; void stopMozzi() { MozziPrivate::stopMozzi(); }; From 42c79560711a2b5e39e05aa6f830b382d46bc1a0 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 28 Mar 2024 10:42:53 +0100 Subject: [PATCH 188/215] Check range of MOZZI_ANALOG_READ_RESOLUTION, and add some further internal docs. --- internal/config_checks_generic.h | 7 +++++++ internal/config_checks_template.h | 23 +++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/internal/config_checks_generic.h b/internal/config_checks_generic.h index 42ee55774..795081b97 100644 --- a/internal/config_checks_generic.h +++ b/internal/config_checks_generic.h @@ -119,6 +119,13 @@ MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_RE # undef MOZZI__ANALOG_READ_NOT_CONFIGURED #endif +#if defined(MOZZI_ANALOG_READ_RESOLUTION) +# if (MOZZI_ANALOG_READ_RESOLUTION < 1) || (MOZZI_ANALOG_READ_RESOLUTION > 16) +// NOTE: We could certainly allow more than 16 bits, but then the data type would need to be adjusted/adjustable, accrodingly. +# error MOZZI_ANALOG_READ_RESOLUTION must be between 1 and 16 bits +# endif +#endif + /// Step 4: Init Read-only defines that depend on other values #if !defined(MOZZI_AUDIO_BIAS) #define MOZZI_AUDIO_BIAS ((uint16_t) 1<<(MOZZI_AUDIO_BITS-1)) diff --git a/internal/config_checks_template.h b/internal/config_checks_template.h index 1e00d2c5e..14e026b78 100644 --- a/internal/config_checks_template.h +++ b/internal/config_checks_template.h @@ -32,11 +32,26 @@ MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_ // MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ) /** NOTE: This should be set to whichever resolution (in bits) mozziAnalogRead() returns values in by default in your implementation. - * mozziAnalogRead() will shift the return value accordingly. + * mozziAnalogRead() will shift the return value accordingly. Generally you will set this to the default hardware resolution for this platform. * - * Generally you will set this to the default hardware resolution for this platform, but of course it's also possible - for instance - - * to set this to the user configurable MOZZI_ANALOG_READ_RESOLUTION (if it has been defined), and configure your ADC reads, accordingly, - * avoiding the extra shift operation. + * @em Optionally, you could to set this to the user configurable MOZZI_ANALOG_READ_RESOLUTION (if it has been defined), and configure your ADC reads, + * accordingly, avoiding the extra shift operation: + * + * @code +#ifdef MOZZI_ANALOG_READ_RESOLUTION +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION MOZZI_ANALOG_READ_RESOLUTION +#define MOZZI__IMPL_SET_ANALOG_READ_RESOLUTION +#else +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 16 +#endif + +[...] + +//inside MozziGuts_impl_MPLATFORM, function setupMozziADC(): +#ifdef MOZZI__IMPL_SET_ANALOG_READ_RESOLUTION +analogReadResolution(MOZZI_ANALOG_READ_RESOLUTION); +#endif + * @endcode */ #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10 From 82237fe0f9c2a82bc3c1d34e3e2a15ba19c6c387 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 28 Mar 2024 10:46:25 +0100 Subject: [PATCH 189/215] Fix more return types --- MozziGuts.h | 4 ++-- internal/MozziGuts.hpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MozziGuts.h b/MozziGuts.h index b18b5fe98..eb3bb9689 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -139,12 +139,12 @@ void audioHook(); /** @ingroup analog See getAudioInput(). The template parameter specifies the desired value range in bits. */ -template int16_t getAudioInput(); +template uint16_t getAudioInput(); /** @ingroup analog See getAudioInput(). Equivalent to getAudioInput<16>(). */ -template inline int16_t getAudioInput16() { return getAudioInput<16>(); } +template inline uint16_t getAudioInput16() { return getAudioInput<16>(); } /** @ingroup analog This returns audio input from the input buffer, if diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 454b38cbd..4e8bcf15c 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -131,20 +131,20 @@ __attribute__((noinline)) void adcStartReadCycle() { } } -int16_t mozziAnalogRead(uint8_t pin) { +uint16_t mozziAnalogRead(uint8_t pin) { pin = adcPinToChannelNum(pin); // allow for channel or pin numbers; on most platforms other than AVR this has no effect. See note on pins/channels adc_channels_to_read.push(pin); return analog_readings[channelNumToIndex(pin)]; } #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) -static AudioOutputStorage_t audio_input; // holds the latest audio from input_buffer -int16_t getAudioInput() { return audio_input; } +static uint16_t audio_input; // holds the latest audio from input_buffer +uint16_t getAudioInput() { return audio_input; } #endif #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // ring buffer for audio input -CircularBuffer input_buffer; // fixed size 256 +CircularBuffer input_buffer; // fixed size 256 #define audioInputAvailable() (!input_buffer.isEmpty()) #define readAudioInput() (input_buffer.read()) /** NOTE: Triggered at MOZZI_AUDIO_RATE via defaultAudioOutput(). In addition to the AUDIO_INPUT_PIN, at most one reading is taken for mozziAnalogRead(). */ From c2f8ace41903d524cd33960aa59606b4509c4687 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 30 Mar 2024 11:21:12 +0100 Subject: [PATCH 190/215] Convert one more instance of analog readings to uint16_t --- internal/MozziGuts.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/MozziGuts.hpp b/internal/MozziGuts.hpp index 3cb0f5858..4b016c053 100644 --- a/internal/MozziGuts.hpp +++ b/internal/MozziGuts.hpp @@ -105,7 +105,7 @@ jRaskell, bobgardner, theusch, Koshchi, and code by jRaskell. #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD) #include "Stack.h" -static volatile int analog_readings[NUM_ANALOG_INPUTS]; +static volatile uint16_t analog_readings[NUM_ANALOG_INPUTS]; static Stack adc_channels_to_read; volatile static int8_t current_channel = -1; // volatile because accessed in control and adc ISRs From 172da016ac39b725fb8612d989a7f5c8afd79557 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Sat, 30 Mar 2024 22:14:43 +0100 Subject: [PATCH 191/215] Fix copy and paste bug As pointed out by poetaster in #241 --- internal/MozziGuts_impl_RP2040.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/MozziGuts_impl_RP2040.hpp b/internal/MozziGuts_impl_RP2040.hpp index e7d34542c..4495796f5 100644 --- a/internal/MozziGuts_impl_RP2040.hpp +++ b/internal/MozziGuts_impl_RP2040.hpp @@ -225,7 +225,7 @@ static void startAudio() { pwm_config_set_wrap(&c, 1l << MOZZI_AUDIO_BITS); // 11 bits output resolution means FCPU / 2048 values per second, which is around 60kHz for 133Mhz clock speed. pwm_init(pwm_gpio_to_slice_num(MOZZI_AUDIO_PIN_1), &c, true); gpio_set_function(MOZZI_AUDIO_PIN_1, GPIO_FUNC_PWM); - gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get + gpio_set_drive_strength(MOZZI_AUDIO_PIN_1, GPIO_DRIVE_STRENGTH_12MA); // highest we can get # if (MOZZI_AUDIO_CHANNELS > 1) # if ((MOZZI_AUDIO_PIN_1 / 2) != (MOZZI_AUDIO_PIN_1 / 2)) # error Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. Adjust MOZZI_AUDIO_PIN_1/2 . From a619093bb895322626e133f0077c5d1f2bb9e8f7 Mon Sep 17 00:00:00 2001 From: Thomas Friedrichsmeier Date: Thu, 28 Mar 2024 20:52:18 +0100 Subject: [PATCH 192/215] Compile twi_nonblock implementation only if the header is included. (Since the file includes an interrupt handler, compiler cannot discard it on its own.) See https://github.com/sensorium/Mozzi/issues/241 --- twi_nonblock.cpp => internal/twi_nonblock.hpp | 7 +++---- twi_nonblock.h | 5 +++++ 2 files changed, 8 insertions(+), 4 deletions(-) rename twi_nonblock.cpp => internal/twi_nonblock.hpp (99%) diff --git a/twi_nonblock.cpp b/internal/twi_nonblock.hpp similarity index 99% rename from twi_nonblock.cpp rename to internal/twi_nonblock.hpp index 084b88cfe..3d38e2d61 100644 --- a/twi_nonblock.cpp +++ b/internal/twi_nonblock.hpp @@ -10,11 +10,11 @@ */ #include "hardware_defines.h" +#if !IS_AVR() +#error Wrong include +#endif // Added by TB2014 for Mozzi library, to hide code from Teensy 3.1 -#if IS_AVR() - -#include "twi_nonblock.h" #include @@ -601,4 +601,3 @@ ISR(TWI_vect) } } -#endif diff --git a/twi_nonblock.h b/twi_nonblock.h index a2c95ce2d..954770f9a 100644 --- a/twi_nonblock.h +++ b/twi_nonblock.h @@ -90,4 +90,9 @@ uint8_t twi_readFromBlocking(uint8_t address, uint8_t* data, uint8_t length); uint8_t twi_writeToBlocking(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait); #endif + +#if !defined _MOZZI_TWI_HEADER_ONLY +#include "internal/twi_nonblock.hpp" +#endif + #endif From 2cf91434b551ae49f2aec9fec167bd4c90fa6a9b Mon Sep 17 00:00:00 2001 From: "mr.sensorium" Date: Thu, 11 Apr 2024 13:21:37 +1000 Subject: [PATCH 193/215] generate docs with doxygen --- ...sics_2_vibrato_2_vibrato_8ino-example.html | 6 +- ..._control__echo__theremin_8ino-example.html | 6 +- ...emelo_2_control__tremelo_8ino-example.html | 6 +- ...vent_delay_2_event_delay_8ino-example.html | 6 +- ...etronome__sample_huffman_8ino-example.html | 6 +- ...b__l_d_r_x2__wave_packet_8ino-example.html | 8 +- ..._d_c_filter_2_d_c_filter_8ino-example.html | 6 +- ...ilters_2_smooth_2_smooth_8ino-example.html | 6 +- ..._s_b__m_i_d_i_portamento_8ino-example.html | 4 +- ..._thermistor__over_sample_8ino-example.html | 8 +- ..._2_non_alias__meta_oscil_8ino-example.html | 6 +- ...phasing_2_p_w_m__phasing_8ino-example.html | 6 +- ...ave_packet_2_wave_packet_8ino-example.html | 4 +- ...le_2_wave_packet__sample_8ino-example.html | 6 +- ...ave_shaper_2_wave_shaper_8ino-example.html | 6 +- ...lope_2_a_d_s_r__envelope_8ino-example.html | 4 +- ...envelope_2_ead__envelope_8ino-example.html | 6 +- ...amples_2_sample_2_sample_8ino-example.html | 6 +- ..._2_sample_huffman__umpah_8ino-example.html | 6 +- ...udio_delay_2_audio_delay_8ino-example.html | 6 +- ...k_2_audio_delay_feedback_8ino-example.html | 6 +- ...rb_tank__s_t_a_n_d_a_r_d_8ino-example.html | 6 +- ..._2_multi_resonant_filter_8ino-example.html | 6 +- ...er16_2_resonant_filter16_8ino-example.html | 6 +- ...filter_2_resonant_filter_8ino-example.html | 6 +- ..._2_state_variable_filter_8ino-example.html | 4 +- extras/doc/html/_a_d_s_r_8h_source.html | 56 +- extras/doc/html/_audio_delay_8h_source.html | 6 +- .../html/_audio_delay_feedback_8h_source.html | 30 +- extras/doc/html/_audio_output_8h_source.html | 51 +- extras/doc/html/_auto_map_8h_source.html | 18 +- extras/doc/html/_auto_range_8h_source.html | 16 +- extras/doc/html/_cap_poll_8h_source.html | 4 +- .../doc/html/_circular_buffer_8h_source.html | 9 +- extras/doc/html/_control_delay_8h_source.html | 4 +- extras/doc/html/_d_cfilter_8h_source.html | 4 +- extras/doc/html/_ead_8h_source.html | 14 +- extras/doc/html/_event_delay_8h_source.html | 6 +- extras/doc/html/_int_map_8h_source.html | 4 +- extras/doc/html/_integer_type_8h_source.html | 6 +- extras/doc/html/_line_8h_source.html | 46 +- .../doc/html/_low_pass_filter_8h_source.html | 4 +- extras/doc/html/_meta_oscil_8h_source.html | 46 +- extras/doc/html/_metronome_8h_source.html | 4 +- extras/doc/html/_mozzi_8h.html | 130 ++ extras/doc/html/_mozzi_8h_source.html | 118 ++ .../html/_mozzi_config_values_8h_source.html | 118 ++ extras/doc/html/_mozzi_guts_8h_source.html | 44 +- extras/doc/html/_mozzi_guts_8hpp_source.html | 137 +++ ..._mozzi_guts__impl___a_v_r_8hpp_source.html | 12 +- ...ozzi_guts__impl___e_s_p32_8hpp_source.html | 16 +- ...zi_guts__impl___e_s_p8266_8hpp_source.html | 14 +- ...ozzi_guts__impl___m_b_e_d_8hpp_source.html | 118 ++ ...uts__impl___r_e_n_e_s_a_s_8hpp_source.html | 119 ++ ...l___r_e_n_e_s_a_s___a_d_c_8hpp_source.html | 119 ++ ...l___r_e_n_e_s_a_s__analog_8hpp_source.html | 118 ++ ...ozzi_guts__impl___r_p2040_8hpp_source.html | 9 +- ...ozzi_guts__impl___s_a_m_d_8hpp_source.html | 11 +- ...ozzi_guts__impl___s_t_m32_8hpp_source.html | 13 +- ...guts__impl___s_t_m32duino_8hpp_source.html | 120 ++ ...pl___s_t_m32duino__analog_8hpp_source.html | 119 ++ ..._guts__impl___t_e_e_n_s_y_8hpp_source.html | 14 +- ...ozzi_guts__impl__template_8hpp_source.html | 9 +- extras/doc/html/_mozzi_headers_only_8h.html | 132 ++ .../html/_mozzi_headers_only_8h_source.html | 118 ++ extras/doc/html/_oscil_8h_source.html | 46 +- extras/doc/html/_over_sample_8h_source.html | 9 +- extras/doc/html/_p_d_resonant_8h_source.html | 10 +- extras/doc/html/_phasor_8h_source.html | 22 +- extras/doc/html/_portamento_8h_source.html | 10 +- extras/doc/html/_r_cpoll_8h_source.html | 4 +- .../doc/html/_resonant_filter_8h_source.html | 12 +- extras/doc/html/_reverb_tank_8h_source.html | 4 +- .../doc/html/_rolling_average_8h_source.html | 9 +- extras/doc/html/_rolling_stat_8h_source.html | 19 +- extras/doc/html/_sample_8h_source.html | 8 +- .../doc/html/_sample_huffman_8h_source.html | 4 +- ..._skeleton___multi___unit2_8cpp_source.html | 119 ++ extras/doc/html/_smooth_8h_source.html | 10 +- extras/doc/html/_stack_8h_source.html | 4 +- .../doc/html/_state_variable_8h_source.html | 13 +- extras/doc/html/_wave_folder_8h_source.html | 10 +- extras/doc/html/_wave_packet_8h_source.html | 24 +- .../html/_wave_packet_sample_8h_source.html | 8 +- extras/doc/html/_wave_shaper_8h_source.html | 4 +- extras/doc/html/audio2huff_8py_source.html | 6 +- .../doc/html/blahblah4b__int8_8h_source.html | 6 +- extras/doc/html/char2mozzi_8py.html | 24 +- extras/doc/html/char2mozzi_8py_source.html | 6 +- .../doc/html/chebyshev__int8_8py_source.html | 6 +- extras/doc/html/class_a_d_s_r-members.html | 4 +- extras/doc/html/class_a_d_s_r.html | 90 +- .../doc/html/class_audio_delay-members.html | 4 +- extras/doc/html/class_audio_delay.html | 38 +- .../class_audio_delay_feedback-members.html | 4 +- .../doc/html/class_audio_delay_feedback.html | 74 +- extras/doc/html/class_cap_poll-members.html | 4 +- extras/doc/html/class_cap_poll.html | 28 +- .../html/class_circular_buffer-members.html | 17 +- extras/doc/html/class_circular_buffer.html | 37 +- .../doc/html/class_control_delay-members.html | 4 +- extras/doc/html/class_control_delay.html | 38 +- extras/doc/html/class_d_cfilter-members.html | 4 +- extras/doc/html/class_d_cfilter.html | 20 +- extras/doc/html/class_ead-members.html | 4 +- extras/doc/html/class_ead.html | 20 +- .../doc/html/class_event_delay-members.html | 4 +- extras/doc/html/class_event_delay.html | 24 +- extras/doc/html/class_int_map-members.html | 4 +- extras/doc/html/class_int_map.html | 18 +- extras/doc/html/class_line-members.html | 4 +- extras/doc/html/class_line.html | 46 +- ...line_3_01unsigned_01char_01_4-members.html | 4 +- .../class_line_3_01unsigned_01char_01_4.html | 30 +- ..._line_3_01unsigned_01int_01_4-members.html | 4 +- .../class_line_3_01unsigned_01int_01_4.html | 30 +- ...line_3_01unsigned_01long_01_4-members.html | 4 +- .../class_line_3_01unsigned_01long_01_4.html | 30 +- extras/doc/html/class_meta_oscil-members.html | 4 +- extras/doc/html/class_meta_oscil.html | 58 +- extras/doc/html/class_metronome-members.html | 4 +- extras/doc/html/class_metronome.html | 24 +- .../class_midi_to_freq_private-members.html | 123 ++ .../doc/html/class_midi_to_freq_private.html | 250 ++++ ...rivate_1_1_mozzi_rand_private-members.html | 125 ++ ..._mozzi_private_1_1_mozzi_rand_private.html | 245 ++++ .../class_multi_resonant_filter-members.html | 4 +- .../doc/html/class_multi_resonant_filter.html | 36 +- extras/doc/html/class_oscil-members.html | 18 +- extras/doc/html/class_oscil.html | 406 +++++-- .../doc/html/class_p_d_resonant-members.html | 4 +- extras/doc/html/class_p_d_resonant.html | 20 +- extras/doc/html/class_phasor-members.html | 4 +- extras/doc/html/class_phasor.html | 50 +- extras/doc/html/class_portamento-members.html | 4 +- extras/doc/html/class_portamento.html | 22 +- extras/doc/html/class_r_cpoll-members.html | 4 +- extras/doc/html/class_r_cpoll.html | 28 +- .../html/class_resonant_filter-members.html | 4 +- extras/doc/html/class_resonant_filter.html | 40 +- .../doc/html/class_reverb_tank-members.html | 4 +- extras/doc/html/class_reverb_tank.html | 24 +- extras/doc/html/class_sample-members.html | 4 +- extras/doc/html/class_sample.html | 42 +- .../html/class_sample_huffman-members.html | 4 +- extras/doc/html/class_sample_huffman.html | 32 +- extras/doc/html/class_smooth-members.html | 4 +- extras/doc/html/class_smooth.html | 36 +- extras/doc/html/class_stack-members.html | 4 +- extras/doc/html/class_stack.html | 34 +- .../html/class_state_variable-members.html | 4 +- extras/doc/html/class_state_variable.html | 42 +- .../doc/html/class_wave_folder-members.html | 4 +- extras/doc/html/class_wave_folder.html | 22 +- .../doc/html/class_wave_packet-members.html | 4 +- extras/doc/html/class_wave_packet.html | 36 +- .../class_wave_packet_sample-members.html | 4 +- extras/doc/html/class_wave_packet_sample.html | 34 +- extras/doc/html/class_wave_shaper.html | 4 +- ...ass_wave_shaper_3_01char_01_4-members.html | 4 +- .../html/class_wave_shaper_3_01char_01_4.html | 22 +- ...lass_wave_shaper_3_01int_01_4-members.html | 4 +- .../html/class_wave_shaper_3_01int_01_4.html | 24 +- .../html/config__checks__avr_8h_source.html | 120 ++ .../html/config__checks__esp32_8h_source.html | 120 ++ .../config__checks__esp8266_8h_source.html | 120 ++ .../config__checks__generic_8h_source.html | 153 +++ .../html/config__checks__mbed_8h_source.html | 120 ++ .../config__checks__renesas_8h_source.html | 120 ++ .../config__checks__rp2040_8h_source.html | 120 ++ .../config__checks__samd21_8h_source.html | 120 ++ .../config__checks__stm32duino_8h_source.html | 119 ++ .../config__checks__stm32maple_8h_source.html | 119 ++ .../config__checks__teensy_8h_source.html | 119 ++ .../config__checks__template_8h_source.html | 119 ++ .../config__example__avr__hifi_8h_source.html | 119 ++ ...avr__legacy__standard__mode_8h_source.html | 118 ++ ..._legacy__standardplus__mode_8h_source.html | 118 ++ ...onfig__example__avr__stereo_8h_source.html | 119 ++ .../config__example__external_8h_source.html | 119 ++ ...__rp2040__i2s__pt8211__mono_8h_source.html | 121 ++ ...onfig__example__rp2040__pwm_8h_source.html | 118 ++ .../dir_0d6feda837323b0c7a50b1cca0a6cf12.html | 4 +- .../dir_3faa5fff9e46bf8b8f48c87f683ce0e6.html | 4 +- .../dir_7374381ecdb819c64ee9b6ea2bd3370d.html | 118 ++ .../dir_91ea62b43b2ac03ee8b1ec98abec0fd0.html | 118 ++ .../dir_972072f1ab172f7c6da94578c90fb35b.html | 122 ++ .../dir_9ca29615486e86932f4b900563144736.html | 4 +- .../dir_9f351d46ce3cc29445a41dc3a31e6919.html | 10 +- .../dir_d28a4824dc47e487b107a5db32ef43c4.html | 4 +- .../dir_da40a2d191134d083f9bacf4a8879a55.html | 4 +- .../dir_dd81b9de5c9027a54e49f977944ecdc1.html | 4 +- .../dir_ed9afb3abf3b1f94fbd9a8bdbdfef2ae.html | 4 +- .../dir_fc249940a2785800fd142bbf8a5801d3.html | 4 +- ...nmode__on__github__workflow_8h_source.html | 118 ++ ...tereo__on__github__workflow_8h_source.html | 118 ++ extras/doc/html/float2mozzi_8py_source.html | 6 +- .../html/float2mozzi__uint8_8py_source.html | 6 +- extras/doc/html/group__analog.html | 69 +- extras/doc/html/group__audio__output.html | 137 +++ extras/doc/html/group__audio__output.js | 5 + ...put_mozzi_audio_output_architecture_dup.js | 6 + extras/doc/html/group__config.html | 441 +++++++ extras/doc/html/group__config.js | 16 + .../doc/html/group__config_config_main_dup.js | 6 + extras/doc/html/group__core.html | 442 ++----- extras/doc/html/group__core.js | 18 +- extras/doc/html/group__fixmath.html | 192 +-- extras/doc/html/group__hardware.html | 470 +++++++ extras/doc/html/group__hardware.js | 15 + .../html/group__hardware_hardware_avr_dup.js | 14 + .../group__hardware_hardware_esp32_dup.js | 16 + .../group__hardware_hardware_esp8266_dup.js | 14 + .../html/group__hardware_hardware_mbed_dup.js | 14 + .../group__hardware_hardware_renesas_dup.js | 12 + .../group__hardware_hardware_rp2040_dup.js | 14 + .../html/group__hardware_hardware_samd_dup.js | 6 + ...roup__hardware_hardware_stm32_maple_dup.js | 14 + ...group__hardware_hardware_stm32duino_dup.js | 12 + .../group__hardware_hardware_teensy3_dup.js | 12 + .../group__hardware_hardware_teensy4_dup.js | 10 + extras/doc/html/group__midi.html | 58 +- extras/doc/html/group__random.html | 349 ++++-- extras/doc/html/group__random.js | 12 +- extras/doc/html/group__sensortools.html | 1079 +++++++++++++++++ extras/doc/html/group__sensortools.js | 35 + extras/doc/html/group__sensortools.png | Bin 0 -> 1272 bytes extras/doc/html/group__soundtables.html | 4 +- extras/doc/html/group__util.html | 120 +- extras/doc/html/group__util.js | 8 +- .../doc/html/hardware__defines_8h_source.html | 21 +- extras/doc/html/index.html | 13 +- .../html/known__16bit__timers_8h_source.html | 4 +- extras/doc/html/meta_8h_source.html | 6 +- extras/doc/html/modules.html | 22 +- extras/doc/html/modules.js | 14 +- extras/doc/html/mozzi__analog_8h_source.html | 17 +- .../html/mozzi__config__documentation_8h.html | 162 +++ ...ozzi__config__documentation_8h_source.html | 118 ++ .../doc/html/mozzi__fixmath_8cpp_source.html | 10 +- extras/doc/html/mozzi__fixmath_8h_source.html | 188 +-- extras/doc/html/mozzi__macros_8h_source.html | 123 ++ extras/doc/html/mozzi__midi_8h_source.html | 14 +- .../doc/html/mozzi__pgmspace_8h_source.html | 13 +- extras/doc/html/mozzi__rand_8h_source.html | 21 +- extras/doc/html/mozzi__rand__p_8h_source.html | 121 ++ extras/doc/html/mozzi__utils_8h_source.html | 10 +- extras/doc/html/mult16x16_8h_source.html | 4 +- extras/doc/html/mult16x8_8h_source.html | 4 +- extras/doc/html/mult32x16_8h_source.html | 4 +- extras/doc/html/namespace_mozzi_private.html | 227 ++++ extras/doc/html/namespacemembers.html | 133 ++ extras/doc/html/namespacemembers_func.html | 133 ++ extras/doc/html/navtreedata.js | 21 +- extras/doc/html/navtreeindex0.js | 500 ++++---- extras/doc/html/navtreeindex1.js | 324 ++--- extras/doc/html/primes_8h_source.html | 6 +- extras/doc/html/search/all_0.js | 26 +- extras/doc/html/search/all_1.js | 2 +- extras/doc/html/search/all_10.js | 13 +- extras/doc/html/search/all_11.js | 8 +- extras/doc/html/search/all_12.js | 13 +- extras/doc/html/search/all_13.js | 10 +- extras/doc/html/search/all_14.html | 30 + extras/doc/html/search/all_14.js | 5 + extras/doc/html/search/all_2.js | 6 +- extras/doc/html/search/all_3.js | 2 +- extras/doc/html/search/all_4.js | 2 +- extras/doc/html/search/all_5.js | 12 +- extras/doc/html/search/all_6.js | 16 +- extras/doc/html/search/all_7.js | 1 + extras/doc/html/search/all_8.js | 6 +- extras/doc/html/search/all_a.js | 42 +- extras/doc/html/search/all_b.js | 2 +- extras/doc/html/search/all_c.js | 12 +- extras/doc/html/search/all_d.js | 9 +- extras/doc/html/search/all_e.js | 2 +- extras/doc/html/search/all_f.js | 14 +- extras/doc/html/search/classes_0.js | 10 +- extras/doc/html/search/classes_4.js | 6 +- extras/doc/html/search/classes_6.js | 2 + extras/doc/html/search/classes_7.js | 8 +- extras/doc/html/search/classes_8.js | 2 +- extras/doc/html/search/classes_9.js | 6 +- extras/doc/html/search/files_1.html | 30 + extras/doc/html/search/files_1.js | 6 + extras/doc/html/search/functions_0.js | 12 +- extras/doc/html/search/functions_1.js | 3 +- extras/doc/html/search/functions_10.js | 11 +- extras/doc/html/search/functions_11.js | 7 +- extras/doc/html/search/functions_12.js | 10 +- extras/doc/html/search/functions_13.js | 7 +- extras/doc/html/search/functions_14.html | 30 + extras/doc/html/search/functions_14.js | 5 + extras/doc/html/search/functions_2.js | 2 +- extras/doc/html/search/functions_3.js | 2 +- extras/doc/html/search/functions_5.js | 9 +- extras/doc/html/search/functions_6.js | 16 +- extras/doc/html/search/functions_a.js | 9 +- extras/doc/html/search/functions_b.js | 2 +- extras/doc/html/search/functions_c.js | 4 +- extras/doc/html/search/functions_d.js | 7 +- extras/doc/html/search/functions_e.js | 2 +- extras/doc/html/search/functions_f.js | 12 +- extras/doc/html/search/groups_0.js | 4 +- extras/doc/html/search/groups_1.js | 3 +- extras/doc/html/search/groups_2.js | 2 +- extras/doc/html/search/groups_3.js | 2 + extras/doc/html/search/namespaces_0.html | 30 + extras/doc/html/search/namespaces_0.js | 4 + extras/doc/html/search/pages_0.html | 30 + extras/doc/html/search/pages_0.js | 4 + extras/doc/html/search/pages_1.html | 30 + extras/doc/html/search/pages_1.js | 4 + extras/doc/html/search/pages_2.html | 30 + extras/doc/html/search/pages_2.js | 16 + extras/doc/html/search/related_0.html | 30 + extras/doc/html/search/related_0.js | 4 + extras/doc/html/search/related_1.html | 30 + extras/doc/html/search/related_1.js | 4 + extras/doc/html/search/related_2.html | 30 + extras/doc/html/search/related_2.js | 4 + extras/doc/html/search/related_3.html | 30 + extras/doc/html/search/related_3.js | 4 + extras/doc/html/search/searchdata.js | 35 +- extras/doc/html/sin1024__int8_8py_source.html | 6 +- .../doc/html/sin8192__uint8_8py_source.html | 6 +- .../sin__multi__levels__int8_8py_source.html | 6 +- ...truct_integer_type_3_011_01_4-members.html | 4 +- .../html/struct_integer_type_3_011_01_4.html | 20 +- ...truct_integer_type_3_012_01_4-members.html | 4 +- .../html/struct_integer_type_3_012_01_4.html | 20 +- ...truct_integer_type_3_014_01_4-members.html | 4 +- .../html/struct_integer_type_3_014_01_4.html | 20 +- ...truct_integer_type_3_018_01_4-members.html | 4 +- .../html/struct_integer_type_3_018_01_4.html | 20 +- .../doc/html/struct_mono_output-members.html | 13 +- extras/doc/html/struct_mono_output.html | 134 +- .../html/struct_stereo_output-members.html | 12 +- extras/doc/html/struct_stereo_output.html | 227 +--- ...table__generator__template_8py_source.html | 6 +- extras/doc/html/teensy_pin_map_8h_source.html | 8 +- .../html/triangle512__uint8_8h_source.html | 6 +- extras/doc/html/triangle_8py_source.html | 6 +- .../doc/html/twi__nonblock_8cpp_source.html | 4 +- extras/doc/html/twi__nonblock_8h_source.html | 4 +- extras/doc/html/umpah__huff_8h_source.html | 6 +- extras/doxygen-style/Doxyfile | 116 +- 348 files changed, 12085 insertions(+), 3106 deletions(-) create mode 100644 extras/doc/html/_mozzi_8h.html create mode 100644 extras/doc/html/_mozzi_8h_source.html create mode 100644 extras/doc/html/_mozzi_config_values_8h_source.html create mode 100644 extras/doc/html/_mozzi_guts_8hpp_source.html create mode 100644 extras/doc/html/_mozzi_guts__impl___m_b_e_d_8hpp_source.html create mode 100644 extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s_8hpp_source.html create mode 100644 extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s___a_d_c_8hpp_source.html create mode 100644 extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s__analog_8hpp_source.html create mode 100644 extras/doc/html/_mozzi_guts__impl___s_t_m32duino_8hpp_source.html create mode 100644 extras/doc/html/_mozzi_guts__impl___s_t_m32duino__analog_8hpp_source.html create mode 100644 extras/doc/html/_mozzi_headers_only_8h.html create mode 100644 extras/doc/html/_mozzi_headers_only_8h_source.html create mode 100644 extras/doc/html/_skeleton___multi___unit2_8cpp_source.html create mode 100644 extras/doc/html/class_midi_to_freq_private-members.html create mode 100644 extras/doc/html/class_midi_to_freq_private.html create mode 100644 extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private-members.html create mode 100644 extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private.html create mode 100644 extras/doc/html/config__checks__avr_8h_source.html create mode 100644 extras/doc/html/config__checks__esp32_8h_source.html create mode 100644 extras/doc/html/config__checks__esp8266_8h_source.html create mode 100644 extras/doc/html/config__checks__generic_8h_source.html create mode 100644 extras/doc/html/config__checks__mbed_8h_source.html create mode 100644 extras/doc/html/config__checks__renesas_8h_source.html create mode 100644 extras/doc/html/config__checks__rp2040_8h_source.html create mode 100644 extras/doc/html/config__checks__samd21_8h_source.html create mode 100644 extras/doc/html/config__checks__stm32duino_8h_source.html create mode 100644 extras/doc/html/config__checks__stm32maple_8h_source.html create mode 100644 extras/doc/html/config__checks__teensy_8h_source.html create mode 100644 extras/doc/html/config__checks__template_8h_source.html create mode 100644 extras/doc/html/config__example__avr__hifi_8h_source.html create mode 100644 extras/doc/html/config__example__avr__legacy__standard__mode_8h_source.html create mode 100644 extras/doc/html/config__example__avr__legacy__standardplus__mode_8h_source.html create mode 100644 extras/doc/html/config__example__avr__stereo_8h_source.html create mode 100644 extras/doc/html/config__example__external_8h_source.html create mode 100644 extras/doc/html/config__example__rp2040__i2s__pt8211__mono_8h_source.html create mode 100644 extras/doc/html/config__example__rp2040__pwm_8h_source.html create mode 100644 extras/doc/html/dir_7374381ecdb819c64ee9b6ea2bd3370d.html create mode 100644 extras/doc/html/dir_91ea62b43b2ac03ee8b1ec98abec0fd0.html create mode 100644 extras/doc/html/dir_972072f1ab172f7c6da94578c90fb35b.html create mode 100644 extras/doc/html/disable__2pinmode__on__github__workflow_8h_source.html create mode 100644 extras/doc/html/disable__stereo__on__github__workflow_8h_source.html create mode 100644 extras/doc/html/group__audio__output.html create mode 100644 extras/doc/html/group__audio__output.js create mode 100644 extras/doc/html/group__audio__output_mozzi_audio_output_architecture_dup.js create mode 100644 extras/doc/html/group__config.html create mode 100644 extras/doc/html/group__config.js create mode 100644 extras/doc/html/group__config_config_main_dup.js create mode 100644 extras/doc/html/group__hardware.html create mode 100644 extras/doc/html/group__hardware.js create mode 100644 extras/doc/html/group__hardware_hardware_avr_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_esp32_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_esp8266_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_mbed_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_renesas_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_rp2040_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_samd_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_stm32_maple_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_stm32duino_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_teensy3_dup.js create mode 100644 extras/doc/html/group__hardware_hardware_teensy4_dup.js create mode 100644 extras/doc/html/group__sensortools.html create mode 100644 extras/doc/html/group__sensortools.js create mode 100644 extras/doc/html/group__sensortools.png create mode 100644 extras/doc/html/mozzi__config__documentation_8h.html create mode 100644 extras/doc/html/mozzi__config__documentation_8h_source.html create mode 100644 extras/doc/html/mozzi__macros_8h_source.html create mode 100644 extras/doc/html/mozzi__rand__p_8h_source.html create mode 100644 extras/doc/html/namespace_mozzi_private.html create mode 100644 extras/doc/html/namespacemembers.html create mode 100644 extras/doc/html/namespacemembers_func.html create mode 100644 extras/doc/html/search/all_14.html create mode 100644 extras/doc/html/search/all_14.js create mode 100644 extras/doc/html/search/files_1.html create mode 100644 extras/doc/html/search/files_1.js create mode 100644 extras/doc/html/search/functions_14.html create mode 100644 extras/doc/html/search/functions_14.js create mode 100644 extras/doc/html/search/namespaces_0.html create mode 100644 extras/doc/html/search/namespaces_0.js create mode 100644 extras/doc/html/search/pages_0.html create mode 100644 extras/doc/html/search/pages_0.js create mode 100644 extras/doc/html/search/pages_1.html create mode 100644 extras/doc/html/search/pages_1.js create mode 100644 extras/doc/html/search/pages_2.html create mode 100644 extras/doc/html/search/pages_2.js create mode 100644 extras/doc/html/search/related_0.html create mode 100644 extras/doc/html/search/related_0.js create mode 100644 extras/doc/html/search/related_1.html create mode 100644 extras/doc/html/search/related_1.js create mode 100644 extras/doc/html/search/related_2.html create mode 100644 extras/doc/html/search/related_2.js create mode 100644 extras/doc/html/search/related_3.html create mode 100644 extras/doc/html/search/related_3.js diff --git a/extras/doc/html/01_8_basics_2_vibrato_2_vibrato_8ino-example.html b/extras/doc/html/01_8_basics_2_vibrato_2_vibrato_8ino-example.html index a6760f9aa..6b5cfbae3 100644 --- a/extras/doc/html/01_8_basics_2_vibrato_2_vibrato_8ino-example.html +++ b/extras/doc/html/01_8_basics_2_vibrato_2_vibrato_8ino-example.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -105,12 +105,12 @@


This is an example using Oscil::phMod to produce vibrato using phase modulation.

-
/* Example playing a sinewave with vibrato,
using Mozzi sonification library.
Demonstrates simple FM using phase modulation.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h> // for mtof
#include <mozzi_fixmath.h>
#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aCos(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aVibrato(COS2048_DATA);
const byte intensity = 255;
void setup(){
startMozzi(CONTROL_RATE);
aCos.setFreq(mtof(84.f));
aVibrato.setFreq(15.f);
}
void updateControl(){
}
AudioOutput_t updateAudio(){
Q15n16 vibrato = (Q15n16) intensity * aVibrato.next();
return MonoOutput::from8Bit(aCos.phMod(vibrato)); // phase modulation to modulate frequency
}
void loop(){
audioHook();
}
+
/* Example playing a sinewave with vibrato,
using Mozzi sonification library.
Demonstrates simple FM using phase modulation.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h> // for mtof
//#include <mozzi_fixmath.h>
#include <FixMath.h> // Fixed point arithmetics
Oscil<COS2048_NUM_CELLS, MOZZI_AUDIO_RATE> aCos(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_AUDIO_RATE> aVibrato(COS2048_DATA);
//const byte intensity = 255;
const UFix<0,8> intensity = 0.5; // amplitude of the phase modulation
// 0.5 leads to a modulation of half the
// wavetable
void setup(){
startMozzi();
aCos.setFreq(mtof(84.f));
aVibrato.setFreq(15.f);
}
void updateControl(){
}
AudioOutput updateAudio(){
//Q15n16 vibrato = (Q15n16) intensity * aVibrato.next();
auto vibrato = intensity * toSFraction(aVibrato.next()); // Oscils in Mozzi are 8bits: 7bits of signal plus one bit of sign, so what they fit into a SFixMath<0,7> which is a signed fixMath type with 7 bits of value.
return MonoOutput::from8Bit(aCos.phMod(vibrato)); // phase modulation to modulate frequency
}
void loop(){
audioHook();
}


- This example demonstrates the AutoMap class.

-
/*
Example of Wavepacket synthesis, using analog
inputs to change the fundamental frequency,
bandwidth and centre frequency,
using Mozzi sonification library.
Demonstrates WavePacket, mozziAnalogRead(), and smoothing
control signals with RollingAverage.
Also demonstrates AutoMap, which maps unpredictable inputs to a set range.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#include <WavePacket.h>
#include <RollingAverage.h>
#include <AutoMap.h>
#include <IntMap.h>
const int KNOB_PIN = 0; // set the input for the knob to analog pin 0
const int LDR1_PIN=1; // set the analog input for fm_intensity to pin 1
const int LDR2_PIN=2; // set the analog input for mod rate to pin 2
// min and max values of synth parameters to map AutoRanged analog inputs to
const int MIN_F = 20;
const int MAX_F = 150;
const int MIN_BW = 20;
const int MAX_BW = 600;
const int MIN_CF = 60;
const int MAX_CF = 600;
// for smoothing the control signals
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage <int, 16> kAverageF;
RollingAverage <int, 16> kAverageBw;
RollingAverage <int, 16> kAverageCf;
// Intmap is a pre-calculated faster version of Arduino's map, OK for pots
IntMap kMapF(0,1023,MIN_F,MAX_F);
// AutoMap adapts to range of input as it arrives, useful for LDR's
AutoMap kMapBw(0,1023,MIN_BW,MAX_BW);
AutoMap kMapCf(0,1023,MIN_CF,MAX_CF);
WavePacket <DOUBLE> wavey; // DOUBLE selects 2 overlapping streams
void setup(){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial.begin(115200);
// wait before starting Mozzi to receive analog reads, so AutoRange will not get 0
delay(200);
startMozzi();
}
void updateControl(){
int fundamental = mozziAnalogRead(KNOB_PIN)+1;
fundamental = kMapF(fundamental);
Serial.print("f=");
Serial.print(fundamental);
int bandwidth = mozziAnalogRead(LDR1_PIN);
bandwidth = kMapBw(bandwidth);
Serial.print("\t bw=");
Serial.print(bandwidth);
int centre_freq = mozziAnalogRead(LDR2_PIN);
centre_freq = kMapCf(centre_freq);
Serial.print("\t cf=");
Serial.print(centre_freq);
Serial.println();
wavey.set(fundamental, bandwidth, centre_freq);
}
AudioOutput_t updateAudio(){
return MonoOutput::from16Bit(wavey.next());
}
void loop(){
audioHook(); // required here
}
+ This example demonstrates the AutoMap class.

+
/*
Example of Wavepacket synthesis, using analog
inputs to change the fundamental frequency,
bandwidth and centre frequency,
using Mozzi sonification library.
Demonstrates WavePacket, mozziAnalogRead(), and smoothing
control signals with RollingAverage.
Also demonstrates AutoMap, which maps unpredictable inputs to a set range.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#include <WavePacket.h>
#include <RollingAverage.h>
#include <AutoMap.h>
#include <IntMap.h>
const int KNOB_PIN = 0; // set the input for the knob to analog pin 0
const int LDR1_PIN=1; // set the analog input for fm_intensity to pin 1
const int LDR2_PIN=2; // set the analog input for mod rate to pin 2
// min and max values of synth parameters to map AutoRanged analog inputs to
const int MIN_F = 20;
const int MAX_F = 150;
const int MIN_BW = 20;
const int MAX_BW = 600;
const int MIN_CF = 60;
const int MAX_CF = 600;
// for smoothing the control signals
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage <int, 16> kAverageF;
RollingAverage <int, 16> kAverageBw;
RollingAverage <int, 16> kAverageCf;
// Intmap is a pre-calculated faster version of Arduino's map, OK for pots
IntMap kMapF(0,1023,MIN_F,MAX_F);
// AutoMap adapts to range of input as it arrives, useful for LDR's
AutoMap kMapBw(0,1023,MIN_BW,MAX_BW);
AutoMap kMapCf(0,1023,MIN_CF,MAX_CF);
WavePacket <DOUBLE> wavey; // DOUBLE selects 2 overlapping streams
void setup(){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial.begin(115200);
// wait before starting Mozzi to receive analog reads, so AutoRange will not get 0
delay(200);
startMozzi();
}
void updateControl(){
int fundamental = mozziAnalogRead(KNOB_PIN)+1;
fundamental = kMapF(fundamental);
Serial.print("f=");
Serial.print(fundamental);
int bandwidth = mozziAnalogRead(LDR1_PIN);
bandwidth = kMapBw(bandwidth);
Serial.print("\t bw=");
Serial.print(bandwidth);
int centre_freq = mozziAnalogRead(LDR2_PIN);
centre_freq = kMapCf(centre_freq);
Serial.print("\t cf=");
Serial.print(centre_freq);
Serial.println();
wavey.set(fundamental, bandwidth, centre_freq);
}
AudioOutput updateAudio(){
return MonoOutput::from16Bit(wavey.next());
}
void loop(){
audioHook(); // required here
}

This is an example of how to use the WaveShaper class.

-
/* Example using waveshaping to modify the spectrum of an audio signal
using Mozzi sonification library.
Demonstrates the use of WaveShaper(), EventDelay(), Smooth(),
rand(), and fixed-point numbers.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <MozziGuts.h>
#include <Oscil.h>
#include <WaveShaper.h>
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <Smooth.h>
#include <tables/sin2048_int8.h>
#include <tables/waveshape_chebyshev_3rd_256_int8.h>
#include <tables/waveshape_chebyshev_6th_256_int8.h>
#include <tables/waveshape_compress_512_to_488_int16.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA); // sine wave sound source
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aGain1(SIN2048_DATA); // to fade sine wave in and out before waveshaping
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aGain2(SIN2048_DATA); // to fade sine wave in and out before waveshaping
// Chebyshev polynomial curves, The nth curve produces the n+2th harmonic component.
WaveShaper <char> aCheby3rd(CHEBYSHEV_3RD_256_DATA); // 5th harmonic
WaveShaper <char> aCheby6th(CHEBYSHEV_6TH_256_DATA); // 8th harmonic
WaveShaper <int> aCompress(WAVESHAPE_COMPRESS_512_TO_488_DATA); // to compress instead of dividing by 2 after adding signals
// for scheduling note changes
EventDelay kChangeNoteDelay;
// for random notes
Q8n0 octave_start_note = 42;
Q24n8 carrier_freq; // unsigned long with 24 integer bits and 8 fractional bits
// smooth transitions between notes
Smooth <unsigned int> kSmoothFreq(0.85f);
int target_freq, smoothed_freq;
void setup(){
startMozzi(); // :)
randSeed(); // reseed the random generator for different results each time the sketch runs
aSin.setFreq(110); // set the frequency
aGain1.setFreq(2.f); // use a float for low frequencies, in setup it doesn't need to be fast
aGain2.setFreq(.4f);
kChangeNoteDelay.set(4000); // note duration ms, within resolution of CONTROL_RATE
}
byte rndPentatonic(){
byte note = rand((byte)5);
switch(note){
case 0:
note = 0;
break;
case 1:
note = 3;
break;
case 2:
note = 5;
break;
case 3:
note = 7;
break;
case 4:
note = 10;
break;
}
return note;
}
void updateControl(){
if(kChangeNoteDelay.ready()){
if(rand((byte)5)==0){ // about 1 in 5 or so
// change octave to midi 24 or any of 3 octaves above
octave_start_note = (rand((byte)4)*12)+36;
}
Q16n16 midi_note = Q8n0_to_Q16n16(octave_start_note+rndPentatonic());
target_freq = Q16n16_to_Q16n0(Q16n16_mtof(midi_note)); // has to be 16 bits for Smooth
kChangeNoteDelay.start();
}
smoothed_freq = kSmoothFreq.next(target_freq*4); // temporarily scale up target_freq to get better int smoothing at low values
aSin.setFreq(smoothed_freq/4); // then scale it back down after it's smoothed
}
AudioOutput_t updateAudio(){
char asig0 = aSin.next(); // sine wave source
// make 2 signals fading in and out to show effect of amplitude when waveshaping with Chebyshev polynomial curves
// offset the signals by 128 to fit in the 0-255 range for the waveshaping table lookups
byte asig1 = (byte)128+((asig0*((byte)128+aGain1.next()))>>8);
byte asig2 = (byte)128+((asig0*((byte)128+aGain2.next()))>>8);
// get the waveshaped signals
char awaveshaped1 = aCheby3rd.next(asig1);
char awaveshaped2 = aCheby6th.next(asig2);
// use a waveshaping table to squeeze 2 summed 8 bit signals into the range -244 to 243
int awaveshaped3 = aCompress.next(256u + awaveshaped1 + awaveshaped2);
return MonoOutput::fromAlmostNBit(9, awaveshaped3);
}
void loop(){
audioHook(); // required here
}
+
/* Example using waveshaping to modify the spectrum of an audio signal
using Mozzi sonification library.
Demonstrates the use of WaveShaper(), EventDelay(), Smooth(),
rand(), and fixed-point numbers.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <WaveShaper.h>
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <Smooth.h>
#include <tables/sin2048_int8.h>
#include <tables/waveshape_chebyshev_3rd_256_int8.h>
#include <tables/waveshape_chebyshev_6th_256_int8.h>
#include <tables/waveshape_compress_512_to_488_int16.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA); // sine wave sound source
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aGain1(SIN2048_DATA); // to fade sine wave in and out before waveshaping
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aGain2(SIN2048_DATA); // to fade sine wave in and out before waveshaping
// Chebyshev polynomial curves, The nth curve produces the n+2th harmonic component.
WaveShaper <char> aCheby3rd(CHEBYSHEV_3RD_256_DATA); // 5th harmonic
WaveShaper <char> aCheby6th(CHEBYSHEV_6TH_256_DATA); // 8th harmonic
WaveShaper <int> aCompress(WAVESHAPE_COMPRESS_512_TO_488_DATA); // to compress instead of dividing by 2 after adding signals
// for scheduling note changes
EventDelay kChangeNoteDelay;
// for random notes
Q8n0 octave_start_note = 42;
Q24n8 carrier_freq; // unsigned long with 24 integer bits and 8 fractional bits
// smooth transitions between notes
Smooth <unsigned int> kSmoothFreq(0.85f);
int target_freq, smoothed_freq;
void setup(){
startMozzi(); // :)
randSeed(); // reseed the random generator for different results each time the sketch runs
aSin.setFreq(110); // set the frequency
aGain1.setFreq(2.f); // use a float for low frequencies, in setup it doesn't need to be fast
aGain2.setFreq(.4f);
kChangeNoteDelay.set(4000); // note duration ms, within resolution of MOZZI_CONTROL_RATE
}
byte rndPentatonic(){
byte note = rand((byte)5);
switch(note){
case 0:
note = 0;
break;
case 1:
note = 3;
break;
case 2:
note = 5;
break;
case 3:
note = 7;
break;
case 4:
note = 10;
break;
}
return note;
}
void updateControl(){
if(kChangeNoteDelay.ready()){
if(rand((byte)5)==0){ // about 1 in 5 or so
// change octave to midi 24 or any of 3 octaves above
octave_start_note = (rand((byte)4)*12)+36;
}
Q16n16 midi_note = Q8n0_to_Q16n16(octave_start_note+rndPentatonic());
target_freq = Q16n16_to_Q16n0(Q16n16_mtof(midi_note)); // has to be 16 bits for Smooth
kChangeNoteDelay.start();
}
smoothed_freq = kSmoothFreq.next(target_freq*4); // temporarily scale up target_freq to get better int smoothing at low values
aSin.setFreq(smoothed_freq/4); // then scale it back down after it's smoothed
}
AudioOutput updateAudio(){
char asig0 = aSin.next(); // sine wave source
// make 2 signals fading in and out to show effect of amplitude when waveshaping with Chebyshev polynomial curves
// offset the signals by 128 to fit in the 0-255 range for the waveshaping table lookups
byte asig1 = (byte)128+((asig0*((byte)128+aGain1.next()))>>8);
byte asig2 = (byte)128+((asig0*((byte)128+aGain2.next()))>>8);
// get the waveshaped signals
char awaveshaped1 = aCheby3rd.next(asig1);
char awaveshaped2 = aCheby6th.next(asig2);
// use a waveshaping table to squeeze 2 summed 8 bit signals into the range -244 to 243
int awaveshaped3 = aCompress.next(256u + awaveshaped1 + awaveshaped2);
return MonoOutput::fromAlmostNBit(9, awaveshaped3);
}
void loop(){
audioHook(); // required here
}

This example demonstrates the MultiResonantFilter specification of this class.

-
/* Example of filtering a wave with different types of filters
using Mozzi sonification library.
Demonstrates MultiResonantFilter<uint8_t>.
MultiResonantFilter is a derivative of ResonantFilter which allows all filter types to be accessed with only one filter.
It behaves similarly to ResonantFilter except:
- next(in) does not return anything and is just used to pass the current sample to the filter. Except for special cases should probably be called only once in updateAudio()
- different filter outputs are accessible via low(), high(), band() and notch() functions.
- note that the different filter types can be called in the same updateAudio(), for eg. to get different part of the signal.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
Thomas Combriat 2023, CC by-nc-sa.
*/
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil<CHUM9_NUM_CELLS, AUDIO_RATE> aCrunchySound(CHUM9_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kFilterMod(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kFilterMod2(COS2048_DATA);
MultiResonantFilter<uint8_t> mf; // Multifilter applied to a 8 bits signal.
// MultiResonantFilter<uint16_t> can also be used for signals with higher number of bits
// in this last case, both the cutoff frequency and the resonance are uint16_t,
// ranging from 0, to 65535.
enum types {lowpass, bandpass, highpass, notch};
byte filter_type = 0;
uint8_t resonance = 200; // range 0-255, 255 is most resonant.
void setup() {
startMozzi();
aCrunchySound.setFreq(2.f);
kFilterMod.setFreq(1.3f);
kFilterMod2.setFreq(0.1f);
}
void loop() {
audioHook();
}
void updateControl() {
if (rand(CONTROL_RATE / 2) == 0) { // about once every half second
kFilterMod.setFreq((float)rand(255) / 64); // choose a new modulation frequency
filter_type = rand(4); // change the filter type, randomly
}
// map the modulation into the filter range (0-255), corresponds with 0-AUDIO_RATE/(sqrt(2)*pi) Hz
uint8_t cutoff_freq = (100 + kFilterMod.next() / 2) ;
mf.setCutoffFreqAndResonance(cutoff_freq, resonance);
}
AudioOutput_t updateAudio() {
AudioOutput_t asig;
mf.next(aCrunchySound.next()); // this send the current sample to the filter, does not return anything
switch (filter_type) // recover the output from the current selected filter type.
{
case lowpass:
asig = mf.low(); // lowpassed sample
break;
case highpass:
asig = mf.high(); // highpassed sample
break;
case bandpass:
asig = mf.band(); // bandpassed sample
break;
case notch:
asig = mf.notch(); // notched sample
break;
}
return MonoOutput::fromNBit(9, asig); // signal is theoretically 8 bits, but resonance push it further so we let one bit of margin
}
+
/* Example of filtering a wave with different types of filters
using Mozzi sonification library.
Demonstrates MultiResonantFilter<uint8_t>.
MultiResonantFilter is a derivative of ResonantFilter which allows all filter types to be accessed with only one filter.
It behaves similarly to ResonantFilter except:
- next(in) does not return anything and is just used to pass the current sample to the filter. Except for special cases should probably be called only once in updateAudio()
- different filter outputs are accessible via low(), high(), band() and notch() functions.
- note that the different filter types can be called in the same updateAudio(), for eg. to get different part of the signal.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
Thomas Combriat 2023, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil<CHUM9_NUM_CELLS, MOZZI_AUDIO_RATE> aCrunchySound(CHUM9_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod2(COS2048_DATA);
MultiResonantFilter<uint8_t> mf; // Multifilter applied to a 8 bits signal.
// MultiResonantFilter<uint16_t> can also be used for signals with higher number of bits
// in this last case, both the cutoff frequency and the resonance are uint16_t,
// ranging from 0, to 65535.
enum types {lowpass, bandpass, highpass, notch};
byte filter_type = 0;
uint8_t resonance = 200; // range 0-255, 255 is most resonant.
void setup() {
startMozzi();
aCrunchySound.setFreq(2.f);
kFilterMod.setFreq(1.3f);
kFilterMod2.setFreq(0.1f);
}
void loop() {
audioHook();
}
void updateControl() {
if (rand(MOZZI_CONTROL_RATE / 2) == 0) { // about once every half second
kFilterMod.setFreq((float)rand(255) / 64); // choose a new modulation frequency
filter_type = rand(4); // change the filter type, randomly
}
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
uint8_t cutoff_freq = (100 + kFilterMod.next() / 2) ;
mf.setCutoffFreqAndResonance(cutoff_freq, resonance);
}
AudioOutput updateAudio() {
AudioOutput asig;
mf.next(aCrunchySound.next()); // this send the current sample to the filter, does not return anything
switch (filter_type) // recover the output from the current selected filter type.
{
case lowpass:
asig = mf.low(); // lowpassed sample
break;
case highpass:
asig = mf.high(); // highpassed sample
break;
case bandpass:
asig = mf.band(); // bandpassed sample
break;
case notch:
asig = mf.notch(); // notched sample
break;
}
return MonoOutput::fromNBit(9, asig); // signal is theoretically 8 bits, but resonance push it further so we let one bit of margin
}

This example demonstrates the ResonantFilter16 specification of this class.

-
/* Example of filtering a wave,
using Mozzi sonification library.
Demonstrates ResonantFilter<uint16_t, FILTER_TYPE>.
ResonantFilter<uint16_t, FILTER_TYPE> is a different version of ResonantFilter<uint8_t, FILTER_TYPE> which uses bigger containing types for internal calculations.
The main differences with LowPassFilter are:
- parameters (resonance and cutoff_freq) are coded on 16bits, allowing for smoother transitions and finer tuning if needed,
- for 8bits platforms (like the Arduino) it will accept input samples of more than 8bits without overflowing,
- the drawback is higher CPU usage, especially for 8bits platform. If speed is crucial, you should probably use ResonantFilter<uint8_t, FILTER_TYPE> instead.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil<CHUM9_NUM_CELLS, AUDIO_RATE> aCrunchySound(CHUM9_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kFilterMod(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kFilterMod2(COS2048_DATA);
//Different types of filters available
LowPassFilter16 rf; // Equivalent to ResonantFilter<LOWPASS, uint16_t>
//ResonantFilter<HIGHPASS, uint16_t> rf; // HighPass filter
//ResonantFilter<BANDPASS, uint16_t> rf; // BandPass filter
//ResonantFilter<NOTCH, uint16_t> rf; // Notch filter
uint16_t resonance = 50000; // range 0-65535, 65535 is most resonant.
// note the difference of type with the LowPassFilter()
void setup(){
startMozzi();
aCrunchySound.setFreq(2.f);
kFilterMod.setFreq(1.3f);
kFilterMod2.setFreq(0.1f);
}
void loop(){
audioHook();
}
void updateControl(){
if (rand(CONTROL_RATE/2) == 0){ // about once every half second
kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency
}
// map the modulation into the filter range (0-255), corresponds with 0-AUDIO_RATE/(sqrt(2)*pi) Hz
uint16_t cutoff_freq = (100 + kFilterMod.next()/2) * (170+kFilterMod2.next());
rf.setCutoffFreqAndResonance(cutoff_freq, resonance);
}
AudioOutput_t updateAudio(){
AudioOutput_t asig = rf.next(aCrunchySound.next());
return MonoOutput::from8Bit(asig);
}
+
/* Example of filtering a wave,
using Mozzi sonification library.
Demonstrates ResonantFilter<uint16_t, FILTER_TYPE>.
ResonantFilter<uint16_t, FILTER_TYPE> is a different version of ResonantFilter<uint8_t, FILTER_TYPE> which uses bigger containing types for internal calculations.
The main differences with LowPassFilter are:
- parameters (resonance and cutoff_freq) are coded on 16bits, allowing for smoother transitions and finer tuning if needed,
- for 8bits platforms (like the Arduino) it will accept input samples of more than 8bits without overflowing,
- the drawback is higher CPU usage, especially for 8bits platform. If speed is crucial, you should probably use ResonantFilter<uint8_t, FILTER_TYPE> instead.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil<CHUM9_NUM_CELLS, MOZZI_AUDIO_RATE> aCrunchySound(CHUM9_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod2(COS2048_DATA);
//Different types of filters available
LowPassFilter16 rf; // Equivalent to ResonantFilter<LOWPASS, uint16_t>
//ResonantFilter<HIGHPASS, uint16_t> rf; // HighPass filter
//ResonantFilter<BANDPASS, uint16_t> rf; // BandPass filter
//ResonantFilter<NOTCH, uint16_t> rf; // Notch filter
uint16_t resonance = 50000; // range 0-65535, 65535 is most resonant.
// note the difference of type with the LowPassFilter()
void setup(){
startMozzi();
aCrunchySound.setFreq(2.f);
kFilterMod.setFreq(1.3f);
kFilterMod2.setFreq(0.1f);
}
void loop(){
audioHook();
}
void updateControl(){
if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second
kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency
}
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
uint16_t cutoff_freq = (100 + kFilterMod.next()/2) * (170+kFilterMod2.next());
rf.setCutoffFreqAndResonance(cutoff_freq, resonance);
}
AudioOutput updateAudio(){
AudioOutput asig = rf.next(aCrunchySound.next());
return MonoOutput::from8Bit(asig);
}
-
1 /*
2  * ADSR.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef ADSR_H_
13 #define ADSR_H_
14 
15 #if ARDUINO >= 100
16  #include "Arduino.h"
17 #else
18  #include "WProgram.h"
19 #endif
20 #include "Line.h"
21 #include "mozzi_fixmath.h"
22 
23 
24 /** A simple ADSR envelope generator. This implementation has separate update() and next()
25 methods, where next() interpolates values between each update().
26 The "normal" way to use this would be with update() in updateControl(), where it calculates a new internal state each control step,
27 and then next() is in updateAudio(), called much more often, where it interpolates between the control values.
28 This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update.
29 @tparam CONTROL_UPDATE_RATE The frequency of control updates.
30 Ordinarily this will be CONTROL_RATE, but an alternative (amongst others) is
31 to set this as well as the LERP_RATE parameter to AUDIO_RATE, and call both update() and next() in updateAudio().
32 Such a use would allow accurate envelopes with finer resolution of the control points than CONTROL_RATE.
33 @tparam LERP_RATE Sets how often next() will be called, to interpolate between updates set by CONTROL_UPDATE_RATE.
34 This will produce the smoothest results if it's set to AUDIO_RATE, but if you need to save processor time and your
35 envelope changes slowly or controls something like a filter where there may not be problems with glitchy or clicking transitions,
36 LERP_RATE could be set to CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(),
37 greatly reducing the amount of processing required compared to calling next() in updateAudio().
38 @todo Test whether using the template parameters makes any difference to speed,
39 and rationalise which units do and don't need them.
40 Template objects are messy when you try to use pointers to them,
41 you have to include the whole template in the pointer handling.
42 */
43 
44 template <unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
45 class ADSR
46 {
47 private:
48 
49  const unsigned int LERPS_PER_CONTROL;
50 
51  T update_step_counter;
52  T num_update_steps;
53 
54  enum {ATTACK,DECAY,SUSTAIN,RELEASE,IDLE};
55 
56 
57  struct phase{
58  byte phase_type;
59  T update_steps;
60  long lerp_steps; // signed, to match params to transition (line) type Q15n16, below
61  Q8n0 level;
62  }attack,decay,sustain,release,idle;
63 
64  phase * current_phase;
65 
66  // Linear audio rate transitions for envelope
67  //Line <unsigned long> transition;
68  Line <Q15n16> transition; // scale up unsigned char levels for better accuracy, then scale down again for output
69 
70  inline
71  T convertMsecToControlUpdateSteps(unsigned int msec){
72  return (T) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
73  }
74 
75 
76  inline
77  void setPhase(phase * next_phase) {
78  update_step_counter = 0;
79  num_update_steps = next_phase->update_steps;
80  transition.set(Q8n0_to_Q15n16(next_phase->level),next_phase->lerp_steps);
81  current_phase = next_phase;
82  }
83 
84 
85  inline
86  void checkForAndSetNextPhase(phase * next_phase) {
87  if (++update_step_counter >= num_update_steps){
88  setPhase(next_phase);
89  }
90  }
91 
92 
93 
94  inline
95  void setTime(phase * p, unsigned int msec)
96  {
97  p->update_steps = convertMsecToControlUpdateSteps(msec);
98  p->lerp_steps = (long) p->update_steps * LERPS_PER_CONTROL;
99  }
100 
101 
102  inline
103  void setUpdateSteps(phase * p, unsigned int steps)
104  {
105  p->update_steps = steps;
106  p->lerp_steps = (long) steps * LERPS_PER_CONTROL;
107  }
108 
109 
110 
111 public:
112 
113  /** Constructor.
114  */
115  ADSR():LERPS_PER_CONTROL(LERP_RATE/CONTROL_UPDATE_RATE)
116  {
117  attack.phase_type = ATTACK;
118  decay.phase_type = DECAY;
119  sustain.phase_type = SUSTAIN;
120  release.phase_type = RELEASE;
121  idle.phase_type = IDLE;
122  release.level = 0;
123  adsr_playing = false;
124  current_phase = &idle;
125  }
126 
127 
128 
129  /** Updates the internal controls of the ADSR.
130  Call this in updateControl().
131  */
132  void update(){ // control rate
133 
134  switch(current_phase->phase_type) {
135 
136  case ATTACK:
137  checkForAndSetNextPhase(&decay);
138  break;
139 
140  case DECAY:
141  checkForAndSetNextPhase(&sustain);
142  break;
143 
144  case SUSTAIN:
145  checkForAndSetNextPhase(&release);
146  break;
147 
148  case RELEASE:
149  checkForAndSetNextPhase(&idle);
150  break;
151 
152  case IDLE:
153  adsr_playing = false;
154  break;
155  }
156  }
157 
158 
159 
160  /** Advances one audio step along the ADSR and returns the level.
161  Call this in updateAudio().
162  @return the next value, as an unsigned char.
163  */
164  inline
165  unsigned char next()
166  {
167  unsigned char out = 0;
168  if (adsr_playing) out = Q15n16_to_Q8n0(transition.next());
169  return out;
170  }
171 
172 
173 
174  /** Start the attack phase of the ADSR. This will restart the ADSR no matter what phase it is up to.
175  @param reset If true, the envelope will start from 0, even if it is still playing (often useful for effect envelopes).
176  If false (default if omitted), the envelope will start rising from the current level, which could be non-zero, if
177  it is still playing (most useful for note envelopes).
178  */
179  inline
180  void noteOn(bool reset=false){
181  if (reset) transition.set(0);
182  setPhase(&attack);
183  adsr_playing = true;
184  }
185 
186 
187 
188  /** Start the release phase of the ADSR.
189  @todo fix release for rate rather than steps (time), so it releases at the same rate whatever the current level.
190  */
191  inline
192  void noteOff(){
193  setPhase(&release);
194  }
195 
196 
197 
198  /** Set the attack level of the ADSR.
199  @param value the attack level.
200  */
201  inline
202  void setAttackLevel(byte value)
203  {
204  attack.level=value;
205  }
206 
207 
208 
209  /** Set the decay level of the ADSR.
210  @param value the decay level.
211  */
212  inline
213  void setDecayLevel(byte value)
214  {
215  decay.level=value;
216  }
217 
218 
219  /** Set the sustain level of the ADSR.
220  @param value the sustain level. Usually the same as the decay level,
221  for a steady sustained note.
222  */
223  inline
224  void setSustainLevel(byte value)
225  {
226  sustain.level=value;
227  }
228 
229  /** Set the release level of the ADSR. Normally you'd make this 0,
230  but you have the option of some other value.
231  @param value the release level (usually 0).
232  */
233  inline
234  void setReleaseLevel(byte value)
235  {
236  release.level=value;
237  }
238 
239 
240  inline
241  void setIdleLevel(byte value)
242  {
243  idle.level=value;
244  }
245 
246 
247  /** Set the attack and decay levels of the ADSR. This assumes a conventional
248  ADSR where the sustain continues at the same level as the decay, till the release ramps to 0.
249  @param attack the new attack level.
250  @param decay the new decay level.
251  */
252  inline
253  void setADLevels(byte attack, byte decay)
254  {
255  setAttackLevel(attack);
256  setDecayLevel(decay);
257  setSustainLevel(decay); // stay at decay level
258  setReleaseLevel(1);
259  setIdleLevel(0);
260  }
261 
262 
263  /** Set the attack, decay, sustain and release levels.
264  @param attack the new attack level.
265  @param decay the new sustain level.
266  @param attack the new sustain level.
267  @param decay the new release level.
268  */
269  inline
270  void setLevels(byte attack, byte decay, byte sustain, byte release)
271  {
272  setAttackLevel(attack);
273  setDecayLevel(decay);
274  setSustainLevel(sustain);
275  setReleaseLevel(release);
276  setIdleLevel(0);
277  }
278 
279 
280  /** Set the attack time of the ADSR in milliseconds.
281  The actual time taken will be resolved within the resolution of CONTROL_RATE.
282  @param msec the unsigned int attack time in milliseconds.
283  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
284  in case internal step size gets calculated as 0, which would mean nothing happens.
285  */
286  inline
287  void setAttackTime(unsigned int msec)
288  {
289  setTime(&attack, msec);
290  }
291 
292 
293  /** Set the decay time of the ADSR in milliseconds.
294  The actual time taken will be resolved within the resolution of CONTROL_RATE.
295  @param msec the unsigned int decay time in milliseconds.
296  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
297  in case internal step size gets calculated as 0, which would mean nothing happens.
298  */
299  inline
300  void setDecayTime(unsigned int msec)
301  {
302  setTime(&decay, msec);
303  }
304 
305 
306  /** Set the sustain time of the ADSR in milliseconds.
307  The actual time taken will be resolved within the resolution of CONTROL_RATE.
308  The sustain phase will finish if the ADSR recieves a noteOff().
309  @param msec the unsigned int sustain time in milliseconds.
310  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
311  in case internal step size gets calculated as 0, which would mean nothing happens.
312  */
313  inline
314  void setSustainTime(unsigned int msec)
315  {
316  setTime(&sustain, msec);
317  }
318 
319 
320 
321  /** Set the release time of the ADSR in milliseconds.
322  The actual time taken will be resolved within the resolution of CONTROL_RATE.
323  @param msec the unsigned int release time in milliseconds.
324  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
325  in case internal step size gets calculated as 0, which would mean nothing happens.
326  */
327  inline
328  void setReleaseTime(unsigned int msec)
329  {
330  setTime(&release, msec);
331  }
332 
333 
334  inline
335  void setIdleTime(unsigned int msec)
336  {
337  setTime(&idle, msec);
338  }
339 
340 
341  /** Set the attack, decay and release times of the ADSR in milliseconds.
342  The actual times will be resolved within the resolution of CONTROL_RATE.
343  @param attack_ms the new attack time in milliseconds.
344  @param decay_ms the new decay time in milliseconds.
345  @param sustain_ms the new sustain time in milliseconds.
346  @param release_ms the new release time in milliseconds.
347  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
348  in case internal step size gets calculated as 0, which would mean nothing happens.
349  */
350  inline
351  void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
352  {
353  setAttackTime(attack_ms);
354  setDecayTime(decay_ms);
355  setSustainTime(sustain_ms);
356  setReleaseTime(release_ms);
357  setIdleTime(65535); // guarantee step size of line will be 0
358  }
359 
360 
361 
362  /** Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the attack phase.
363  @param steps the number of times ADSR::update() will be called in the attack phase.
364  */
365  inline
366  void setAttackUpdateSteps(unsigned int steps)
367  {
368  setUpdateSteps(&attack, steps);
369  }
370 
371 
372  /** Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the decay phase.
373  @param steps the number of times ADSR::update() will be called in the decay phase.
374  */
375  inline
376  void setDecayUpdateSteps(unsigned int steps)
377  {
378  setUpdateSteps(&decay, steps);
379  }
380 
381 
382  /** Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the sustain phase.
383  @param steps the number of times ADSR::update() will be called in the sustain phase.
384  */
385  inline
386  void setSustainUpdateSteps(unsigned int steps)
387  {
388  setUpdateSteps(&sustain, steps);
389  }
390 
391 
392  /** Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the release phase.
393  @param steps the number of times ADSR::update() will be called in the release phase.
394  */
395  inline
396  void setReleaseUpdateSteps(unsigned int steps)
397  {
398  setUpdateSteps(&release, steps);
399  }
400 
401 
402  inline
403  void setIdleUpdateSteps(unsigned int steps)
404  {
405  setUpdateSteps(&idle, steps);
406  }
407 
408  /** Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() interpolation steps).
409  @param attack_steps the number of update steps in the attack phase
410  @param decay_steps the number of update steps in the decay phase
411  @param sustain_steps the number of update steps in the sustain phase
412  @param release_steps the number of update steps in the release phase
413  */
414  inline
415  void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
416  {
417  setAttackUpdateSteps(attack_steps);
418  setDecayUpdateSteps(decay_steps);
419  setSustainUpdateSteps(sustain_steps);
420  setReleaseUpdateSteps(release_steps);
421  setIdleUpdateSteps(65535); // guarantee step size of line will be 0
422  }
423 
424 
425 bool adsr_playing;
426 
427  /** Tells if the envelope is currently playing.
428  @return true if playing, false if in IDLE state
429  */
430  inline
431  bool playing()
432  {
433  return adsr_playing;
434  }
435 
436 
437 };
438 
439 
440 /** @example 07.Envelopes/ADSR_Envelope/ADSR_Envelope.ino
441 This is an example of how to use the ADSR class.
442 */
443 
444 #endif /* ADSR_H_ */
void setDecayLevel(byte value)
Set the decay level of the ADSR.
Definition: ADSR.h:213
-
void noteOn(bool reset=false)
Start the attack phase of the ADSR.
Definition: ADSR.h:180
-
void setAttackUpdateSteps(unsigned int steps)
Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolat...
Definition: ADSR.h:366
-
void setSustainLevel(byte value)
Set the sustain level of the ADSR.
Definition: ADSR.h:224
-
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:40
-
void setLevels(byte attack, byte decay, byte sustain, byte release)
Set the attack, decay, sustain and release levels.
Definition: ADSR.h:270
-
unsigned char next()
Advances one audio step along the ADSR and returns the level.
Definition: ADSR.h:165
-
void setSustainUpdateSteps(unsigned int steps)
Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpola...
Definition: ADSR.h:386
-
void setReleaseUpdateSteps(unsigned int steps)
Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpola...
Definition: ADSR.h:396
-
void setReleaseTime(unsigned int msec)
Set the release time of the ADSR in milliseconds.
Definition: ADSR.h:328
-
void setDecayUpdateSteps(unsigned int steps)
Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolati...
Definition: ADSR.h:376
-
void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() inte...
Definition: ADSR.h:415
-
void noteOff()
Start the release phase of the ADSR.
Definition: ADSR.h:192
-
For linear changes with a minimum of calculation at each step.
Definition: Line.h:37
-
void setAttackLevel(byte value)
Set the attack level of the ADSR.
Definition: ADSR.h:202
-
void setADLevels(byte attack, byte decay)
Set the attack and decay levels of the ADSR.
Definition: ADSR.h:253
-
bool playing()
Tells if the envelope is currently playing.
Definition: ADSR.h:431
-
void setAttackTime(unsigned int msec)
Set the attack time of the ADSR in milliseconds.
Definition: ADSR.h:287
-
void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
Set the attack, decay and release times of the ADSR in milliseconds.
Definition: ADSR.h:351
-
void setReleaseLevel(byte value)
Set the release level of the ADSR.
Definition: ADSR.h:234
-
void setDecayTime(unsigned int msec)
Set the decay time of the ADSR in milliseconds.
Definition: ADSR.h:300
-
ADSR()
Constructor.
Definition: ADSR.h:115
-
uint8_t Q8n0
normal uint8_t with 0 fractional bits, represents 0.0 to 255.0
Definition: mozzi_fixmath.h:28
-
void setSustainTime(unsigned int msec)
Set the sustain time of the ADSR in milliseconds.
Definition: ADSR.h:314
-
A simple ADSR envelope generator.
Definition: ADSR.h:45
-
void update()
Updates the internal controls of the ADSR.
Definition: ADSR.h:132
+
1 /*
2  * ADSR.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef ADSR_H_
13 #define ADSR_H_
14 
15 #include <Arduino.h>
16 #include "Line.h"
17 #include "mozzi_fixmath.h"
18 
19 
20 /** A simple ADSR envelope generator. This implementation has separate update() and next()
21 methods, where next() interpolates values between each update().
22 The "normal" way to use this would be with update() in updateControl(), where it calculates a new internal state each control step,
23 and then next() is in updateAudio(), called much more often, where it interpolates between the control values.
24 This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update.
25 @tparam CONTROL_UPDATE_RATE The frequency of control updates.
26 Ordinarily this will be MOZZI_CONTROL_RATE, but an alternative (amongst others) is
27 to set this as well as the LERP_RATE parameter to MOZZI_AUDIO_RATE, and call both update() and next() in updateAudio().
28 Such a use would allow accurate envelopes with finer resolution of the control points than MOZZI_CONTROL_RATE.
29 @tparam LERP_RATE Sets how often next() will be called, to interpolate between updates set by CONTROL_UPDATE_RATE.
30 This will produce the smoothest results if it's set to MOZZI_AUDIO_RATE, but if you need to save processor time and your
31 envelope changes slowly or controls something like a filter where there may not be problems with glitchy or clicking transitions,
32 LERP_RATE could be set to MOZZI_CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(),
33 greatly reducing the amount of processing required compared to calling next() in updateAudio().
34 @todo Test whether using the template parameters makes any difference to speed,
35 and rationalise which units do and don't need them.
36 Template objects are messy when you try to use pointers to them,
37 you have to include the whole template in the pointer handling.
38 */
39 
40 template <unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
41 class ADSR
42 {
43 private:
44 
45  const unsigned int LERPS_PER_CONTROL;
46 
47  T update_step_counter;
48  T num_update_steps;
49 
50  enum {ATTACK,DECAY,SUSTAIN,RELEASE,IDLE};
51 
52 
53  struct phase{
54  byte phase_type;
55  T update_steps;
56  long lerp_steps; // signed, to match params to transition (line) type Q15n16, below
57  Q8n0 level;
58  }attack,decay,sustain,release,idle;
59 
60  phase * current_phase;
61 
62  // Linear audio rate transitions for envelope
63  //Line <unsigned long> transition;
64  Line <Q15n16> transition; // scale up unsigned char levels for better accuracy, then scale down again for output
65 
66  inline
67  T convertMsecToControlUpdateSteps(unsigned int msec){
68  return (T) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
69  }
70 
71 
72  inline
73  void setPhase(phase * next_phase) {
74  update_step_counter = 0;
75  num_update_steps = next_phase->update_steps;
76  transition.set(Q8n0_to_Q15n16(next_phase->level),next_phase->lerp_steps);
77  current_phase = next_phase;
78  }
79 
80 
81  inline
82  void checkForAndSetNextPhase(phase * next_phase) {
83  if (++update_step_counter >= num_update_steps){
84  setPhase(next_phase);
85  }
86  }
87 
88 
89 
90  inline
91  void setTime(phase * p, unsigned int msec)
92  {
93  p->update_steps = convertMsecToControlUpdateSteps(msec);
94  p->lerp_steps = (long) p->update_steps * LERPS_PER_CONTROL;
95  }
96 
97 
98  inline
99  void setUpdateSteps(phase * p, unsigned int steps)
100  {
101  p->update_steps = steps;
102  p->lerp_steps = (long) steps * LERPS_PER_CONTROL;
103  }
104 
105 
106 
107 public:
108 
109  /** Constructor.
110  */
111  ADSR():LERPS_PER_CONTROL(LERP_RATE/CONTROL_UPDATE_RATE)
112  {
113  attack.phase_type = ATTACK;
114  decay.phase_type = DECAY;
115  sustain.phase_type = SUSTAIN;
116  release.phase_type = RELEASE;
117  idle.phase_type = IDLE;
118  release.level = 0;
119  adsr_playing = false;
120  current_phase = &idle;
121  }
122 
123 
124 
125  /** Updates the internal controls of the ADSR.
126  Call this in updateControl().
127  */
128  void update(){ // control rate
129 
130  switch(current_phase->phase_type) {
131 
132  case ATTACK:
133  checkForAndSetNextPhase(&decay);
134  break;
135 
136  case DECAY:
137  checkForAndSetNextPhase(&sustain);
138  break;
139 
140  case SUSTAIN:
141  checkForAndSetNextPhase(&release);
142  break;
143 
144  case RELEASE:
145  checkForAndSetNextPhase(&idle);
146  break;
147 
148  case IDLE:
149  adsr_playing = false;
150  break;
151  }
152  }
153 
154 
155 
156  /** Advances one audio step along the ADSR and returns the level.
157  Call this in updateAudio().
158  @return the next value, as an unsigned char.
159  */
160  inline
161  unsigned char next()
162  {
163  unsigned char out = 0;
164  if (adsr_playing) out = Q15n16_to_Q8n0(transition.next());
165  return out;
166  }
167 
168 
169 
170  /** Start the attack phase of the ADSR. This will restart the ADSR no matter what phase it is up to.
171  @param reset If true, the envelope will start from 0, even if it is still playing (often useful for effect envelopes).
172  If false (default if omitted), the envelope will start rising from the current level, which could be non-zero, if
173  it is still playing (most useful for note envelopes).
174  */
175  inline
176  void noteOn(bool reset=false){
177  if (reset) transition.set(0);
178  setPhase(&attack);
179  adsr_playing = true;
180  }
181 
182 
183 
184  /** Start the release phase of the ADSR.
185  @todo fix release for rate rather than steps (time), so it releases at the same rate whatever the current level.
186  */
187  inline
188  void noteOff(){
189  setPhase(&release);
190  }
191 
192 
193 
194  /** Set the attack level of the ADSR.
195  @param value the attack level.
196  */
197  inline
198  void setAttackLevel(byte value)
199  {
200  attack.level=value;
201  }
202 
203 
204 
205  /** Set the decay level of the ADSR.
206  @param value the decay level.
207  */
208  inline
209  void setDecayLevel(byte value)
210  {
211  decay.level=value;
212  }
213 
214 
215  /** Set the sustain level of the ADSR.
216  @param value the sustain level. Usually the same as the decay level,
217  for a steady sustained note.
218  */
219  inline
220  void setSustainLevel(byte value)
221  {
222  sustain.level=value;
223  }
224 
225  /** Set the release level of the ADSR. Normally you'd make this 0,
226  but you have the option of some other value.
227  @param value the release level (usually 0).
228  */
229  inline
230  void setReleaseLevel(byte value)
231  {
232  release.level=value;
233  }
234 
235 
236  inline
237  void setIdleLevel(byte value)
238  {
239  idle.level=value;
240  }
241 
242 
243  /** Set the attack and decay levels of the ADSR. This assumes a conventional
244  ADSR where the sustain continues at the same level as the decay, till the release ramps to 0.
245  @param attack the new attack level.
246  @param decay the new decay level.
247  */
248  inline
249  void setADLevels(byte attack, byte decay)
250  {
251  setAttackLevel(attack);
252  setDecayLevel(decay);
253  setSustainLevel(decay); // stay at decay level
254  setReleaseLevel(1);
255  setIdleLevel(0);
256  }
257 
258 
259  /** Set the attack, decay, sustain and release levels.
260  @param attack the new attack level.
261  @param decay the new sustain level.
262  @param attack the new sustain level.
263  @param decay the new release level.
264  */
265  inline
266  void setLevels(byte attack, byte decay, byte sustain, byte release)
267  {
268  setAttackLevel(attack);
269  setDecayLevel(decay);
270  setSustainLevel(sustain);
271  setReleaseLevel(release);
272  setIdleLevel(0);
273  }
274 
275 
276  /** Set the attack time of the ADSR in milliseconds.
277  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
278  @param msec the unsigned int attack time in milliseconds.
279  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
280  in case internal step size gets calculated as 0, which would mean nothing happens.
281  */
282  inline
283  void setAttackTime(unsigned int msec)
284  {
285  setTime(&attack, msec);
286  }
287 
288 
289  /** Set the decay time of the ADSR in milliseconds.
290  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
291  @param msec the unsigned int decay time in milliseconds.
292  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
293  in case internal step size gets calculated as 0, which would mean nothing happens.
294  */
295  inline
296  void setDecayTime(unsigned int msec)
297  {
298  setTime(&decay, msec);
299  }
300 
301 
302  /** Set the sustain time of the ADSR in milliseconds.
303  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
304  The sustain phase will finish if the ADSR recieves a noteOff().
305  @param msec the unsigned int sustain time in milliseconds.
306  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
307  in case internal step size gets calculated as 0, which would mean nothing happens.
308  */
309  inline
310  void setSustainTime(unsigned int msec)
311  {
312  setTime(&sustain, msec);
313  }
314 
315 
316 
317  /** Set the release time of the ADSR in milliseconds.
318  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
319  @param msec the unsigned int release time in milliseconds.
320  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
321  in case internal step size gets calculated as 0, which would mean nothing happens.
322  */
323  inline
324  void setReleaseTime(unsigned int msec)
325  {
326  setTime(&release, msec);
327  }
328 
329 
330  inline
331  void setIdleTime(unsigned int msec)
332  {
333  setTime(&idle, msec);
334  }
335 
336 
337  /** Set the attack, decay and release times of the ADSR in milliseconds.
338  The actual times will be resolved within the resolution of MOZZI_CONTROL_RATE.
339  @param attack_ms the new attack time in milliseconds.
340  @param decay_ms the new decay time in milliseconds.
341  @param sustain_ms the new sustain time in milliseconds.
342  @param release_ms the new release time in milliseconds.
343  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
344  in case internal step size gets calculated as 0, which would mean nothing happens.
345  */
346  inline
347  void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
348  {
349  setAttackTime(attack_ms);
350  setDecayTime(decay_ms);
351  setSustainTime(sustain_ms);
352  setReleaseTime(release_ms);
353  setIdleTime(65535); // guarantee step size of line will be 0
354  }
355 
356 
357 
358  /** Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the attack phase.
359  @param steps the number of times ADSR::update() will be called in the attack phase.
360  */
361  inline
362  void setAttackUpdateSteps(unsigned int steps)
363  {
364  setUpdateSteps(&attack, steps);
365  }
366 
367 
368  /** Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the decay phase.
369  @param steps the number of times ADSR::update() will be called in the decay phase.
370  */
371  inline
372  void setDecayUpdateSteps(unsigned int steps)
373  {
374  setUpdateSteps(&decay, steps);
375  }
376 
377 
378  /** Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the sustain phase.
379  @param steps the number of times ADSR::update() will be called in the sustain phase.
380  */
381  inline
382  void setSustainUpdateSteps(unsigned int steps)
383  {
384  setUpdateSteps(&sustain, steps);
385  }
386 
387 
388  /** Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the release phase.
389  @param steps the number of times ADSR::update() will be called in the release phase.
390  */
391  inline
392  void setReleaseUpdateSteps(unsigned int steps)
393  {
394  setUpdateSteps(&release, steps);
395  }
396 
397 
398  inline
399  void setIdleUpdateSteps(unsigned int steps)
400  {
401  setUpdateSteps(&idle, steps);
402  }
403 
404  /** Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() interpolation steps).
405  @param attack_steps the number of update steps in the attack phase
406  @param decay_steps the number of update steps in the decay phase
407  @param sustain_steps the number of update steps in the sustain phase
408  @param release_steps the number of update steps in the release phase
409  */
410  inline
411  void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
412  {
413  setAttackUpdateSteps(attack_steps);
414  setDecayUpdateSteps(decay_steps);
415  setSustainUpdateSteps(sustain_steps);
416  setReleaseUpdateSteps(release_steps);
417  setIdleUpdateSteps(65535); // guarantee step size of line will be 0
418  }
419 
420 
421 bool adsr_playing;
422 
423  /** Tells if the envelope is currently playing.
424  @return true if playing, false if in IDLE state
425  */
426  inline
427  bool playing()
428  {
429  return adsr_playing;
430  }
431 
432 
433 };
434 
435 
436 /** @example 07.Envelopes/ADSR_Envelope/ADSR_Envelope.ino
437 This is an example of how to use the ADSR class.
438 */
439 
440 #endif /* ADSR_H_ */
void setDecayLevel(byte value)
Set the decay level of the ADSR.
Definition: ADSR.h:209
+
void noteOn(bool reset=false)
Start the attack phase of the ADSR.
Definition: ADSR.h:176
+
void setAttackUpdateSteps(unsigned int steps)
Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolat...
Definition: ADSR.h:362
+
void setSustainLevel(byte value)
Set the sustain level of the ADSR.
Definition: ADSR.h:220
+
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:38
+
void setLevels(byte attack, byte decay, byte sustain, byte release)
Set the attack, decay, sustain and release levels.
Definition: ADSR.h:266
+
unsigned char next()
Advances one audio step along the ADSR and returns the level.
Definition: ADSR.h:161
+
void setSustainUpdateSteps(unsigned int steps)
Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpola...
Definition: ADSR.h:382
+
void setReleaseUpdateSteps(unsigned int steps)
Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpola...
Definition: ADSR.h:392
+
void setReleaseTime(unsigned int msec)
Set the release time of the ADSR in milliseconds.
Definition: ADSR.h:324
+
void setDecayUpdateSteps(unsigned int steps)
Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolati...
Definition: ADSR.h:372
+
void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() inte...
Definition: ADSR.h:411
+
void noteOff()
Start the release phase of the ADSR.
Definition: ADSR.h:188
+
For linear changes with a minimum of calculation at each step.
Definition: Line.h:33
+
void setAttackLevel(byte value)
Set the attack level of the ADSR.
Definition: ADSR.h:198
+
void setADLevels(byte attack, byte decay)
Set the attack and decay levels of the ADSR.
Definition: ADSR.h:249
+
bool playing()
Tells if the envelope is currently playing.
Definition: ADSR.h:427
+
void setAttackTime(unsigned int msec)
Set the attack time of the ADSR in milliseconds.
Definition: ADSR.h:283
+
void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
Set the attack, decay and release times of the ADSR in milliseconds.
Definition: ADSR.h:347
+
void setReleaseLevel(byte value)
Set the release level of the ADSR.
Definition: ADSR.h:230
+
void setDecayTime(unsigned int msec)
Set the decay time of the ADSR in milliseconds.
Definition: ADSR.h:296
+
ADSR()
Constructor.
Definition: ADSR.h:111
+
uint8_t Q8n0
normal uint8_t with 0 fractional bits, represents 0.0 to 255.0
Definition: mozzi_fixmath.h:26
+
void setSustainTime(unsigned int msec)
Set the sustain time of the ADSR in milliseconds.
Definition: ADSR.h:310
+
A simple ADSR envelope generator.
Definition: ADSR.h:41
+
void update()
Updates the internal controls of the ADSR.
Definition: ADSR.h:128
-
1 /*
2  * AudioDelay.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUDIODELAY_H_
13 #define AUDIODELAY_H_
14 
15 
16 /** Audio delay line for comb filter, flange, chorus and short echo effects.
17 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples. This should
18 be a power of two. The largest delay you'll fit in an atmega328 will be 512
19 cells, which at 16384 Hz sample rate is 31 milliseconds. More of a flanger or a
20 doubler than an echo. The amount of memory available for delays on other chips will vary.
21 AudioDelay() doesn't have feedback. If you want feedback, use AudioDelayFeedback().
22 @tparam the type of numbers to use for the signal in the delay. The default is int8_t, but int could be useful
23 when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
24 */
25 
26 template <unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
28 {
29 
30 private:
31 
32  T delay_array[NUM_BUFFER_SAMPLES];
33  unsigned int _write_pos;
34  unsigned int _delaytime_cells;
35 
36 public:
37 
38  /** Constructor.
39  */
40  AudioDelay(): _write_pos(0)
41  {}
42 
43 
44  /** Constructor.
45  @param delaytime_cells delay time expressed in cells.
46  For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
47  Put another way, num_cells = delay_seconds * AUDIO_RATE.
48  */
49  AudioDelay(unsigned int delaytime_cells): _write_pos(0), _delaytime_cells(delaytime_cells)
50  {}
51 
52 
53 
54  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
55  @param in_value the signal input.
56  @param delaytime_cells sets the delay time in terms of cells in the delay buffer.
57  */
58  inline
59  T next(T in_value, unsigned int delaytime_cells)
60  {
61  ++_write_pos &= (NUM_BUFFER_SAMPLES - 1);
62  unsigned int read_pos = (_write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
63 
64  // why does delay jump if I read it before writing?
65  delay_array[_write_pos] = in_value; // write to buffer
66  int8_t delay_sig = delay_array[read_pos] ; // read the delay buffer
67 
68  return (T)delay_sig;
69  }
70 
71 
72 
73  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
74  @param in_value the signal input.
75  */
76  inline
77  T next(T in_value)
78  {
79  ++_write_pos &= (NUM_BUFFER_SAMPLES - 1);
80  unsigned int read_pos = (_write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
81 
82  // why does delay jump if I read it before writing?
83  delay_array[_write_pos] = in_value; // write to buffer
84  T delay_sig = delay_array[read_pos] ; // read the delay buffer
85 
86  return delay_sig;
87  }
88 
89 
90  /** Set the delay time, measured in cells.
91  @param delaytime_cells how many cells to delay the input signal by.
92  */
93  inline
94  void set(unsigned int delaytime_cells){
95  _delaytime_cells = delaytime_cells;
96  }
97 
98 
99  /** Retrieve the signal in the delay line at the position delaytime_cells.
100  It doesn't change the stored internal value of _delaytime_cells.
101  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
102  */
103  inline
104  T read(unsigned int delaytime_cells)
105  {
106  unsigned int read_pos = (_write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
107  return delay_array[read_pos];
108  }
109 
110 
111  // /** Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal.
112  // This can be useful for manually adding feedback to the delay line, "behind" the advancing write head.
113  // @param input the signal input.
114  // */
115  // inline
116  // void writeFeedback(T input)
117  // {
118  // delay_array[_write_pos] = input;
119  // }
120 
121 };
122 
123 /**
124 @example 09.Delays/AudioDelay/AudioDelay.ino
125 This is an example of how to use the AudioDelay class.
126 */
127 
128 #endif // #ifndef AUDIODELAY_H_
T next(T in_value)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells...
Definition: AudioDelay.h:77
+
1 /*
2  * AudioDelay.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUDIODELAY_H_
13 #define AUDIODELAY_H_
14 
15 
16 /** Audio delay line for comb filter, flange, chorus and short echo effects.
17 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples. This should
18 be a power of two. The largest delay you'll fit in an atmega328 will be 512
19 cells, which at 16384 Hz sample rate is 31 milliseconds. More of a flanger or a
20 doubler than an echo. The amount of memory available for delays on other chips will vary.
21 AudioDelay() doesn't have feedback. If you want feedback, use AudioDelayFeedback().
22 @tparam the type of numbers to use for the signal in the delay. The default is int8_t, but int could be useful
23 when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
24 */
25 
26 template <unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
28 {
29 
30 private:
31 
32  T delay_array[NUM_BUFFER_SAMPLES];
33  unsigned int _write_pos;
34  unsigned int _delaytime_cells;
35 
36 public:
37 
38  /** Constructor.
39  */
40  AudioDelay(): _write_pos(0)
41  {}
42 
43 
44  /** Constructor.
45  @param delaytime_cells delay time expressed in cells.
46  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
47  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
48  */
49  AudioDelay(unsigned int delaytime_cells): _write_pos(0), _delaytime_cells(delaytime_cells)
50  {}
51 
52 
53 
54  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
55  @param in_value the signal input.
56  @param delaytime_cells sets the delay time in terms of cells in the delay buffer.
57  */
58  inline
59  T next(T in_value, unsigned int delaytime_cells)
60  {
61  ++_write_pos &= (NUM_BUFFER_SAMPLES - 1);
62  unsigned int read_pos = (_write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
63 
64  // why does delay jump if I read it before writing?
65  delay_array[_write_pos] = in_value; // write to buffer
66  int8_t delay_sig = delay_array[read_pos] ; // read the delay buffer
67 
68  return (T)delay_sig;
69  }
70 
71 
72 
73  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
74  @param in_value the signal input.
75  */
76  inline
77  T next(T in_value)
78  {
79  ++_write_pos &= (NUM_BUFFER_SAMPLES - 1);
80  unsigned int read_pos = (_write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
81 
82  // why does delay jump if I read it before writing?
83  delay_array[_write_pos] = in_value; // write to buffer
84  T delay_sig = delay_array[read_pos] ; // read the delay buffer
85 
86  return delay_sig;
87  }
88 
89 
90  /** Set the delay time, measured in cells.
91  @param delaytime_cells how many cells to delay the input signal by.
92  */
93  inline
94  void set(unsigned int delaytime_cells){
95  _delaytime_cells = delaytime_cells;
96  }
97 
98 
99  /** Retrieve the signal in the delay line at the position delaytime_cells.
100  It doesn't change the stored internal value of _delaytime_cells.
101  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
102  */
103  inline
104  T read(unsigned int delaytime_cells)
105  {
106  unsigned int read_pos = (_write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
107  return delay_array[read_pos];
108  }
109 
110 
111  // /** Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal.
112  // This can be useful for manually adding feedback to the delay line, "behind" the advancing write head.
113  // @param input the signal input.
114  // */
115  // inline
116  // void writeFeedback(T input)
117  // {
118  // delay_array[_write_pos] = input;
119  // }
120 
121 };
122 
123 /**
124 @example 09.Delays/AudioDelay/AudioDelay.ino
125 This is an example of how to use the AudioDelay class.
126 */
127 
128 #endif // #ifndef AUDIODELAY_H_
T next(T in_value)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells...
Definition: AudioDelay.h:77
void set(unsigned int delaytime_cells)
Set the delay time, measured in cells.
Definition: AudioDelay.h:94
Audio delay line for comb filter, flange, chorus and short echo effects.
Definition: AudioDelay.h:27
AudioDelay(unsigned int delaytime_cells)
Constructor.
Definition: AudioDelay.h:49
@@ -116,7 +116,7 @@
-
1 /*
2  * AudioDelayFeedback.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUDIODELAY_FEEDBACK_H_
13 #define AUDIODELAY_FEEDBACK_H_
14 
15 #if ARDUINO >= 100
16  #include "Arduino.h"
17 #else
18  #include "WProgram.h"
19 #endif
20 
21 #include "mozzi_utils.h"
22 #include "meta.h"
23 
24 enum interpolation_types {LINEAR,ALLPASS};
25 
26 
27 /** Audio delay line with feedback for comb filter, flange, chorus and short echo effects.
28 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples, and should be a
29 power of two. The maximum delay length which will fit in an atmega328 is half
30 that of a plain AudioDelay object, in this case 256 cells, or about 15
31 milliseconds. AudioDelayFeedback uses int16_t sized cells to accomodate the higher
32 amplitude of direct input to the delay as well as the feedback, without losing
33 precision. Output is only the delay line signal. If you want to mix the delay
34 with the input, do it in your sketch. AudioDelayFeedback uses more processing and memory
35 than a plain AudioDelay, but allows for more dramatic effects with feedback.
36 @tparam INTERP_TYPE a choice of LINEAR (default) or ALLPASS interpolation. LINEAR is better
37 for sweeping delay times, ALLPASS may be better for reverb-like effects.
38 */
39 template <uint16_t NUM_BUFFER_SAMPLES, int8_t INTERP_TYPE = LINEAR>
40 class AudioDelayFeedback
41 {
42 
43 public:
44  /** Constructor.
45  */
47  {}
48 
49 
50  /** Constructor.
51  @param delaytime_cells delay time expressed in cells.
52  For example, 128 cells delay at AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
53  Put another way, num_cells = delay_seconds * AUDIO_RATE.
54  */
56  {}
57 
58 
59  /** Constructor.
60  @param delaytime_cells delay time expressed in cells.
61  For example, 128 cells delay at AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
62  Put another way, num_cells = delay_seconds * AUDIO_RATE.
63  @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1).
64  */
65  AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level): write_pos(0), _feedback_level(feedback_level), _delaytime_cells(delaytime_cells)
66  {}
67 
68 
69 
70  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
71  @param input the signal input.
72  @note slower than next(int8_t input, uint16_t delaytime_cells)
73  */
74  inline
76  {
77  // chooses a different next() function depending on whether the
78  // the template parameter is LINEAR(default if none provided) or ALLPASS.
79  // See meta.h.
80  return next(input, Int2Type<INTERP_TYPE>());
81  }
82 
83 
84 
85  /** Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells, and add feedback from the output to the input.
86  @param input the signal input.
87  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
88  It doesn't change the stored internal value of _delaytime_cells.
89  @note Timing: 4us
90  */
91  inline
93  {
94  //setPin13High();
95  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
96  uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
97  // < 1us to here
98  int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
99  // with this line, the method takes 18us
100  //int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
101  // this line, the whole method takes 4us... Compiler doesn't optimise pow2 divides. Why?
102  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
103  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
104  //setPin13Low();
105  return delay_sig;
106  }
107 
108 
109 
110  /** Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input.
111  @param input the signal input.
112  @param delaytime_cells is a fractional number to set the delay time in terms of cells
113  or partial cells in the delay buffer. It doesn't change the stored internal
114  value of _delaytime_cells.
115  */
116  inline
118  {
119  //setPin13High();
120  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
121 
122  uint16_t index = Q16n16_to_Q16n0(delaytime_cells);
123  uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word
124 
125  uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
126  int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
127 
128  uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
129  int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
130 
131 
132  int16_t difference = delay_sig2 - delay_sig1;
133  int16_t delay_sig_fraction = (int16_t)((int32_t)((int32_t) fraction * difference) >> 16);
134 
135  int16_t delay_sig = delay_sig1+delay_sig_fraction;
136 
137  //int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
138 
139  int8_t feedback_sig = (int8_t) min(max((((int16_t)(delay_sig * _feedback_level))>>7),-128),127); // feedback clipped
140  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
141  //setPin13Low();
142  return delay_sig;
143  }
144 
145 
146  /** Input a value to the delay but don't change the delay time or retrieve the output signal.
147  @param input the signal input.
148  */
149  inline
150  void write(int8_t input)
151  {
152  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
153  delay_array[write_pos] = input;
154  }
155 
156 
157  /** Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal.
158  This can be useful for manually adding feedback to the delay line, "behind" the advancing write head.
159  @param input the signal input.
160  */
161  inline
162  void writeFeedback(int8_t input)
163  {
164  delay_array[write_pos] = input;
165  }
166 
167 
168  /** Input a value to the delay at an offset from the current write position. Don't advance the main
169  write position or change the stored delay time or retrieve the output signal.
170  @param input the signal input.
171  @param offset the number of cells behind the ordinary write position where the input will be written.
172  */
173  inline
174  void write(int8_t input, uint16_t offset)
175  {
176  uint16_t _pos = (write_pos + offset) & (NUM_BUFFER_SAMPLES - 1);
177  delay_array[_pos] = input;
178  }
179 
180 
181  /** Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
182  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
183  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
184  */
185  inline
187  {
188  return read(delaytime_cells, Int2Type<INTERP_TYPE>());
189  }
190 
191 
192  /** Retrieve the signal in the delay line at the current stored delaytime_cells.
193  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
194  */
195  inline
197  {
198  return read(Int2Type<INTERP_TYPE>());
199  }
200 
201 
202  /** Set delay time expressed in samples.
203  @param delaytime_cells delay time expressed in cells, with each cell played per tick of AUDIO_RATE.
204  For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
205  Put another way, num_cells = delay_seconds * AUDIO_RATE.
206  */
207  inline
208  void setDelayTimeCells(uint16_t delaytime_cells)
209  {
210  _delaytime_cells = (uint16_t) delaytime_cells;
211  }
212 
213 
214  /** Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
215  @param delaytime_cells delay time expressed in cells, with each cell played per tick of AUDIO_RATE.
216  For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
217  Put another way, num_cells = delay_seconds * AUDIO_RATE.
218  */
219  inline
220  void setDelayTimeCells(Q16n16 delaytime_cells)
221  {
222  return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
223  }
224 
225 
226  /** Set delay time expressed in samples, fractional float for an interpolating delay.
227  @param delaytime_cells delay time expressed in cells, with each cell played per tick of AUDIO_RATE.
228  For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
229  Put another way, num_cells = delay_seconds * AUDIO_RATE.
230  */
231  inline
232  void setDelayTimeCells(float delaytime_cells)
233  {
234  return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
235  }
236 
237 
238  /** Set the feedback gain.
239  @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1).
240  */
241  inline
242  void setFeedbackLevel(int8_t feedback_level)
243  {
244  _feedback_level = feedback_level;
245  }
246 
247 
248 
249 private:
250  int16_t delay_array[NUM_BUFFER_SAMPLES];
251  uint16_t write_pos;
252  int8_t _feedback_level;
253  uint16_t _delaytime_cells;
254  Q15n16 _coeff; // for allpass interpolation
255 
256 
257 
258  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
259  @param in_value the signal input.
260  */
261  inline
262  int16_t next(int8_t in_value, Int2Type<LINEAR>)
263  {
264  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
265  uint16_t read_pos = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
266 
267  int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
268  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
269  delay_array[write_pos] = (int16_t) in_value + feedback_sig; // write to buffer
270 
271  return delay_sig;
272  }
273 
274 
275 
276  /** The delaytime_cells has to be set seperately, because it's slowish
277  and in this implementation the allpass interpolation mode doesn't slide
278  nicely from one delay time to another.
279  @param input an audio signal in
280  @return the delayed signal, including feedback
281  @note Timing: 10us
282  */
283  inline
284  int16_t next(int8_t input, Int2Type<ALLPASS>)
285  {
286  /*
287  http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
288  also https://ccrma.stanford.edu/~jos/Interpolation/Interpolation_4up.pdf
289  for desired fractional delay of d samples,
290  coeff = (1-d)/(1+d)
291  or
292  coeff = ((d-1)>1) + (((d-1)*(d-1))>>2) - (((d-1)*(d-1)*(d-1))>>3)
293  out = coeff * in + last_in - coeff * last_out
294  = coeff * (in-last_out) + last_in
295  */
296  //setPin13High();
297  static int8_t last_in;
298  static int16_t last_out;
299 
300  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
301 
302  uint16_t read_pos1 = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
303  int16_t delay_sig = delay_array[read_pos1]; // read the delay buffer
304 
305  int16_t interp = (int16_t)(_coeff * ((int16_t)input - last_out)>>16) + last_in; // Q15n16*Q15n0 + Q15n0 = Q15n16 + Q15n0 = Q15n16
306  delay_sig += interp;
307 
308  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
309  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
310 
311  last_in = input;
312  last_out = delay_sig;
313  //setPin13Low();
314  return delay_sig;
315  }
316 
317 
318 
319  // 20-25us
320  inline
321  void setDelayTimeCells(Q16n16 delaytime_cells, Int2Type<ALLPASS>)
322  {
323  /*
324  integer optimisation/approximation from
325  Van Duyne, Jaffe, Scandalis, Stilson 1997
326  http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
327  //coeff = -((d-1)>1) + (((d-1)*(d-1))>>2) - (((d-1)*(d-1)*(d-1))>>3) , d is fractional part
328  */
329  _delaytime_cells = delaytime_cells>>16; // whole integer part
330  Q15n16 dminus1 = - Q15n16_FIX1 + (uint16_t) delaytime_cells;
331  Q15n16 dminus1squared = (dminus1)*(dminus1)>>16;
332  _coeff = -(dminus1>>1) + (dminus1squared>>2) - (((dminus1squared*dminus1)>>16)>>3);
333  }
334 
335 
336  // 100us
337  inline
338  void setDelayTimeCells(float delaytime_cells, Int2Type<ALLPASS>)
339  {
340  //coeff = (1-d)/(1+d)
341  _delaytime_cells = (uint16_t) delaytime_cells;
342 
343  float fraction = delaytime_cells - _delaytime_cells;
344 
345  // modified from stk DelayA.cpp
346  float alpha_ = 1.0f + fraction; // fractional part
347  if ( alpha_ < 0.5f ) {
348  // (stk): The optimal range for alpha is about 0.5 - 1.5 in order to
349  // achieve the flattest phase delay response.
350 
351  // something's not right about how I use _delaytime_cells and
352  // NUM_BUFFER_SAMPLES etc. in my ringbuffer compared to stk
353  _delaytime_cells += 1;
354  if ( _delaytime_cells >= NUM_BUFFER_SAMPLES ) _delaytime_cells -= NUM_BUFFER_SAMPLES;
355  alpha_ += 1.0f;
356  }
357  // otherwise this would use fraction instead of alpha
358  _coeff = float_to_Q15n16((1.f-alpha_)/(1.f+alpha_));
359  }
360 
361  // Retrieve the signal in the delay line at the position delaytime_cells.
362  // It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
363  // param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
364  //
365  // inline
366  // int16_t read(uint16_t delaytime_cells, Int2Type<LINEAR>)
367  // {
368  // uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
369  // int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
370  //
371  // return delay_sig;
372  // }
373 
374  /** Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
375  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
376  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
377  */
378  inline
379  int16_t read(Q16n16 delaytime_cells, Int2Type<LINEAR>)
380  {
381  uint16_t index = (Q16n16)delaytime_cells >> 16;
382  uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word
383 
384  uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
385  int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
386 
387  uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
388  int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
389 
390  /*
391  int16_t difference = delay_sig2 - delay_sig1;
392  int16_t delay_sig_fraction = ((int32_t) fraction * difference) >> 16;
393 
394  int16_t delay_sig = delay_sig1+delay_sig_fraction;
395  */
396  int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
397 
398  return delay_sig;
399  }
400 
401 
402 };
403 
404 /**
405 @example 09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino
406 This is an example of how to use the AudioDelayFeedback class.
407 */
408 
409 #endif // #ifndef AUDIODELAY_FEEDBACK_H_
void write(int8_t input)
Input a value to the delay but don&#39;t change the delay time or retrieve the output signal...
-
void write(int8_t input, uint16_t offset)
Input a value to the delay at an offset from the current write position.
-
void setFeedbackLevel(int8_t feedback_level)
Set the feedback gain.
-
int16_t read(Q16n16 delaytime_cells)
Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
-
Enables you to instantiate a template based on an integer value.
Definition: meta.h:20
-
AudioDelayFeedback()
Constructor.
-
void writeFeedback(int8_t input)
Input a value to the delay but don&#39;t advance the write position, change the delay time or retrieve th...
-
void setDelayTimeCells(float delaytime_cells)
Set delay time expressed in samples, fractional float for an interpolating delay. ...
-
int16_t read()
Retrieve the signal in the delay line at the current stored delaytime_cells.
-
AudioDelayFeedback(uint16_t delaytime_cells)
Constructor.
-
void setDelayTimeCells(Q16n16 delaytime_cells)
Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
-
int16_t next(int8_t input)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells...
-
int16_t next(int8_t input, Q16n16 delaytime_cells)
Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional posi...
-
AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level)
Constructor.
+
1 /*
2  * AudioDelayFeedback.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUDIODELAY_FEEDBACK_H_
13 #define AUDIODELAY_FEEDBACK_H_
14 
15 #include <Arduino.h>
16 
17 #include "mozzi_utils.h"
18 #include "meta.h"
19 
20 enum interpolation_types {LINEAR,ALLPASS};
21 
22 
23 /** Audio delay line with feedback for comb filter, flange, chorus and short echo effects.
24 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples, and should be a
25 power of two. The maximum delay length which will fit in an atmega328 is half
26 that of a plain AudioDelay object, in this case 256 cells, or about 15
27 milliseconds. AudioDelayFeedback uses int16_t sized cells to accomodate the higher
28 amplitude of direct input to the delay as well as the feedback, without losing
29 precision. Output is only the delay line signal. If you want to mix the delay
30 with the input, do it in your sketch. AudioDelayFeedback uses more processing and memory
31 than a plain AudioDelay, but allows for more dramatic effects with feedback.
32 @tparam INTERP_TYPE a choice of LINEAR (default) or ALLPASS interpolation. LINEAR is better
33 for sweeping delay times, ALLPASS may be better for reverb-like effects.
34 */
35 template <uint16_t NUM_BUFFER_SAMPLES, int8_t INTERP_TYPE = LINEAR>
36 class AudioDelayFeedback
37 {
38 
39 public:
40  /** Constructor.
41  */
43  {}
44 
45 
46  /** Constructor.
47  @param delaytime_cells delay time expressed in cells.
48  For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
49  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
50  */
52  {}
53 
54 
55  /** Constructor.
56  @param delaytime_cells delay time expressed in cells.
57  For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
58  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
59  @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1).
60  */
61  AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level): write_pos(0), _feedback_level(feedback_level), _delaytime_cells(delaytime_cells)
62  {}
63 
64 
65 
66  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
67  @param input the signal input.
68  @note slower than next(int8_t input, uint16_t delaytime_cells)
69  */
70  inline
72  {
73  // chooses a different next() function depending on whether the
74  // the template parameter is LINEAR(default if none provided) or ALLPASS.
75  // See meta.h.
76  return next(input, Int2Type<INTERP_TYPE>());
77  }
78 
79 
80 
81  /** Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells, and add feedback from the output to the input.
82  @param input the signal input.
83  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
84  It doesn't change the stored internal value of _delaytime_cells.
85  @note Timing: 4us
86  */
87  inline
88  int16_t next(int8_t input, uint16_t delaytime_cells)
89  {
90  //setPin13High();
91  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
92  uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
93  // < 1us to here
94  int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
95  // with this line, the method takes 18us
96  //int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
97  // this line, the whole method takes 4us... Compiler doesn't optimise pow2 divides. Why?
98  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
99  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
100  //setPin13Low();
101  return delay_sig;
102  }
103 
104 
105 
106  /** Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input.
107  @param input the signal input.
108  @param delaytime_cells is a fractional number to set the delay time in terms of cells
109  or partial cells in the delay buffer. It doesn't change the stored internal
110  value of _delaytime_cells.
111  */
112  inline
113  int16_t next(int8_t input, Q16n16 delaytime_cells)
114  {
115  //setPin13High();
116  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
117 
118  uint16_t index = Q16n16_to_Q16n0(delaytime_cells);
119  uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word
120 
121  uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
122  int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
123 
124  uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
125  int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
126 
127 
128  int16_t difference = delay_sig2 - delay_sig1;
129  int16_t delay_sig_fraction = (int16_t)((int32_t)((int32_t) fraction * difference) >> 16);
130 
131  int16_t delay_sig = delay_sig1+delay_sig_fraction;
132 
133  //int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
134 
135  int8_t feedback_sig = (int8_t) min(max((((int16_t)(delay_sig * _feedback_level))>>7),-128),127); // feedback clipped
136  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
137  //setPin13Low();
138  return delay_sig;
139  }
140 
141 
142  /** Input a value to the delay but don't change the delay time or retrieve the output signal.
143  @param input the signal input.
144  */
145  inline
146  void write(int8_t input)
147  {
148  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
149  delay_array[write_pos] = input;
150  }
151 
152 
153  /** Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal.
154  This can be useful for manually adding feedback to the delay line, "behind" the advancing write head.
155  @param input the signal input.
156  */
157  inline
158  void writeFeedback(int8_t input)
159  {
160  delay_array[write_pos] = input;
161  }
162 
163 
164  /** Input a value to the delay at an offset from the current write position. Don't advance the main
165  write position or change the stored delay time or retrieve the output signal.
166  @param input the signal input.
167  @param offset the number of cells behind the ordinary write position where the input will be written.
168  */
169  inline
170  void write(int8_t input, uint16_t offset)
171  {
172  uint16_t _pos = (write_pos + offset) & (NUM_BUFFER_SAMPLES - 1);
173  delay_array[_pos] = input;
174  }
175 
176 
177  /** Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
178  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
179  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
180  */
181  inline
183  {
184  return read(delaytime_cells, Int2Type<INTERP_TYPE>());
185  }
186 
187 
188  /** Retrieve the signal in the delay line at the current stored delaytime_cells.
189  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
190  */
191  inline
193  {
194  return read(Int2Type<INTERP_TYPE>());
195  }
196 
197 
198  /** Set delay time expressed in samples.
199  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
200  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
201  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
202  */
203  inline
204  void setDelayTimeCells(uint16_t delaytime_cells)
205  {
206  _delaytime_cells = (uint16_t) delaytime_cells;
207  }
208 
209 
210  /** Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
211  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
212  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
213  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
214  */
215  inline
216  void setDelayTimeCells(Q16n16 delaytime_cells)
217  {
218  return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
219  }
220 
221 
222  /** Set delay time expressed in samples, fractional float for an interpolating delay.
223  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
224  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
225  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
226  */
227  inline
228  void setDelayTimeCells(float delaytime_cells)
229  {
230  return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
231  }
232 
233 
234  /** Set the feedback gain.
235  @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1).
236  */
237  inline
238  void setFeedbackLevel(int8_t feedback_level)
239  {
240  _feedback_level = feedback_level;
241  }
242 
243 
244 
245 private:
246  int16_t delay_array[NUM_BUFFER_SAMPLES];
247  uint16_t write_pos;
248  int8_t _feedback_level;
249  uint16_t _delaytime_cells;
250  Q15n16 _coeff; // for allpass interpolation
251 
252 
253 
254  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
255  @param in_value the signal input.
256  */
257  inline
258  int16_t next(int8_t in_value, Int2Type<LINEAR>)
259  {
260  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
261  uint16_t read_pos = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
262 
263  int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
264  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
265  delay_array[write_pos] = (int16_t) in_value + feedback_sig; // write to buffer
266 
267  return delay_sig;
268  }
269 
270 
271 
272  /** The delaytime_cells has to be set seperately, because it's slowish
273  and in this implementation the allpass interpolation mode doesn't slide
274  nicely from one delay time to another.
275  @param input an audio signal in
276  @return the delayed signal, including feedback
277  @note Timing: 10us
278  */
279  inline
280  int16_t next(int8_t input, Int2Type<ALLPASS>)
281  {
282  /*
283  http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
284  also https://ccrma.stanford.edu/~jos/Interpolation/Interpolation_4up.pdf
285  for desired fractional delay of d samples,
286  coeff = (1-d)/(1+d)
287  or
288  coeff = ((d-1)>1) + (((d-1)*(d-1))>>2) - (((d-1)*(d-1)*(d-1))>>3)
289  out = coeff * in + last_in - coeff * last_out
290  = coeff * (in-last_out) + last_in
291  */
292  //setPin13High();
293  static int8_t last_in;
294  static int16_t last_out;
295 
296  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
297 
298  uint16_t read_pos1 = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
299  int16_t delay_sig = delay_array[read_pos1]; // read the delay buffer
300 
301  int16_t interp = (int16_t)(_coeff * ((int16_t)input - last_out)>>16) + last_in; // Q15n16*Q15n0 + Q15n0 = Q15n16 + Q15n0 = Q15n16
302  delay_sig += interp;
303 
304  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
305  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
306 
307  last_in = input;
308  last_out = delay_sig;
309  //setPin13Low();
310  return delay_sig;
311  }
312 
313 
314 
315  // 20-25us
316  inline
317  void setDelayTimeCells(Q16n16 delaytime_cells, Int2Type<ALLPASS>)
318  {
319  /*
320  integer optimisation/approximation from
321  Van Duyne, Jaffe, Scandalis, Stilson 1997
322  http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
323  //coeff = -((d-1)>1) + (((d-1)*(d-1))>>2) - (((d-1)*(d-1)*(d-1))>>3) , d is fractional part
324  */
325  _delaytime_cells = delaytime_cells>>16; // whole integer part
326  Q15n16 dminus1 = - Q15n16_FIX1 + (uint16_t) delaytime_cells;
327  Q15n16 dminus1squared = (dminus1)*(dminus1)>>16;
328  _coeff = -(dminus1>>1) + (dminus1squared>>2) - (((dminus1squared*dminus1)>>16)>>3);
329  }
330 
331 
332  // 100us
333  inline
334  void setDelayTimeCells(float delaytime_cells, Int2Type<ALLPASS>)
335  {
336  //coeff = (1-d)/(1+d)
337  _delaytime_cells = (uint16_t) delaytime_cells;
338 
339  float fraction = delaytime_cells - _delaytime_cells;
340 
341  // modified from stk DelayA.cpp
342  float alpha_ = 1.0f + fraction; // fractional part
343  if ( alpha_ < 0.5f ) {
344  // (stk): The optimal range for alpha is about 0.5 - 1.5 in order to
345  // achieve the flattest phase delay response.
346 
347  // something's not right about how I use _delaytime_cells and
348  // NUM_BUFFER_SAMPLES etc. in my ringbuffer compared to stk
349  _delaytime_cells += 1;
350  if ( _delaytime_cells >= NUM_BUFFER_SAMPLES ) _delaytime_cells -= NUM_BUFFER_SAMPLES;
351  alpha_ += 1.0f;
352  }
353  // otherwise this would use fraction instead of alpha
354  _coeff = float_to_Q15n16((1.f-alpha_)/(1.f+alpha_));
355  }
356 
357  // Retrieve the signal in the delay line at the position delaytime_cells.
358  // It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
359  // param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
360  //
361  // inline
362  // int16_t read(uint16_t delaytime_cells, Int2Type<LINEAR>)
363  // {
364  // uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
365  // int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
366  //
367  // return delay_sig;
368  // }
369 
370  /** Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
371  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
372  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
373  */
374  inline
375  int16_t read(Q16n16 delaytime_cells, Int2Type<LINEAR>)
376  {
377  uint16_t index = (Q16n16)delaytime_cells >> 16;
378  uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word
379 
380  uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
381  int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
382 
383  uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
384  int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
385 
386  /*
387  int16_t difference = delay_sig2 - delay_sig1;
388  int16_t delay_sig_fraction = ((int32_t) fraction * difference) >> 16;
389 
390  int16_t delay_sig = delay_sig1+delay_sig_fraction;
391  */
392  int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
393 
394  return delay_sig;
395  }
396 
397 
398 };
399 
400 /**
401 @example 09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino
402 This is an example of how to use the AudioDelayFeedback class.
403 */
404 
405 #endif // #ifndef AUDIODELAY_FEEDBACK_H_
void write(int8_t input)
Input a value to the delay but don&#39;t change the delay time or retrieve the output signal...
+
void write(int8_t input, uint16_t offset)
Input a value to the delay at an offset from the current write position.
+
void setFeedbackLevel(int8_t feedback_level)
Set the feedback gain.
+
int16_t read(Q16n16 delaytime_cells)
Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
+
AudioDelayFeedback()
Constructor.
+
void writeFeedback(int8_t input)
Input a value to the delay but don&#39;t advance the write position, change the delay time or retrieve th...
+
void setDelayTimeCells(float delaytime_cells)
Set delay time expressed in samples, fractional float for an interpolating delay. ...
+
int16_t read()
Retrieve the signal in the delay line at the current stored delaytime_cells.
+
AudioDelayFeedback(uint16_t delaytime_cells)
Constructor.
+
void setDelayTimeCells(Q16n16 delaytime_cells)
Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
+
int16_t next(int8_t input)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells...
+
AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level)
Constructor.
-
1 /** @file AudioOutput
2  *
3  * Platform independent audio output and adding support for new platforms or output methods.
4  *
5  * Mozzi provides support for audio ouput on a range of different boards and CPUs. This page is about the following related topics:
6  *
7  * - adding a custom output method (importantly using external DACs) to your sketch
8  * - writing sketches that will work on different platforms / with different output methods
9  * - extending Mozzi for a new architecture
10  *
11  * For all of these topics, it is helpful to have a basic understanding of the basic output steps in Mozzi:
12  *
13  * 1. Inside the loop() function in your sketch you call audioHook(). This function is responsible for calling updateAudio(), whenever there is room in the output buffer,
14  * adding the generated sample to the output buffer, calling updateControl() at an appropriate rate, and a few other details that are not important for this discussion.
15  *
16  * 2. A platform-specific timer is triggered at audio rate (usually), takes a sample from the output buffer and sends it to audioOutput().
17  *
18  * 3. The audioOutput() function - usually predefined inside Mozzi - takes care of sending the sample to the hardware.
19  *
20  * This basic output pipeline can be customized in several ways. First, defining EXTERNAL_AUDIO_OUTPUT to true in mozzi_config.h will allow you to define your own audioOutput()
21  * fuction. The library ships with some sample sketches for output to external DACs using this mechanism.
22  *
23  * In some cases, you will additionally want to bypass Mozzis output buffer, for example, if your board, or your external DAC already comes with an efficient built-in buffer.
24  * In this case, define BYPASS_MOZZI_OUTPUT_BUFFER to true. You will then have to provide a custom definition of canBufferAudioOutput(), returning true whenever your hardware
25  * is ready toaccept a new sample of output. This is called from inside audioHook(), and whenever there is room for a new sample, it is generated and sent to audioOutput(),
26  * immediately. In this case, should you need a timer running at AUDIO_RATE, you will have to set up one, yourself, if needed.
27  *
28  * In custom code, setting BYPASS_MOZZI_OUTPUT_BUFFER does not make much sense without EXTERNAL_AUDIO_OUTPUT also set to true. However, some platform ports (e.g. ESP32) actually
29  * use this combination, internally.
30  *
31  * Different output methods often support a different resolution of output samples. To provide best performance on slow boards, Mozzi expects your updateAudio() function to
32  * return samples in exactly the width that is needed at the output stage. Thus, defining this naively, an updateAudio() function designed for 8 bit output will produce very
33  * low volume output on a 16 bit DAC, while the other way around overflows will result in way too loud and heavily distored output. Fortunately, all that is needed to write
34  * portable sketches is to specify how many bits your updateAudio() function provides. The (inline) functions in the AudioOutput namespace do just that. Using them makes sure
35  * your audio output is shifted if, and as much as needed on all platforms.
36  */
37 
38 #ifndef AUDIOOUTPUT
39 #define AUDIOOUTPUT
40 
41 #include "MozziGuts.h"
42 
43 /** The type used to store a single channel of a single frame, internally. For compatibility with earlier versions of Mozzi this is defined as int.
44  * If you do not care about keeping old sketches working, you may be able to save some RAM by using int16_t, instead (on boards where int is larger
45  * than 16 bits). */
46 #define AudioOutputStorage_t int
47 
48 #if IS_AVR() && ((AUDIO_MODE == STANDARD_PLUS) || (AUDIO_MODE == STANDARD))
49 #define SCALE_AUDIO(x,bits) (bits > 8 ? (x) >> (bits - 8) : (x) << (8 - bits))
50 #define SCALE_AUDIO_NEAR(x,bits) (bits > 9 ? (x) >> (bits - 9) : (x) << (9 - bits))
51 #define CLIP_AUDIO(x) constrain((x), -244,243)
52 #else
53 #define SCALE_AUDIO(x,bits) (bits > AUDIO_BITS ? (x) >> (bits - AUDIO_BITS) : (x) << (AUDIO_BITS - bits))
54 #define SCALE_AUDIO_NEAR(x,bits) SCALE_AUDIO(x,bits)
55 #define CLIP_AUDIO(x) constrain((x), (-(AudioOutputStorage_t) AUDIO_BIAS), (AudioOutputStorage_t) AUDIO_BIAS-1)
56 #endif
57 
58 #if (AUDIO_CHANNELS == STEREO)
59 #define AudioOutput StereoOutput
60 #if (STEREO_HACK == true)
61 #define AudioOutput_t void
62 #else
63 #define AudioOutput_t StereoOutput
64 #endif
65 #else
66 /** Representation of an single audio output sample/frame. For mono output, this is really just a single zero-centered int,
67  * but for stereo it's a struct containing two ints.
68  *
69  * While it may be tempting (and is possible) to use an int, directly, using AudioOutput_t and the functions AudioOutput::from8Bit(),
70  * AudioOutput::fromNBit(), or AudioOutput::fromAlmostNBit() will allow you to write code that will work across different platforms, even
71  * when those use a different output resolution.
72  *
73  * @note The only place where you should be using AudioOutput_t, directly, is in your updateAudio() function signature. It's really just a
74  * dummy used to make the "same" function signature work across different configurations (importantly mono/stereo). It's true value
75  * might be subject to change, and it may even be void. Use either MonoOutput or StereoOutput to represent a piece of audio output.
76  */
77 #define AudioOutput_t AudioOutputStorage_t
78 /** Representation of an single audio output sample/frame. This #define maps to either MonoOutput or StereoOutput, depending on what is configured
79  * in mozzi_config.h. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g.
80  * both have functions l() and r(), to return "two" audio channels (which will be the same in case of mono).
81  *
82  * You will not usually use or encounter this definition, unless using EXTERNAL_AUDIO_OUTPUT.
83  */
84 #define AudioOutput MonoOutput
85 #endif
86 
87 /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to two int values, but the struct provides
88  * useful API an top of that. For more detail @see MonoOutput . */
89 struct StereoOutput {
90  /** Construct an audio frame from raw values (zero-centered) */
92  /** Default contstructor */
93  StereoOutput() : _l(0), _r(0) {};
94 #if (AUDIO_CHANNELS != STEREO)
95  /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning).
96  This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
97  using StereoOutput in a mono config, is not intended. */
98  inline AudioOutput_t portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check mozzi_config.h."))) { return _l; };
99 #endif
100  AudioOutputStorage_t l() const { return _l; };
101  AudioOutputStorage_t r() const { return _r; };
102  /** @see MonoOutput::clip(). Clips both channels. */
103  StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; };
104 
105  /** @see MonoOutput::fromNBit(), stereo variant */
106 template<typename T> static inline StereoOutput fromNBit(uint8_t bits, T l, T r) { return StereoOutput(SCALE_AUDIO(l, bits), SCALE_AUDIO(r, bits)); }
107  /** @see MonoOutput::from8Bit(), stereo variant */
108  static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); }
109  /** @see MonoOutput::from16Bit(), stereo variant */
110  static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); }
111  /** @see MonoOutput::fromAlmostNBit(), stereo variant */
112  template<typename A, typename B> static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); }
113 private:
116 };
117 
118 /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to a single int value, but the struct provides
119  * useful API an top of that, for the following:
120  *
121  * a) To construct an output frame, you should use one of the from8Bit(), fromNBit(), etc. functions. Given a raw input value, at a known resolution (number of bits),
122  * this scales the output efficiently to whatever is needed on the target platform. Using this, your updateAudio() function will be portable across different CPU and
123  * different output methods, including external DACs.
124  * b) The struct provides some convenience API on top of this. Right now, this is the function clip(), replacing the more verbose, and non-portable constrain(x, -244, 243)
125  * found in some old sketches.
126  * c) The struct provides accessors l() and r() that are source-compatible with StereoOutput, making it easy to e.g. implement support for an external DAC in both mono
127  * and stereo.
128  * d) Finally, an automatic conversion operator to int aka AudioOutput_t provides backward compatibility with old Mozzi sketches. Internally, the compiler will actually
129  * do away with this wholw struct, leaving just the same basic fast integer operations as in older Mozzi sketches. However, now, you don't have to rewrite those for
130  * different configurations.
131  */
132 struct MonoOutput {
133  /** Construct an audio frame from raw values (zero-centered) */
135 #if (AUDIO_CHANNELS > 1)
136  /** Conversion to stereo operator: If used in a stereo config, returns identical channels (and gives a compile time warning).
137  This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
138  using StereoOutput in a mono config, is not intended. */
139  inline StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check mozzi_config.h."))) { return StereoOutput(_l, _l); };
140 #else
141  /** Conversion to int operator. */
142  inline operator AudioOutput_t() const { return _l; };
143 #endif
144  AudioOutputStorage_t l() const { return _l; };
145  AudioOutputStorage_t r() const { return _l; };
146  /** Clip frame to supported range. This is useful when at times, but only rarely, the signal may exceed the usual range. Using this function does not avoid
147  * artifacts, entirely, but gives much better results than an overflow. */
148  MonoOutput& clip() { _l = CLIP_AUDIO(_l); return *this; };
149 
150  /** Construct an audio frame a zero-centered value known to be in the N bit range. Appropriate left- or right-shifting will be performed, based on the number of output
151  * bits available. While this function takes care of the shifting, beware of potential overflow issues, if your intermediary results exceed the 16 bit range. Use proper
152  * casts to int32_t or larger in that case (and the compiler will automatically pick the 32 bit overload in this case) */
153  template<typename T> static inline MonoOutput fromNBit(uint8_t bits, T l) { return MonoOutput(SCALE_AUDIO(l, bits)); }
154  /** Construct an audio frame from a zero-centered value known to be in the 8 bit range. On AVR, STANDADR or STANDARD_PLUS mode, this is effectively the same as calling the
155  * constructor, directly (no scaling gets applied). On platforms/configs using more bits, an appropriate left-shift will be performed. */
156  static inline MonoOutput from8Bit(int16_t l) { return fromNBit(8, l); }
157  /** Construct an audio frame a zero-centered value known to be in the 16 bit range. This is jsut a shortcut for fromNBit(16, ...) provided for convenience. */
158  static inline MonoOutput from16Bit(int16_t l) { return fromNBit(16, l); }
159  /** Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit range, e.g. at N=8 bits and a litte. On most platforms, this is
160  * exactly the same as fromNBit(), shifting up or down to the platforms' available resolution.
161  *
162  * However, on AVR, STANDARD(_PLUS) (where about 8.5 bits are usable), the value will be shifted to the (almost) 9 bit range, instead of to the 8 bit range. allowing to
163  * make use of that extra half bit of resolution. In many cases it is useful to follow up this call with clip().
164  *
165  * @example fromAlmostNBit(10, oscilA.next() + oscilB.next() + oscilC.next());
166  */
167  template<typename A, typename B> static inline MonoOutput fromAlmostNBit(A bits, B l) { return MonoOutput(SCALE_AUDIO_NEAR(l, bits)); }
168 
169 private:
171 };
172 
173 
174 /** When setting EXTERNAL_AUDIO_OUTPUT to true, implement this function to take care of writing samples to the hardware. */
175 void audioOutput(const AudioOutput f);
176 #if BYPASS_MOZZI_OUTPUT_BUFFER
177 /** When setting BYPASS_MOZZI_OUTPUT_BUFFER to true, implement this function to return true, if and only if your hardware (or custom buffer) is ready to accept the next sample. */
178 inline bool canBufferAudioOutput();
179 #endif
180 
181 /** Perform one step of (fast) pdm encoding, returning 8 "bits" (i.e. 8 ones and zeros).
182  * You will usually call this at least four or eight times for a single input sample.
183  *
184  * The return type is defined as uint32_t to avoid conversion steps. Actually, only the 8 lowest
185  * bits of the return value are set. */
186 inline uint32_t pdmCode8(uint16_t sample) {
187  // lookup table for fast pdm coding on 8 output bits at a time
188  static const byte fast_pdm_table[]{0, 0b00010000, 0b01000100,
189  0b10010010, 0b10101010, 0b10110101,
190  0b11011101, 0b11110111, 0b11111111};
191 
192  static uint32_t lastwritten = 0;
193  static uint32_t nexttarget = 0;
194  // in each iteration, code the highest 3-and-a-little bits.
195  // Note that sample only has 16 bits, while the
196  // highest bit we consider for writing is bit 17.
197  // Thus, if the highest bit is set, the next
198  // three bits cannot be.
199  nexttarget += sample;
200  nexttarget -= lastwritten;
201  lastwritten = nexttarget & 0b11110000000000000;
202  return fast_pdm_table[lastwritten >> 13];
203 }
204 
205 /** Convenience function to perform four iterations of pdmCode8() */
206 inline uint32_t pdmCode32(uint16_t sample) {
207  uint32_t outbits = 0;
208  for (uint8_t i = 0; i < 4; ++i) {
209  outbits = outbits << 8;
210  outbits |= pdmCode8(sample);
211  }
212  return outbits;
213 }
214 
215 #if (EXTERNAL_AUDIO_OUTPUT == true)
216 #warning "Mozzi is configured to use an external void 'audioOutput(const AudioOutput f)' function. Please define one in your sketch"
217 #endif
218 
219 #endif
static MonoOutput from16Bit(int16_t l)
Construct an audio frame a zero-centered value known to be in the 16 bit range.
Definition: AudioOutput.h:158
-
StereoOutput & clip()
Definition: AudioOutput.h:103
-
#define SCALE_AUDIO_NEAR(x, bits)
Definition: AudioOutput.h:54
-
static StereoOutput fromNBit(uint8_t bits, T l, T r)
Definition: AudioOutput.h:106
-
StereoOutput()
Default contstructor.
Definition: AudioOutput.h:93
-
static MonoOutput from8Bit(int16_t l)
Construct an audio frame from a zero-centered value known to be in the 8 bit range.
Definition: AudioOutput.h:156
-
#define AUDIO_MODE
AUDIO_MODE holds the audio mode setting.
Definition: mozzi_config.h:28
-
#define AUDIO_CHANNELS
This sets allows to change from a single/mono audio output channel to stereo output.
Definition: mozzi_config.h:92
-
This struct encapsulates one frame of mono audio output.
Definition: AudioOutput.h:132
-
MonoOutput(AudioOutputStorage_t l=0)
Construct an audio frame from raw values (zero-centered)
Definition: AudioOutput.h:134
-
static StereoOutput from8Bit(int16_t l, int16_t r)
Definition: AudioOutput.h:108
-
AudioOutput_t portable() const __attribute__((deprecated("Sketch generates stereo output
Conversion to int operator: If used in a mono config, returns only the left channel (and gives a comp...
-
#define STANDARD_PLUS
Definition: MozziGuts.h:165
-
MonoOutput & clip()
Clip frame to supported range.
Definition: AudioOutput.h:148
-
#define AudioOutput
Representation of an single audio output sample/frame.
Definition: AudioOutput.h:84
-
#define IS_AVR()
-
#define SCALE_AUDIO(x, bits)
Definition: AudioOutput.h:53
-
This struct encapsulates one frame of mono audio output.
Definition: AudioOutput.h:89
-
static StereoOutput from16Bit(int16_t l, int16_t r)
Definition: AudioOutput.h:110
-
operator AudioOutput_t() const
Conversion to int operator.
Definition: AudioOutput.h:142
-
#define STEREO
Definition: MozziGuts.h:170
-
StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r)
Construct an audio frame from raw values (zero-centered)
Definition: AudioOutput.h:91
-
#define AudioOutput_t
Representation of an single audio output sample/frame.
Definition: AudioOutput.h:77
-
#define STANDARD
Used to set AUDIO_MODE to STANDARD, STANDARD_PLUS, or HIFI.
Definition: MozziGuts.h:164
-
#define EXTERNAL_AUDIO_OUTPUT
Defining this option as true in mozzi_config.h allows to completely customize the audio output...
Definition: mozzi_config.h:99
-
static StereoOutput fromAlmostNBit(A bits, B l, B r)
Definition: AudioOutput.h:112
-
static MonoOutput fromNBit(uint8_t bits, T l)
Construct an audio frame a zero-centered value known to be in the N bit range.
Definition: AudioOutput.h:153
-
#define CLIP_AUDIO(x)
Definition: AudioOutput.h:55
-
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:46
+
1 /** @defgroup audio_output Audio Output and Buffering
2  *
3  * @details Documentation on basic Mozzi architecture and output modes */
4 
5 /** @ingroup audio_output
6  * @page mozzi_audio_output_architecture Basic architecture of audio generation, buffering, and output in Mozzi
7  *
8  * Mozzi provides support for audio ouput on a range of different boards and CPUs. This page is about the following related topics:
9  *
10  * - adding a custom output method (importantly using external DACs) to your sketch
11  * - writing sketches that will work on different platforms / with different output methods
12  * - extending Mozzi for a new architecture
13  *
14  * For all of these topics, it is helpful to have a basic understanding of the basic output steps in Mozzi:
15  *
16  * 1. Inside the loop() function in your sketch you call audioHook().
17  * 1a. If the audio output buffer is currently filled, this does nothing.
18  * 1b. Otherwise, this calls updateAudio(). The generated sample is then added to the audio output buffer. (Also, updateControl() will be called at an appropriate rate,
19  * and a few other details that are not important for this discussion.)
20  *
21  * 2. A platform-specific timer is triggered at audio rate (usually), takes a sample from the output buffer and sends it to audioOutput().
22  *
23  * 3. The audioOutput() function - usually predefined inside Mozzi - takes care of sending the sample to the hardware.
24  *
25  * These output steps are not always followed, however. Firstly, when using @ref external_audio output, the audioOutput() funtion is supplied by the user sketch,
26  * instead of Mozzi. @ref external_audio output.
27  *
28  * Some ports will also want to bypass the Mozzi audio output buffer. For instance, an internal DAC may be addressable via an efficient DMA-connected
29  * buffer, already, and also have a built-in rate control. In this case, ports will internally set the define @ref BYPASS_MOZZI_OUTPUT_BUFFER to true. Such a port will
30  * have to provide a custom definition of canBufferAudioOutput(), returning true, whenever a new sample of output can be accepted. No timer at audio-rate is set up in this
31  * case.
32  *
33  * Finally, the @ref external_audio output mode (@ref MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM) is essentially a combination of the two. Here, the user sketch needs to provide
34  * both audioOutput() and canBufferAudioOutput(). The latter is again called from audioHook(), and whenever it returns true, a new sample is generated and passed to
35  * audioOutput().
36  *
37  * @section audio_shifting Platform specific audio resolution
38  * Different output methods often support a different resolution of output samples. To provide best performance on slow boards, Mozzi expects your updateAudio() function to
39  * return samples in exactly the width that is needed at the output stage. Thus, defining this naively, an updateAudio() function designed for 8 bit output will produce very
40  * low volume output on a 16 bit DAC, while the other way around overflows will result in way too loud and heavily distored output. Fortunately, all that is needed to write
41  * portable sketches is to specify how many bits your updateAudio() function provides. The (inline) functions in the AudioOutput namespace do just that. Using them makes sure
42  * your audio output is shifted if, and as much as needed on all platforms.
43  *
44  * @see MonoOutput::fromNBit(), StereoOutput::fromNBit()
45  */
46 
47 #ifndef AUDIOOUTPUT_H
48 #define AUDIOOUTPUT_H
49 
50 /** The type used to store a single channel of a single frame, internally. For compatibility with earlier versions of Mozzi this is defined as int.
51  * If you do not care about keeping old sketches working, you may be able to save some RAM by using int16_t, instead (on boards where int is larger
52  * than 16 bits). */
53 #define AudioOutputStorage_t int
54 
55 template<typename T> constexpr AudioOutputStorage_t SCALE_AUDIO(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS ? (x) >> (bits - MOZZI_AUDIO_BITS) : (x) << (MOZZI_AUDIO_BITS - bits)); }
56 template<typename T> constexpr AudioOutputStorage_t SCALE_AUDIO_NEAR(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS_OPTIMISTIC ? (x) >> (bits - MOZZI_AUDIO_BITS_OPTIMISTIC) : (x) << (MOZZI_AUDIO_BITS_OPTIMISTIC - bits)); }
57 template<typename T> constexpr AudioOutputStorage_t CLIP_AUDIO(T x) { return (constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) (MOZZI_AUDIO_BIAS-1))); }
58 
59 struct MonoOutput;
60 struct StereoOutput;
61 
62 #if MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO)
63 typedef StereoOutput AudioOutput;
64 #else
65 /** Representation of an single audio output sample/frame. This typedef maps to either MonoOutput or StereoOutput, depending on what is configured
66  * in MOZZI_AUDIO_CHANNELS. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g.
67  * both have functions l() and r(), to return "two" audio channels (which will be the same in case of mono).
68  *
69  * You will not usually use or encounter this definition, unless using @ref external_audio output mode.
70  */
71 typedef MonoOutput AudioOutput;
72 #endif
73 
74 #if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST
75 #if (MOZZI_COMPATIBILITY_LEVEL <= MOZZI_COMPATIBILITY_1_1) && MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_MONO)
76 typedef int AudioOutput_t; // Note: Needed for pre 1.1 backwards compatibility
77 #else
78 /** Transitory alias to AudioOutput. The only point of this typedef is to keep old code working. In new code,
79  * use AudioOutput, directly, instead.
80 */
81 MOZZI_DEPRECATED("2.0", "Replace AudioOutput_t with simple AudioOutput") typedef AudioOutput AudioOutput_t;
82 #endif
83 #endif
84 
85 /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to a single int value, but the struct provides
86  * useful API an top of that, for the following:
87  *
88  * a) To construct an output frame, you should use one of the from8Bit(), fromNBit(), etc. functions. Given a raw input value, at a known resolution (number of bits),
89  * this scales the output efficiently to whatever is needed on the target platform. Using this, your updateAudio() function will be portable across different CPU and
90  * different output methods, including external DACs.
91  * b) The struct provides some convenience API on top of this. Right now, this is the function clip(), replacing the more verbose, and non-portable constrain(x, -244, 243)
92  * found in some old sketches.
93  * c) The struct provides accessors l() and r() that are source-compatible with StereoOutput, making it easy to e.g. implement support for an external DAC in both mono
94  * and stereo.
95  * d) Finally, an automatic conversion operator to int aka AudioOutput_t provides backward compatibility with old Mozzi sketches. Internally, the compiler will actually
96  * do away with this whole struct, leaving just the same basic fast integer operations as in older Mozzi sketches. However, now, you don't have to rewrite those for
97  * different configurations.
98  */
99 struct MonoOutput {
100  /** Default constructor. Does not initialize the sample! */
102  /** Construct an audio frame from raw values (zero-centered) */
104 #if (MOZZI_AUDIO_CHANNELS > 1)
105  /** Conversion to stereo operator: If used in a stereo config, returns identical channels (and gives a compile time warning).
106  This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
107  using StereoOutput in a mono config, is not intended. */
108  StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check MOZZI_AUDIO_CHANNELS setting."))); // Note: defintion below
109 #endif
110  /** Conversion to int operator. */
111  operator AudioOutputStorage_t() const { return _l; };
112 
113  AudioOutputStorage_t l() const { return _l; };
114  AudioOutputStorage_t r() const { return _l; };
115  /** Clip frame to supported range. This is useful when at times, but only rarely, the signal may exceed the usual range. Using this function does not avoid
116  * artifacts, entirely, but gives much better results than an overflow. */
117  MonoOutput& clip() { _l = CLIP_AUDIO(_l); return *this; };
118 
119  /** Construct an audio frame a zero-centered value known to be in the N bit range. Appropriate left- or right-shifting will be performed, based on the number of output
120  * bits available. While this function takes care of the shifting, beware of potential overflow issues, if your intermediary results exceed the 16 bit range. Use proper
121  * casts to int32_t or larger in that case (and the compiler will automatically pick the 32 bit overload in this case) */
122  template<typename T> static inline MonoOutput fromNBit(uint8_t bits, T l) { return MonoOutput(SCALE_AUDIO(l, bits)); }
123  /** Construct an audio frame from a zero-centered value known to be in the 8 bit range. On AVR, if MOZZI_OUTPUT_PWM mode, this is effectively the same as calling the
124  * constructor, directly (no scaling gets applied). On platforms/configs using more bits, an appropriate left-shift will be performed. */
125  static inline MonoOutput from8Bit(int16_t l) { return fromNBit(8, l); }
126  /** Construct an audio frame a zero-centered value known to be in the 16 bit range. This is jsut a shortcut for fromNBit(16, ...) provided for convenience. */
127  static inline MonoOutput from16Bit(int16_t l) { return fromNBit(16, l); }
128  /** Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit range, e.g. at N=8 bits and a litte. On most platforms, this is
129  * exactly the same as fromNBit(), shifting up or down to the platforms' available resolution.
130  *
131  * However, on AVR, MOZZI_OUTPUT_PWM mode (where about 8.5 bits are usable), the value will be shifted to the (almost) 9 bit range, instead of to the 8 bit range. allowing to
132  * make use of that extra half bit of resolution. In many cases it is useful to follow up this call with clip(). E.g.:
133  *
134  * @code
135  * return MonoOutput::fromAlmostNBit(10, oscilA.next() + oscilB.next() + oscilC.next()).clip();
136  * @endcode
137  */
138  template<typename A, typename B> static inline MonoOutput fromAlmostNBit(A bits, B l) { return MonoOutput(SCALE_AUDIO_NEAR(l, bits)); }
139 
140 private:
142 };
143 
144 /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to two int values, but the struct provides
145  * useful API an top of that. For more detail see @ref MonoOutput . */
146 struct StereoOutput {
147  /** Construct an audio frame from raw values (zero-centered) */
149  /** Default constructor. Does not initialize the sample! */
151 #if !MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO)
152  /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning).
153  This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
154  using StereoOutput in a mono config, is not intended. */
155  inline AudioOutput portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; };
156 # if GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO
157  inline operator AudioOutput() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; };
158 # endif
159 #endif
160  AudioOutputStorage_t l() const { return _l; };
161  AudioOutputStorage_t r() const { return _r; };
162  /** See @ref MonoOutput::clip(). Clips both channels. */
163  StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; };
164 
165  /** See @ref MonoOutput::fromNBit(), stereo variant */
166 template<typename T> static inline StereoOutput fromNBit(uint8_t bits, T l, T r) { return StereoOutput(SCALE_AUDIO(l, bits), SCALE_AUDIO(r, bits)); }
167  /** See @ref MonoOutput::from8Bit(), stereo variant */
168  static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); }
169  /** See @ref MonoOutput::from16Bit(), stereo variant */
170  static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); }
171  /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */
172  template<typename A, typename B> static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); }
173 private:
176 };
177 
178 #if MOZZI_AUDIO_CHANNELS > 1
179 StereoOutput MonoOutput::portable() const { return StereoOutput(_l, _l); };
180 #endif
181 
182 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
183 /** When setting using one of the external output modes (@ref MOZZI_OUTPUT_EXTERNAL_TIMED or @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM) implement this function to take care of writing samples to the hardware.
184  * In all otther cases, it will be provided by the platform implementation. You should never call this function, directly, in your sketch. */
185 void audioOutput(const AudioOutput f);
186 #endif
187 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
188 /** For @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM implement this function to return true, if and only if your hardware (or custom buffer) is ready to accept the next sample. */
189 inline bool canBufferAudioOutput();
190 #endif
191 
192 /** Perform one step of (fast) pdm encoding, returning 8 "bits" (i.e. 8 ones and zeros).
193  * You will usually call this at least four or eight times, and possibly much more often
194  * for a single input sample.
195  *
196  * The return type is defined as uint32_t to avoid conversion steps. Actually, only the 8 lowest
197  * bits of the return value are set. */
198 inline uint32_t pdmCode8(uint16_t sample) {
199  // lookup table for fast pdm coding on 8 output bits at a time
200  static const byte fast_pdm_table[]{0, 0b00010000, 0b01000100,
201  0b10010010, 0b10101010, 0b10110101,
202  0b11011101, 0b11110111, 0b11111111};
203 
204  static uint32_t lastwritten = 0;
205  static uint32_t nexttarget = 0;
206  // in each iteration, code the highest 3-and-a-little bits.
207  // Note that sample only has 16 bits, while the
208  // highest bit we consider for writing is bit 17.
209  // Thus, if the highest bit is set, the next
210  // three bits cannot be. (highest possible values:
211  // nexttarget-lastwritten == 0b00001111111111111,
212  // sample == 0b01111111111111111)
213  nexttarget += sample;
214  nexttarget -= lastwritten;
215  lastwritten = nexttarget & 0b11110000000000000;
216  return fast_pdm_table[lastwritten >> 13];
217 }
218 
219 /** Convenience function to perform four iterations of pdmCode8() */
220 inline uint32_t pdmCode32(uint16_t sample) {
221  uint32_t outbits = 0;
222  for (uint8_t i = 0; i < 4; ++i) {
223  outbits = outbits << 8;
224  outbits |= pdmCode8(sample);
225  }
226  return outbits;
227 }
228 
229 #endif
static MonoOutput from16Bit(int16_t l)
Construct an audio frame a zero-centered value known to be in the 16 bit range.
Definition: AudioOutput.h:127
+
static MonoOutput fromAlmostNBit(A bits, B l)
Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit ra...
Definition: AudioOutput.h:138
+
StereoOutput & clip()
See MonoOutput::clip().
Definition: AudioOutput.h:163
+
static StereoOutput fromNBit(uint8_t bits, T l, T r)
See MonoOutput::fromNBit(), stereo variant.
Definition: AudioOutput.h:166
+
StereoOutput()
Default constructor.
Definition: AudioOutput.h:150
+
static MonoOutput from8Bit(int16_t l)
Construct an audio frame from a zero-centered value known to be in the 8 bit range.
Definition: AudioOutput.h:125
+
AudioOutput portable() const __attribute__((deprecated("Sketch generates stereo output
Conversion to int operator: If used in a mono config, returns only the left channel (and gives a comp...
+
This struct encapsulates one frame of mono audio output.
Definition: AudioOutput.h:99
+
static StereoOutput from8Bit(int16_t l, int16_t r)
See MonoOutput::from8Bit(), stereo variant.
Definition: AudioOutput.h:168
+
MonoOutput()
Default constructor.
Definition: AudioOutput.h:101
+
MonoOutput(AudioOutputStorage_t l)
Construct an audio frame from raw values (zero-centered)
Definition: AudioOutput.h:103
+
MonoOutput & clip()
Clip frame to supported range.
Definition: AudioOutput.h:117
+
static StereoOutput from16Bit(int16_t l, int16_t r)
See MonoOutput::from16Bit(), stereo variant.
Definition: AudioOutput.h:170
+
operator AudioOutputStorage_t() const
Conversion to int operator.
Definition: AudioOutput.h:111
+
StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r)
Construct an audio frame from raw values (zero-centered)
Definition: AudioOutput.h:148
+
static StereoOutput fromAlmostNBit(A bits, B l, B r)
See MonoOutput::fromAlmostNBit(), stereo variant.
Definition: AudioOutput.h:172
+
static MonoOutput fromNBit(uint8_t bits, T l)
Construct an audio frame a zero-centered value known to be in the N bit range.
Definition: AudioOutput.h:122
+
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:53
-
1 /*
2  * AutoMap.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUTOMAP_H_
13 #define AUTOMAP_H_
14 
15 // for map - maybe rewrite my own templated map for better efficiency
16 #if ARDUINO >= 100
17  #include "Arduino.h" // for map
18 #else
19  #include "WProgram.h"
20 #endif
21 
22 #include "AutoRange.h"
23 
24 /** @ingroup sensortools
25 Automatically map an input value to an output range without knowing the precise range of inputs beforehand.
26 */
27 
28 class AutoMap : public AutoRange<int>
29 {
30 public:
31  /** Constructor.
32  @param min_expected the minimum possible input value.
33  @param max_expected the maximum possible input value.
34  */
35  AutoMap(int min_expected, int max_expected, int map_to_min, int map_to_max)
36  : inherited(min_expected,max_expected),map_min(map_to_min), map_max(map_to_max)
37  {
38  }
39 
40 
41  /** Process the next value and return it mapped to the range which was set in the constructor.
42  Can use the operator instead if you prefer, eg. myMap(n) instead of myMap.next(n).
43  @param n the next value to process.
44  @return the input value mapped to the range which was set in the constructor.
45  */
46  inline
47  int next(int n)
48  {
49  inherited::next(n);
50  return map(n,inherited::getMin(),inherited::getMax(),map_min,map_max);
51  }
52 
53  /** Process the next value and return it mapped to the range which was set in the constructor.
54  This is an alternative to next() if you prefer, eg. myMap(n) instead of myMap.next(n).
55  @param n the next value to process.
56  @return the input value mapped to the range which was set in the constructor.
57  */
58  inline
59  int operator()(int n)
60  {
61  return next(n);
62  }
63 
64 
65 private:
66  typedef AutoRange <int> inherited;
67  int map_min, map_max;
68 };
69 
70 
71 /**
72 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
73 This example demonstrates the AutoMap class.
74 */
75 
76 #endif // #ifndef AUTOMAP_H_
int next(int n)
Process the next value and return it mapped to the range which was set in the constructor.
Definition: AutoMap.h:47
-
int operator()(int n)
Process the next value and return it mapped to the range which was set in the constructor.
Definition: AutoMap.h:59
-
Automatically map an input value to an output range without knowing the precise range of inputs befor...
Definition: AutoMap.h:28
-
Keeps a running calculation of the range of the input values it receives.
Definition: AutoRange.h:18
-
AutoMap(int min_expected, int max_expected, int map_to_min, int map_to_max)
Constructor.
Definition: AutoMap.h:35
-
void next(T n)
Updates the current range.
Definition: AutoRange.h:35
-
AutoRange(T min_expected, T max_expected)
Constructor.
Definition: AutoRange.h:27
+
1 /*
2  * AutoMap.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUTOMAP_H_
13 #define AUTOMAP_H_
14 
15 // for map - maybe rewrite my own templated map for better efficiency
16 #include <Arduino.h> // for map
17 
18 #include "AutoRange.h"
19 
20 /** @defgroup sensortools Automatic range adjustment
21 */
22 
23 /** @ingroup sensortools
24 Automatically map an input value to an output range without knowing the precise range of inputs beforehand.
25 */
26 
27 class AutoMap : public AutoRange<int>
28 {
29 public:
30  /** Constructor.
31  @param min_expected the minimum possible input value.
32  @param max_expected the maximum possible input value.
33  */
34  AutoMap(int min_expected, int max_expected, int map_to_min, int map_to_max)
35  : inherited(min_expected,max_expected),map_min(map_to_min), map_max(map_to_max)
36  {
37  }
38 
39 
40  /** Process the next value and return it mapped to the range which was set in the constructor.
41  Can use the operator instead if you prefer, eg. myMap(n) instead of myMap.next(n).
42  @param n the next value to process.
43  @return the input value mapped to the range which was set in the constructor.
44  */
45  inline
46  int next(int n)
47  {
48  inherited::next(n);
49  return map(n,inherited::getMin(),inherited::getMax(),map_min,map_max);
50  }
51 
52  /** Process the next value and return it mapped to the range which was set in the constructor.
53  This is an alternative to next() if you prefer, eg. myMap(n) instead of myMap.next(n).
54  @param n the next value to process.
55  @return the input value mapped to the range which was set in the constructor.
56  */
57  inline
58  int operator()(int n)
59  {
60  return next(n);
61  }
62 
63 
64 private:
65  typedef AutoRange <int> inherited;
66  int map_min, map_max;
67 };
68 
69 
70 /**
71 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
72 This example demonstrates the AutoMap class.
73 */
74 
75 #endif // #ifndef AUTOMAP_H_
AutoRange(T min_expected, T max_expected)
Constructor.
Definition: AutoRange.h:27
+
void next(T n)
Updates the current range.
Definition: AutoRange.h:35
+
int next(int n)
Process the next value and return it mapped to the range which was set in the constructor.
Definition: AutoMap.h:46
+
Keeps a running calculation of the range of the input values it receives.
Definition: AutoRange.h:18
+
AutoMap(int min_expected, int max_expected, int map_to_min, int map_to_max)
Constructor.
Definition: AutoMap.h:34
+
Automatically map an input value to an output range without knowing the precise range of inputs befor...
Definition: AutoMap.h:27
+
int operator()(int n)
Process the next value and return it mapped to the range which was set in the constructor.
Definition: AutoMap.h:58
-
1 /*
2  * AutoRange.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 #ifndef AUTORANGE_H
12 #define AUTORANGE_H
13 
14 /** @ingroup sensortools
15 Keeps a running calculation of the range of the input values it receives.
16 */
17 template <class T>
18 class
19  AutoRange {
20 
21 public:
22  /** Constructor.
23  @tparam T the type of numbers to to use, eg. int, unsigned int, float etc.
24  @param min_expected the minimum possible input value.
25  @param max_expected the maximum possible input value.
26  */
27  AutoRange(T min_expected, T max_expected):range_min(max_expected),range_max(min_expected),range(0)
28  {
29  }
30 
31 
32  /** Updates the current range.
33  @param n the next value to include in the range calculation.
34  */
35  void next(T n)
36  {
37  if (n > range_max)
38  {
39  range_max = n;
40  range = range_max - range_min;
41  }
42  else
43  {
44  if (n< range_min)
45  {
46  range_min = n;
47  range = range_max - range_min;
48  }
49  }
50  }
51 
52  /** Returns the current minimum.
53  @return minimum
54  */
55  T getMin()
56  {
57  return range_min;
58  }
59 
60 
61  /** Returns the current maximum.
62  @return maximum
63  */
64  T getMax()
65  {
66  return range_max;
67  }
68 
69 
70  /** Returns the current range.
71  @return range
72  */
74  {
75  return range;
76  }
77 
78 private:
79  T range_max, range_min, range;
80 
81 };
82 
83 #endif // #ifndef AUTORANGE_H
T getRange()
Returns the current range.
Definition: AutoRange.h:73
-
T getMax()
Returns the current maximum.
Definition: AutoRange.h:64
-
T getMin()
Returns the current minimum.
Definition: AutoRange.h:55
-
Keeps a running calculation of the range of the input values it receives.
Definition: AutoRange.h:18
-
void next(T n)
Updates the current range.
Definition: AutoRange.h:35
-
AutoRange(T min_expected, T max_expected)
Constructor.
Definition: AutoRange.h:27
+
1 /*
2  * AutoRange.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 #ifndef AUTORANGE_H
12 #define AUTORANGE_H
13 
14 /** @ingroup sensortools
15 Keeps a running calculation of the range of the input values it receives.
16 */
17 template <class T>
18 class
19  AutoRange {
20 
21 public:
22  /** Constructor.
23  @tparam T the type of numbers to to use, eg. int, unsigned int, float etc.
24  @param min_expected the minimum possible input value.
25  @param max_expected the maximum possible input value.
26  */
27  AutoRange(T min_expected, T max_expected):range_min(max_expected),range_max(min_expected),range(0)
28  {
29  }
30 
31 
32  /** Updates the current range.
33  @param n the next value to include in the range calculation.
34  */
35  void next(T n)
36  {
37  if (n > range_max)
38  {
39  range_max = n;
40  range = range_max - range_min;
41  }
42  else
43  {
44  if (n< range_min)
45  {
46  range_min = n;
47  range = range_max - range_min;
48  }
49  }
50  }
51 
52  /** Returns the current minimum.
53  @return minimum
54  */
55  T getMin()
56  {
57  return range_min;
58  }
59 
60 
61  /** Returns the current maximum.
62  @return maximum
63  */
64  T getMax()
65  {
66  return range_max;
67  }
68 
69 
70  /** Returns the current range.
71  @return range
72  */
74  {
75  return range;
76  }
77 
78 private:
79  T range_max, range_min, range;
80 
81 };
82 
83 #endif // #ifndef AUTORANGE_H
T getMax()
Returns the current maximum.
Definition: AutoRange.h:64
+
AutoRange(T min_expected, T max_expected)
Constructor.
Definition: AutoRange.h:27
+
T getRange()
Returns the current range.
Definition: AutoRange.h:73
+
void next(T n)
Updates the current range.
Definition: AutoRange.h:35
+
Keeps a running calculation of the range of the input values it receives.
Definition: AutoRange.h:18
+
T getMin()
Returns the current minimum.
Definition: AutoRange.h:55
-
1 /*
2 Modified from https://en.wikipedia.org/wiki/Circular_buffer
3 Mirroring version
4 On 18 April 2014, the simplified version on the Wikipedia page for power of 2 sized buffers
5 doesn't work - cbIsEmpty() returns true whether the buffer is full or empty.
6 */
7 
8 /** Circular buffer object. Has a fixed number of cells, set to 256.
9 @tparam ITEM_TYPE the kind of data to store, eg. int, int8_t etc.
10 */
11 template <class ITEM_TYPE>
13 {
14 
15 public:
16  /** Constructor
17  */
19  {
20  }
21 
22  inline
23  bool isFull() {
24  return end == start && e_msb != s_msb;
25  }
26 
27  inline
28  bool isEmpty() {
29  return end == start && e_msb == s_msb;
30  }
31 
32  inline
33  void write(ITEM_TYPE in) {
34  items[end] = in;
35  //if (isFull()) cbIncrStart(); /* full, overwrite moves start pointer */
36  cbIncrEnd();
37  }
38 
39  inline
40  ITEM_TYPE read() {
41  ITEM_TYPE out = items[start];
42  cbIncrStart();
43  return out;
44  }
45 
46  inline
47  unsigned long count() {
48  return (num_buffers_read << 8) + start;
49  }
50 
51 private:
52  ITEM_TYPE items[256];
53  uint8_t start; /* index of oldest itement */
54  uint8_t end; /* index at which to write new itement */
55  uint8_t s_msb;
56  uint8_t e_msb;
57  unsigned long num_buffers_read;
58 
59 
60  inline
61  void cbIncrStart() {
62  start++;
63  if (start == 0) {
64  s_msb ^= 1;
65  num_buffers_read++;
66  }
67  }
68 
69  inline
70  void cbIncrEnd() {
71  end++;
72  if (end == 0) e_msb ^= 1;
73  }
74 
75 };
CircularBuffer()
Constructor.
-
Circular buffer object.
+
1 /*
2 Modified from https://en.wikipedia.org/wiki/Circular_buffer
3 Mirroring version
4 On 18 April 2014, the simplified version on the Wikipedia page for power of 2 sized buffers
5 doesn't work - cbIsEmpty() returns true whether the buffer is full or empty.
6 */
7 
8 #define MOZZI_BUFFER_SIZE 256 // do not expect to change and it to work.
9  // just here for forward compatibility if one day
10  // the buffer size might be editable
11 
12 /** Circular buffer object. Has a fixed number of cells, set to 256.
13 @tparam ITEM_TYPE the kind of data to store, eg. int, int8_t etc.
14 */
15 template <class ITEM_TYPE>
17 {
18 
19 public:
20  /** Constructor
21  */
23  {
24  }
25 
26  inline
27  bool isFull() {
28  return end == start && e_msb != s_msb;
29  }
30 
31  inline
32  bool isEmpty() {
33  return end == start && e_msb == s_msb;
34  }
35 
36  inline
37  void write(ITEM_TYPE in) {
38  items[end] = in;
39  //if (isFull()) cbIncrStart(); /* full, overwrite moves start pointer */
40  cbIncrEnd();
41  }
42 
43  inline
44  ITEM_TYPE read() {
45  ITEM_TYPE out = items[start];
46  cbIncrStart();
47  return out;
48  }
49 
50  inline
51  unsigned long count() {
52  return (num_buffers_read << 8) + start;
53  }
54  inline
55  ITEM_TYPE * address() {
56  return items;
57  }
58 
59 private:
60  ITEM_TYPE items[MOZZI_BUFFER_SIZE];
61  uint8_t start; /* index of oldest itement */
62  uint8_t end; /* index at which to write new itement */
63  uint8_t s_msb;
64  uint8_t e_msb;
65  unsigned long num_buffers_read;
66 
67 
68  inline
69  void cbIncrStart() {
70  start++;
71  if (start == 0) {
72  s_msb ^= 1;
73  num_buffers_read++;
74  }
75  }
76 
77  inline
78  void cbIncrEnd() {
79  end++;
80  if (end == 0) e_msb ^= 1;
81  }
82 
83 };
CircularBuffer()
Constructor.
+
#define MOZZI_BUFFER_SIZE
Definition: CircularBuffer.h:8
+
Circular buffer object.
-
1 /*
2  * EventDelay.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef EVENTDELAY_H_
13 #define EVENTDELAY_H_
14 
15 
16 /** A non-blocking replacement for Arduino's delay() function.
17 EventDelay can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
18 Alternatively, start(milliseconds) will call set() and start() together.
19 */
21 {
22 
23 public:
24 
25  /** Constructor.
26  Declare an EventDelay object.
27  @param delay_milliseconds how long until ready() returns true, after calling start(). Defaults to 0 if no parameter is supplied.
28  */
29  EventDelay(unsigned int delay_milliseconds = 0): AUDIO_TICKS_PER_MILLISECOND((float)AUDIO_RATE/1000.0f)
30  {
31  set(delay_milliseconds);
32  }
33 
34 
35  /** Set the delay time. This setting is persistent, until you change it by using set() again.
36  @param delay_milliseconds delay time in milliseconds.
37  @note timing: 12us
38  */
39  inline
40  void set(unsigned int delay_milliseconds)
41  {
42  ticks = (unsigned long)(AUDIO_TICKS_PER_MILLISECOND*delay_milliseconds); // 12us
43  }
44 
45 
46  /** Start the delay.
47  @todo have a parameter to set whether it's single or repeating, so start doesn't have to be called for repeats.
48  Pro: simpler user programming. Con: would require an if..then every time ready() is called.
49  */
50  inline
51  void start()
52  {
53  deadline=audioTicks()+ticks;
54  }
55 
56 
57  /** Set the delay time and start the delay.
58  @param delay_milliseconds delay time in milliseconds.
59  */
60  inline
61  void start(unsigned int delay_milliseconds)
62  {
63  set(delay_milliseconds);
64  start();
65  }
66 
67 
68  /** Call this in updateControl() or updateAudio() to check if the delay time is up.
69  @return true if the time is up.
70  @note timing: 1us.
71  */
72  inline
73  bool ready()
74  {
75  return(audioTicks()>=deadline); // 1us
76  }
77 
78 
79 protected:
80  // Metronome accesses these
81  unsigned long deadline;
82  unsigned long ticks;
83 
84 private:
85  const float AUDIO_TICKS_PER_MILLISECOND;
86 };
87 
88 /**
89 @example 02.Control/EventDelay/EventDelay.ino
90 This example shows how to use the EventDelay class.
91 */
92 
93 #endif /* EVENTDELAY_H_ */
void start(unsigned int delay_milliseconds)
Set the delay time and start the delay.
Definition: EventDelay.h:61
+
1 /*
2  * EventDelay.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef EVENTDELAY_H_
13 #define EVENTDELAY_H_
14 
15 
16 /** A non-blocking replacement for Arduino's delay() function.
17 EventDelay can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
18 Alternatively, start(milliseconds) will call set() and start() together.
19 */
21 {
22 
23 public:
24 
25  /** Constructor.
26  Declare an EventDelay object.
27  @param delay_milliseconds how long until ready() returns true, after calling start(). Defaults to 0 if no parameter is supplied.
28  */
29  EventDelay(unsigned int delay_milliseconds = 0): AUDIO_TICKS_PER_MILLISECOND((float)MOZZI_AUDIO_RATE/1000.0f)
30  {
31  set(delay_milliseconds);
32  }
33 
34 
35  /** Set the delay time. This setting is persistent, until you change it by using set() again.
36  @param delay_milliseconds delay time in milliseconds.
37  @note timing: 12us
38  */
39  inline
40  void set(unsigned int delay_milliseconds)
41  {
42  ticks = (unsigned long)(AUDIO_TICKS_PER_MILLISECOND*delay_milliseconds); // 12us
43  }
44 
45 
46  /** Start the delay.
47  @todo have a parameter to set whether it's single or repeating, so start doesn't have to be called for repeats.
48  Pro: simpler user programming. Con: would require an if..then every time ready() is called.
49  */
50  inline
51  void start()
52  {
53  deadline=audioTicks()+ticks;
54  }
55 
56 
57  /** Set the delay time and start the delay.
58  @param delay_milliseconds delay time in milliseconds.
59  */
60  inline
61  void start(unsigned int delay_milliseconds)
62  {
63  set(delay_milliseconds);
64  start();
65  }
66 
67 
68  /** Call this in updateControl() or updateAudio() to check if the delay time is up.
69  @return true if the time is up.
70  @note timing: 1us.
71  */
72  inline
73  bool ready()
74  {
75  return(audioTicks()>=deadline); // 1us
76  }
77 
78 
79 protected:
80  // Metronome accesses these
81  unsigned long deadline;
82  unsigned long ticks;
83 
84 private:
85  const float AUDIO_TICKS_PER_MILLISECOND;
86 };
87 
88 /**
89 @example 02.Control/EventDelay/EventDelay.ino
90 This example shows how to use the EventDelay class.
91 */
92 
93 #endif /* EVENTDELAY_H_ */
void start(unsigned int delay_milliseconds)
Set the delay time and start the delay.
Definition: EventDelay.h:61
EventDelay(unsigned int delay_milliseconds=0)
Constructor.
Definition: EventDelay.h:29
void start()
Start the delay.
Definition: EventDelay.h:51
A non-blocking replacement for Arduino&#39;s delay() function.
Definition: EventDelay.h:20
@@ -115,7 +115,7 @@
-
1 
2 template<uint8_t BYTES> struct IntegerType {
3  // at an odd value, such as 3 bytes? Add one more byte (up to at most 8 bytes)..
4  typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::unsigned_type unsigned_type;
5  typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::signed_type signed_type;
6 };
7 
8 // These are the specializations for the types that we actually assume to exist:
9 template<> struct IntegerType<1> {
10  typedef uint8_t unsigned_type;
11  typedef int8_t signed_type;
12 };
13 
14 template<> struct IntegerType<2> {
15  typedef uint16_t unsigned_type;
16  typedef int16_t signed_type;
17 };
18 
19 template<> struct IntegerType<4> {
20  typedef uint32_t unsigned_type;
21  typedef int32_t signed_type;
22 };
23 
24 template<> struct IntegerType<8> {
25  typedef uint64_t unsigned_type;
26  typedef int64_t signed_type;
27 };
+
1 #ifndef INTTYPE_H_
2 #define INTTYPE_H_
3 
4 #include <Arduino.h>
5 
6 /** @ingroup util
7 Provides appropriate integer types that can bit the given number of bytes on this platform (at most 64).
8 */
9 template<uint8_t BYTES> struct IntegerType {
10  // at an odd value, such as 3 bytes? Add one more byte (up to at most 8 bytes)..
11  typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::unsigned_type unsigned_type;
12  typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::signed_type signed_type;
13 };
14 
15 // These are the specializations for the types that we actually assume to exist:
16 template<> struct IntegerType<1> {
17  typedef uint8_t unsigned_type;
18  typedef int8_t signed_type;
19 };
20 
21 template<> struct IntegerType<2> {
22  typedef uint16_t unsigned_type;
23  typedef int16_t signed_type;
24 };
25 
26 template<> struct IntegerType<4> {
27  typedef uint32_t unsigned_type;
28  typedef int32_t signed_type;
29 };
30 
31 template<> struct IntegerType<8> {
32  typedef uint64_t unsigned_type;
33  typedef int64_t signed_type;
34 };
35 
36 #endif /* INTTYPE_H_ */
Provides appropriate integer types that can bit the given number of bytes on this platform (at most 6...
Definition: IntegerType.h:9
-
1 /*
2  * Line.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef LINE_H_
13 #define LINE_H_
14 
15 #if ARDUINO >= 100
16  #include "Arduino.h"
17 #else
18  #include "WProgram.h"
19 #endif
20 
21 /** For linear changes with a minimum of calculation at each step. For instance,
22 you can use Line to make an oscillator glide from one frequency to another,
23 pre-calculating the required phase increments for each end and then letting your
24 Line change the phase increment with only a simple addition at each step.
25 @tparam T the type of numbers to use. For example, Line <int> myline; makes a
26 Line which uses ints.
27 @note Watch out for underflows in the internal calcualtion of Line() if you're not
28 using floats (but on the other hand try to avoid lots of floats, they're too slow!).
29 If it seems like the Line() is not working, there's a good chance you need to
30 scale up the numbers you're using, so internal calculations don't get truncated
31 away. Use Mozzi's fixed-point number types in mozzi_fixmath.h, which enable you to
32 represent fractional numbers. Google "fixed point arithmetic" if this is new to
33 you.
34 */
35 
36 template <class T>
37 class Line
38 {
39 private:
40  volatile T current_value; // volatile because it could be set in control interrupt and updated in audio
41  volatile T step_size;
42 
43 public:
44  /** Constructor. Use the template parameter to set the type of numbers you
45  want to use. For example, Line <int> myline; makes a Line which uses ints.
46  */
47  Line ()
48  {
49  ;
50  }
51 
52 
53 
54  /** Increments one step along the line.
55  @return the next value.
56  */
57  inline
58  T next()
59  {
60  current_value += step_size;
61  //Serial.println(current_value);
62  return current_value;
63  }
64 
65 
66 
67  /** Set the current value of the line.
68  The Line will continue incrementing from this
69  value using any previously calculated step size.
70  @param value the number to set the Line's current_value to.
71  */
72  inline
73  void set(T value)
74  {
75  current_value=value;
76  }
77 
78 
79 
80  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
81  @param targetvalue the value to move towards.
82  @param num_steps how many steps to take to reach the target.
83  */
84  inline
85  void set(T targetvalue, T num_steps)
86  {
87  if(num_steps) {
88  T numerator = targetvalue-current_value;
89  step_size= numerator/num_steps;
90  } else {
91  step_size = 0;
92  current_value = targetvalue;
93  }
94  }
95 
96  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
97  @param startvalue the number to set the Line's current_value to.
98  @param targetvalue the value to move towards.
99  @param num_steps how many steps to take to reach the target.
100  */
101  inline
102  void set(T startvalue, T targetvalue, T num_steps)
103  {
104  set(startvalue);
105  set(targetvalue, num_steps);
106  }
107 };
108 
109 
110 /* unsigned char specialisation (probably not very useful because step size will likely = 0) */
111 template <>
112 class Line <unsigned char>
113 {
114 private:
115  volatile unsigned char current_value; // volatile because it could be set in control interrupt and updated in audio
116  char step_size;
117 
118 public:
119  /** Constructor. Use the template parameter to set the type of numbers you
120  want to use. For example, Line <int> myline; makes a Line which uses ints.
121  */
122  Line ()
123  {
124  ;
125  }
126 
127 
128 
129  /** Increments one step along the line.
130  @return the next value.
131  */
132  inline
133  unsigned char next()
134  {
135  current_value += step_size;
136  return current_value;
137  }
138 
139 
140 
141  /** Set the current value of the line.
142  The Line will continue incrementing from this
143  value using any previously calculated step size.
144  @param value the number to set the Line's current_value to.
145  */
146  inline
147  void set(unsigned char value)
148  {
149  current_value=value;
150  }
151 
152 
153 
154  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
155  @param targetvalue the value to move towards.
156  @param num_steps how many steps to take to reach the target.
157  */
158  inline
159  void set(unsigned char targetvalue, unsigned char num_steps)
160  {
161  step_size=(char)((((float)targetvalue-current_value)/num_steps));
162  }
163 
164  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
165  @param startvalue the number to set the Line's current_value to.
166  @param targetvalue the value to move towards.
167  @param num_steps how many steps to take to reach the target.
168  */
169  inline
170  void set(unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)
171  {
172  set(startvalue);
173  set(targetvalue, num_steps);
174  }
175 
176 };
177 
178 
179 /* unsigned int specialisation */
180 template <>
181 class Line <unsigned int>
182 {
183 private:
184  volatile unsigned int current_value; // volatile because it could be set in control interrupt and updated in audio
185  int step_size;
186 
187 public:
188  /** Constructor. Use the template parameter to set the type of numbers you
189  want to use. For example, Line <int> myline; makes a Line which uses ints.
190  */
191  Line ()
192  {
193  ;
194  }
195 
196 
197 
198  /** Increments one step along the line.
199  @return the next value.
200  */
201  inline
202  unsigned int next()
203  {
204  current_value += step_size;
205  return current_value;
206  }
207 
208 
209 
210  /** Set the current value of the line.
211  The Line will continue incrementing from this
212  value using any previously calculated step size.
213  @param value the number to set the Line's current_value to.
214  */
215  inline
216  void set(unsigned int value)
217  {
218  current_value=value;
219  }
220 
221 
222 
223  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
224  @param targetvalue the value to move towards.
225  @param num_steps how many steps to take to reach the target.
226  */
227  inline
228  void set(unsigned int targetvalue, unsigned int num_steps)
229  {
230  step_size=(int)((((float)targetvalue-current_value)/num_steps));
231  }
232 
233 
234  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
235  @param startvalue the number to set the Line's current_value to.
236  @param targetvalue the value to move towards.
237  @param num_steps how many steps to take to reach the target.
238  */
239  inline
240  void set(unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)
241  {
242  set(startvalue);
243  set(targetvalue, num_steps);
244  }
245 };
246 
247 
248 
249 
250 
251 /* unsigned long specialisation */
252 template <>
253 class Line <unsigned long>
254 {
255 private:
256  volatile unsigned long current_value; // volatile because it could be set in control interrupt and updated in audio
257  long step_size;
258 
259 public:
260  /** Constructor. Use the template parameter to set the type of numbers you
261  want to use. For example, Line <int> myline; makes a Line which uses ints.
262  */
263  Line ()
264  {
265  ;
266  }
267 
268 
269 
270  /** Increments one step along the line.
271  @return the next value.
272  */
273  inline
274  unsigned long next()
275  {
276  current_value += step_size;
277  return current_value;
278  }
279 
280 
281 
282  /** Set the current value of the line.
283  The Line will continue incrementing from this
284  value using any previously calculated step size.
285  @param value the number to set the Line's current_value to.
286  */
287  inline
288  void set(unsigned long value)
289  {
290  current_value=value;
291  }
292 
293 
294 
295  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
296  @param targetvalue the value to move towards.
297  @param num_steps how many steps to take to reach the target.
298  */
299  inline
300  void set(unsigned long targetvalue, unsigned long num_steps)
301  {
302  step_size=(long)((((float)targetvalue-current_value)/num_steps));
303  }
304 
305  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
306  @param startvalue the number to set the Line's current_value to.
307  @param targetvalue the value to move towards.
308  @param num_steps how many steps to take to reach the target.
309  */
310  inline
311  void set(unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)
312  {
313  set(startvalue);
314  set(targetvalue, num_steps);
315  }
316 };
317 
318 /**
319 @example 02.Control/Control_Tremelo/Control_Tremelo.ino
320 This example demonstrates the Line class.
321 */
322 
323 #endif /* LINE_H_ */
void set(T value)
Set the current value of the line.
Definition: Line.h:73
-
Line()
Constructor.
Definition: Line.h:191
-
void set(unsigned int targetvalue, unsigned int num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:228
-
void set(unsigned long value)
Set the current value of the line.
Definition: Line.h:288
-
void set(unsigned long targetvalue, unsigned long num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:300
-
unsigned char next()
Increments one step along the line.
Definition: Line.h:133
-
void set(unsigned int value)
Set the current value of the line.
Definition: Line.h:216
-
void set(unsigned char value)
Set the current value of the line.
Definition: Line.h:147
-
void set(T startvalue, T targetvalue, T num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:102
-
Line()
Constructor.
Definition: Line.h:47
-
For linear changes with a minimum of calculation at each step.
Definition: Line.h:37
-
Line()
Constructor.
Definition: Line.h:122
-
void set(unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:170
-
void set(T targetvalue, T num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:85
-
Line()
Constructor.
Definition: Line.h:263
-
void set(unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:311
-
void set(unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:240
-
unsigned long next()
Increments one step along the line.
Definition: Line.h:274
-
unsigned int next()
Increments one step along the line.
Definition: Line.h:202
-
void set(unsigned char targetvalue, unsigned char num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:159
-
T next()
Increments one step along the line.
Definition: Line.h:58
+
1 /*
2  * Line.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef LINE_H_
13 #define LINE_H_
14 
15 #include <Arduino.h>
16 
17 /** For linear changes with a minimum of calculation at each step. For instance,
18 you can use Line to make an oscillator glide from one frequency to another,
19 pre-calculating the required phase increments for each end and then letting your
20 Line change the phase increment with only a simple addition at each step.
21 @tparam T the type of numbers to use. For example, Line <int> myline; makes a
22 Line which uses ints.
23 @note Watch out for underflows in the internal calcualtion of Line() if you're not
24 using floats (but on the other hand try to avoid lots of floats, they're too slow!).
25 If it seems like the Line() is not working, there's a good chance you need to
26 scale up the numbers you're using, so internal calculations don't get truncated
27 away. Use Mozzi's fixed-point number types in mozzi_fixmath.h, which enable you to
28 represent fractional numbers. Google "fixed point arithmetic" if this is new to
29 you.
30 */
31 
32 template <class T>
33 class Line
34 {
35 private:
36  volatile T current_value; // volatile because it could be set in control interrupt and updated in audio
37  volatile T step_size;
38 
39 public:
40  /** Constructor. Use the template parameter to set the type of numbers you
41  want to use. For example, Line <int> myline; makes a Line which uses ints.
42  */
43  Line ()
44  {
45  ;
46  }
47 
48 
49 
50  /** Increments one step along the line.
51  @return the next value.
52  */
53  inline
54  T next()
55  {
56  current_value += step_size;
57  //Serial.println(current_value);
58  return current_value;
59  }
60 
61 
62 
63  /** Set the current value of the line.
64  The Line will continue incrementing from this
65  value using any previously calculated step size.
66  @param value the number to set the Line's current_value to.
67  */
68  inline
69  void set(T value)
70  {
71  current_value=value;
72  }
73 
74 
75 
76  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
77  @param targetvalue the value to move towards.
78  @param num_steps how many steps to take to reach the target.
79  */
80  inline
81  void set(T targetvalue, T num_steps)
82  {
83  if(num_steps) {
84  T numerator = targetvalue-current_value;
85  step_size= numerator/num_steps;
86  } else {
87  step_size = 0;
88  current_value = targetvalue;
89  }
90  }
91 
92  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
93  @param startvalue the number to set the Line's current_value to.
94  @param targetvalue the value to move towards.
95  @param num_steps how many steps to take to reach the target.
96  */
97  inline
98  void set(T startvalue, T targetvalue, T num_steps)
99  {
100  set(startvalue);
101  set(targetvalue, num_steps);
102  }
103 };
104 
105 
106 /* unsigned char specialisation (probably not very useful because step size will likely = 0) */
107 template <>
108 class Line <unsigned char>
109 {
110 private:
111  volatile unsigned char current_value; // volatile because it could be set in control interrupt and updated in audio
112  char step_size;
113 
114 public:
115  /** Constructor. Use the template parameter to set the type of numbers you
116  want to use. For example, Line <int> myline; makes a Line which uses ints.
117  */
118  Line ()
119  {
120  ;
121  }
122 
123 
124 
125  /** Increments one step along the line.
126  @return the next value.
127  */
128  inline
129  unsigned char next()
130  {
131  current_value += step_size;
132  return current_value;
133  }
134 
135 
136 
137  /** Set the current value of the line.
138  The Line will continue incrementing from this
139  value using any previously calculated step size.
140  @param value the number to set the Line's current_value to.
141  */
142  inline
143  void set(unsigned char value)
144  {
145  current_value=value;
146  }
147 
148 
149 
150  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
151  @param targetvalue the value to move towards.
152  @param num_steps how many steps to take to reach the target.
153  */
154  inline
155  void set(unsigned char targetvalue, unsigned char num_steps)
156  {
157  step_size=(char)((((float)targetvalue-current_value)/num_steps));
158  }
159 
160  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
161  @param startvalue the number to set the Line's current_value to.
162  @param targetvalue the value to move towards.
163  @param num_steps how many steps to take to reach the target.
164  */
165  inline
166  void set(unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)
167  {
168  set(startvalue);
169  set(targetvalue, num_steps);
170  }
171 
172 };
173 
174 
175 /* unsigned int specialisation */
176 template <>
177 class Line <unsigned int>
178 {
179 private:
180  volatile unsigned int current_value; // volatile because it could be set in control interrupt and updated in audio
181  int step_size;
182 
183 public:
184  /** Constructor. Use the template parameter to set the type of numbers you
185  want to use. For example, Line <int> myline; makes a Line which uses ints.
186  */
187  Line ()
188  {
189  ;
190  }
191 
192 
193 
194  /** Increments one step along the line.
195  @return the next value.
196  */
197  inline
198  unsigned int next()
199  {
200  current_value += step_size;
201  return current_value;
202  }
203 
204 
205 
206  /** Set the current value of the line.
207  The Line will continue incrementing from this
208  value using any previously calculated step size.
209  @param value the number to set the Line's current_value to.
210  */
211  inline
212  void set(unsigned int value)
213  {
214  current_value=value;
215  }
216 
217 
218 
219  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
220  @param targetvalue the value to move towards.
221  @param num_steps how many steps to take to reach the target.
222  */
223  inline
224  void set(unsigned int targetvalue, unsigned int num_steps)
225  {
226  step_size=(int)((((float)targetvalue-current_value)/num_steps));
227  }
228 
229 
230  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
231  @param startvalue the number to set the Line's current_value to.
232  @param targetvalue the value to move towards.
233  @param num_steps how many steps to take to reach the target.
234  */
235  inline
236  void set(unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)
237  {
238  set(startvalue);
239  set(targetvalue, num_steps);
240  }
241 };
242 
243 
244 
245 
246 
247 /* unsigned long specialisation */
248 template <>
249 class Line <unsigned long>
250 {
251 private:
252  volatile unsigned long current_value; // volatile because it could be set in control interrupt and updated in audio
253  long step_size;
254 
255 public:
256  /** Constructor. Use the template parameter to set the type of numbers you
257  want to use. For example, Line <int> myline; makes a Line which uses ints.
258  */
259  Line ()
260  {
261  ;
262  }
263 
264 
265 
266  /** Increments one step along the line.
267  @return the next value.
268  */
269  inline
270  unsigned long next()
271  {
272  current_value += step_size;
273  return current_value;
274  }
275 
276 
277 
278  /** Set the current value of the line.
279  The Line will continue incrementing from this
280  value using any previously calculated step size.
281  @param value the number to set the Line's current_value to.
282  */
283  inline
284  void set(unsigned long value)
285  {
286  current_value=value;
287  }
288 
289 
290 
291  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
292  @param targetvalue the value to move towards.
293  @param num_steps how many steps to take to reach the target.
294  */
295  inline
296  void set(unsigned long targetvalue, unsigned long num_steps)
297  {
298  step_size=(long)((((float)targetvalue-current_value)/num_steps));
299  }
300 
301  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
302  @param startvalue the number to set the Line's current_value to.
303  @param targetvalue the value to move towards.
304  @param num_steps how many steps to take to reach the target.
305  */
306  inline
307  void set(unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)
308  {
309  set(startvalue);
310  set(targetvalue, num_steps);
311  }
312 };
313 
314 /**
315 @example 02.Control/Control_Tremelo/Control_Tremelo.ino
316 This example demonstrates the Line class.
317 */
318 
319 #endif /* LINE_H_ */
void set(T value)
Set the current value of the line.
Definition: Line.h:69
+
Line()
Constructor.
Definition: Line.h:187
+
void set(unsigned int targetvalue, unsigned int num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:224
+
void set(unsigned long value)
Set the current value of the line.
Definition: Line.h:284
+
void set(unsigned long targetvalue, unsigned long num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:296
+
unsigned char next()
Increments one step along the line.
Definition: Line.h:129
+
void set(unsigned int value)
Set the current value of the line.
Definition: Line.h:212
+
void set(unsigned char value)
Set the current value of the line.
Definition: Line.h:143
+
void set(T startvalue, T targetvalue, T num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:98
+
Line()
Constructor.
Definition: Line.h:43
+
For linear changes with a minimum of calculation at each step.
Definition: Line.h:33
+
Line()
Constructor.
Definition: Line.h:118
+
void set(unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:166
+
void set(T targetvalue, T num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:81
+
Line()
Constructor.
Definition: Line.h:259
+
void set(unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:307
+
void set(unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:236
+
unsigned long next()
Increments one step along the line.
Definition: Line.h:270
+
unsigned int next()
Increments one step along the line.
Definition: Line.h:198
+
void set(unsigned char targetvalue, unsigned char num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:155
+
T next()
Increments one step along the line.
Definition: Line.h:54
-
1 /*
2  * MetaOscil.h
3  *
4  * A wrap-up to swap between different oscillators seemlessly, allowing to produce non-aliased sounds by automatically switching between oscillators.
5  *
6  * This file is part of Mozzi.
7  */
8 
9 #ifndef META_OSCIL_H
10 #define META_OSCIL_H
11 
12 
13 #if ARDUINO >= 100
14 #include "Arduino.h"
15 #else
16 #include "WProgram.h"
17 #endif
18 
19 #include "Oscil.h"
20 #include "mozzi_fixmath.h"
21 
22 
23 /**
24  MetaOscil is a wrapper for several Oscil. Once constructed it will behave exactly as an Oscil except that it will automatically switch between Oscil depending on the asked frequency. This allows to produce non-aliased sounds by switching between tables with less and less harmonics as the frequency increases.
25 */
26 
27 
28 template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE, byte N_OSCIL>
29  class MetaOscil
30 
31 {
32  public:
33  /** Constructor
34  Declare a MetaOscil containing any number of Oscil pointers. Every Oscil should have the same TABLE_NUM_CELLS and UPDATE_RATE which are also passed in the MetaOscil constructor.
35  @param N_OSCIL is the number of Oscil contained in the MetaOscil. This cannot be changed after construction. */
36  template<class... T> MetaOscil(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* first, T*... elements):oscillators{first, elements...} {
38 
39  MetaOscil(){};
40 
41  /* Add one oscil to the MetaOscil.
42  @param osc is a pointer toward an Oscil
43  @param cutoff_freq is the cutoff frequency of this Oscil
44  void addOscil(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* osc, int cutoff_freq)
45  {
46  oscillators[current_rank] = osc;
47  cutoff_freqs[current_rank] = cutoff_freq;
48  if (current_rank == 0) current_osc=oscillators[0];
49  current_rank += 1;
50  }*/
51 
52 
53  /** Set all Oscil of a MetaOscil.
54  @param first... is a list of pointers towards several Oscil */
55  template<typename ... T > void setOscils(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* first,T... elements)
56  {
57  oscillators[current_rank]=first;
58  if (current_rank == 0) current_osc=oscillators[0];
59  current_rank+=1;
60  setOscils(elements...);
61  current_rank = 0;
62  }
63 
64  void setOscils(){};
65 
66 
67  /** Set all the cutoff frequencies for changing between Oscil. They have to be sorted in increasing values and contain at least N_OSCIL-1 values. Note that the last Oscil will be used by default for frequencies higher than the higher cutoff, hence the last value can be discarded.
68  @param first, elements... a set of int cutoff frequencies.*/
69  template<typename ... T > void setCutoffFreqs(int first,T... elements)
70  {
71  cutoff_freqs[current_rank]=first;
72  current_rank+=1;
73  setCutoffFreqs(elements...);
74  current_rank = 0;
75  }
76 
77  void setCutoffFreqs() {};
78 
79  /** Set or change the cutoff frequency of one Oscil.
80  @param rank is the rank of the Oscil.
81  @param freq is the cutoff frequency. */
82  void setCutoffFreq(int freq, byte rank)
83  {
84  cutoff_freqs[rank] = freq;
85  }
86 
87  /** Updates the phase according to the current frequency and returns the sample at the new phase position.
88  @return the next sample.
89  */
90  inline
91  int8_t next() {return current_osc->next();}
92 
93  /** Change the sound table which will be played by the Oscil of rank.
94  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
95  @param rank is the Oscil.*/
96  void setTable(const int8_t * TABLE_NAME, byte rank) {oscillators[rank]->setTable(TABLE_NAME);}
97 
98 
99  /** Set the phase of the currently playing Oscil.
100  @param phase a position in the wavetable.*/
101  void setPhase(unsigned int phase) {current_osc->setPhase(phase);}
102 
103 
104  /** Set the phase of the currently playing Oscil in fractional format.
105  @param phase a position in the wavetable.*/
106  void setPhaseFractional(unsigned long phase) {current_osc->setPhaseFractional(phase);}
107 
108 
109  /** Get the phase of the currently playin Oscil in fractional format.
110  @return position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
111  */
112  unsigned long getPhaseFractional() {return current_osc->getPhaseFractional();}
113 
114 
115 
116  /** Returns the next sample given a phase modulation value.
117  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
118  phmod_proportion parameter is a Q15n16 fixed-point number where the fractional
119  n16 part represents almost -1 to almost 1, modulating the phase by one whole table length in
120  each direction.
121  @return a sample from the table.*/
122  inline
123  int8_t phMod(Q15n16 phmod_proportion) {return current_osc->phMod(phmod_proportion);}
124 
125 
126  /** Set the MetaOsc frequency with an unsigned int.
127  @param frequency to play the wave table.*/
128  inline
129  void setFreq(int frequency, bool apply = true)
130  {
131  if (frequency < cutoff_freqs[0]) //getting out the extreme cases
132  {
133  oscillators[0]->setPhaseFractional(current_osc->getPhaseFractional());
134  current_osc = oscillators[0];
135  current_osc->setFreq(frequency);
136  }
137 
138  else if (frequency > cutoff_freqs[N_OSCIL-1])
139  {
140  oscillators[N_OSCIL-1]->setPhaseFractional(current_osc->getPhaseFractional());
141  current_osc = oscillators[N_OSCIL-1];
142  current_osc->setFreq(frequency);
143  }
144  else // dichotomic search
145  {
146  byte low_point = 0, high_point = N_OSCIL-1, mid_point = (N_OSCIL-1)>>1;
147  while(low_point != high_point)
148  {
149  if (frequency > cutoff_freqs[mid_point]) low_point = mid_point+1;
150  else if (frequency < cutoff_freqs[mid_point]) high_point = mid_point;
151  else
152  {
153  break;
154  }
155  mid_point = (low_point + high_point)>>1;
156  }
157  oscillators[mid_point]->setPhaseFractional(current_osc->getPhaseFractional());
158  current_osc = oscillators[mid_point];
159  if (apply) current_osc->setFreq(frequency);
160  }
161 
162  }
163 
164 
165  /** Set the MetaOsc frequency with a float.
166  @param frequency to play the wave table.*/
167  inline
168  void setFreq(float frequency)
169  {
170  setFreq((int) frequency, false);
171  current_osc->setFreq(frequency);
172  }
173 
174 
175  /** Set the MetaOsc frequency with a Q24n8 fixed-point number format.
176  @param frequency to play the wave table.*/
177  inline
178  void setFreq_Q24n8(Q24n8 frequency)
179  {
180  setFreq((int) (frequency>>8), false);
181  current_osc->setFreq_Q24n8(frequency);
182  }
183 
184 
185  /** Set the MetaOsc frequency with a Q16n16 fixed-point number format.
186  @param frequency to play the wave table.*/
187  inline
188  void setFreq_Q16n16(Q16n16 frequency)
189  {
190  setFreq((int) (frequency>>16), false);
191  current_osc->setFreq_Q16n16(frequency);
192  }
193 
194 
195  /** Returns the sample at the given table index of the current Oscil.
196  @param index between 0 and the table size.The
197  index rolls back around to 0 if it's larger than the table size.
198  @return the sample at the given table index.
199  */
200  inline
201  int8_t atIndex(unsigned int index) {return current_osc->atIndex(index);}
202 
203 
204  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
205  @param frequency for which you want to calculate a phase increment value.
206  @return the phase increment value which will produce a given frequency.*/
207  inline
208  unsigned long phaseIncFromFreq(int frequency) {return current_osc->phaseIncFromFreq(frequency);}
209 
210  /** Set a specific phase increment.
211  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
212  */
213  inline
214  void setPhaseInc(unsigned long phaseinc_fractional) {current_osc->setPhaseInc(phaseinc_fractional);}
215 
216 
217 
218  private:
219  Oscil<NUM_TABLE_CELLS, UPDATE_RATE> * oscillators[N_OSCIL];
220  Oscil<NUM_TABLE_CELLS, UPDATE_RATE> * current_osc = NULL;
221  int cutoff_freqs[N_OSCIL];
222  byte current_rank = 0;
223 
224 };
225 
226 /**
227 @example 06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino
228 This example demonstrates the Meta_Oscil class.
229 */
230 
231 #endif /* META_OSCIL_H */
void setPhaseInc(unsigned long phaseinc_fractional)
Set a specific phase increment.
Definition: MetaOscil.h:214
-
void setFreq(int frequency, bool apply=true)
Set the MetaOsc frequency with an unsigned int.
Definition: MetaOscil.h:129
-
void setFreq(float frequency)
Set the MetaOsc frequency with a float.
Definition: MetaOscil.h:168
-
void setFreq_Q24n8(Q24n8 frequency)
Set the MetaOsc frequency with a Q24n8 fixed-point number format.
Definition: MetaOscil.h:178
-
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:62
-
void setCutoffFreqs(int first, T... elements)
Set all the cutoff frequencies for changing between Oscil.
Definition: MetaOscil.h:69
-
void setCutoffFreq(int freq, byte rank)
Set or change the cutoff frequency of one Oscil.
Definition: MetaOscil.h:82
-
int8_t atIndex(unsigned int index)
Returns the sample at the given table index of the current Oscil.
Definition: MetaOscil.h:201
-
void setOscils(Oscil< NUM_TABLE_CELLS, UPDATE_RATE > *first, T... elements)
Set all Oscil of a MetaOscil.
Definition: MetaOscil.h:55
-
unsigned long getPhaseFractional()
Get the phase of the currently playin Oscil in fractional format.
Definition: MetaOscil.h:112
-
int8_t phMod(Q15n16 phmod_proportion)
Returns the next sample given a phase modulation value.
Definition: MetaOscil.h:123
-
void setPhaseFractional(unsigned long phase)
Set the phase of the currently playing Oscil in fractional format.
Definition: MetaOscil.h:106
-
MetaOscil(Oscil< NUM_TABLE_CELLS, UPDATE_RATE > *first, T *... elements)
Constructor Declare a MetaOscil containing any number of Oscil pointers.
Definition: MetaOscil.h:36
-
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:45
-
void setPhase(unsigned int phase)
Set the phase of the currently playing Oscil.
Definition: MetaOscil.h:101
-
unsigned long phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: MetaOscil.h:208
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46
-
void setTable(const int8_t *TABLE_NAME, byte rank)
Change the sound table which will be played by the Oscil of rank.
Definition: MetaOscil.h:96
-
MetaOscil is a wrapper for several Oscil.
Definition: MetaOscil.h:29
-
int8_t next()
Updates the phase according to the current frequency and returns the sample at the new phase position...
Definition: MetaOscil.h:91
-
void setFreq_Q16n16(Q16n16 frequency)
Set the MetaOsc frequency with a Q16n16 fixed-point number format.
Definition: MetaOscil.h:188
+
1 /*
2  * MetaOscil.h
3  *
4  * A wrap-up to swap between different oscillators seemlessly, allowing to produce non-aliased sounds by automatically switching between oscillators.
5  *
6  * This file is part of Mozzi.
7  */
8 
9 #ifndef META_OSCIL_H
10 #define META_OSCIL_H
11 
12 
13 #include <Arduino.h>
14 
15 #include "Oscil.h"
16 #include "mozzi_fixmath.h"
17 
18 
19 /**
20  MetaOscil is a wrapper for several Oscil. Once constructed it will behave exactly as an Oscil except that it will automatically switch between Oscil depending on the asked frequency. This allows to produce non-aliased sounds by switching between tables with less and less harmonics as the frequency increases.
21 */
22 
23 
24 template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE, byte N_OSCIL>
25  class MetaOscil
26 
27 {
28  public:
29  /** Constructor
30  Declare a MetaOscil containing any number of Oscil pointers. Every Oscil should have the same TABLE_NUM_CELLS and UPDATE_RATE which are also passed in the MetaOscil constructor.
31  @param N_OSCIL is the number of Oscil contained in the MetaOscil. This cannot be changed after construction. */
32  template<class... T> MetaOscil(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* first, T*... elements):oscillators{first, elements...} {
34 
35  MetaOscil(){};
36 
37  /* Add one oscil to the MetaOscil.
38  @param osc is a pointer toward an Oscil
39  @param cutoff_freq is the cutoff frequency of this Oscil
40  void addOscil(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* osc, int cutoff_freq)
41  {
42  oscillators[current_rank] = osc;
43  cutoff_freqs[current_rank] = cutoff_freq;
44  if (current_rank == 0) current_osc=oscillators[0];
45  current_rank += 1;
46  }*/
47 
48 
49  /** Set all Oscil of a MetaOscil.
50  @param first... is a list of pointers towards several Oscil */
51  template<typename ... T > void setOscils(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* first,T... elements)
52  {
53  oscillators[current_rank]=first;
54  if (current_rank == 0) current_osc=oscillators[0];
55  current_rank+=1;
56  setOscils(elements...);
57  current_rank = 0;
58  }
59 
60  void setOscils(){};
61 
62 
63  /** Set all the cutoff frequencies for changing between Oscil. They have to be sorted in increasing values and contain at least N_OSCIL-1 values. Note that the last Oscil will be used by default for frequencies higher than the higher cutoff, hence the last value can be discarded.
64  @param first, elements... a set of int cutoff frequencies.*/
65  template<typename ... T > void setCutoffFreqs(int first,T... elements)
66  {
67  cutoff_freqs[current_rank]=first;
68  current_rank+=1;
69  setCutoffFreqs(elements...);
70  current_rank = 0;
71  }
72 
73  void setCutoffFreqs() {};
74 
75  /** Set or change the cutoff frequency of one Oscil.
76  @param rank is the rank of the Oscil.
77  @param freq is the cutoff frequency. */
78  void setCutoffFreq(int freq, byte rank)
79  {
80  cutoff_freqs[rank] = freq;
81  }
82 
83  /** Updates the phase according to the current frequency and returns the sample at the new phase position.
84  @return the next sample.
85  */
86  inline
87  int8_t next() {return current_osc->next();}
88 
89  /** Change the sound table which will be played by the Oscil of rank.
90  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
91  @param rank is the Oscil.*/
92  void setTable(const int8_t * TABLE_NAME, byte rank) {oscillators[rank]->setTable(TABLE_NAME);}
93 
94 
95  /** Set the phase of the currently playing Oscil.
96  @param phase a position in the wavetable.*/
97  void setPhase(unsigned int phase) {current_osc->setPhase(phase);}
98 
99 
100  /** Set the phase of the currently playing Oscil in fractional format.
101  @param phase a position in the wavetable.*/
102  void setPhaseFractional(unsigned long phase) {current_osc->setPhaseFractional(phase);}
103 
104 
105  /** Get the phase of the currently playin Oscil in fractional format.
106  @return position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
107  */
108  unsigned long getPhaseFractional() {return current_osc->getPhaseFractional();}
109 
110 
111 
112  /** Returns the next sample given a phase modulation value.
113  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
114  phmod_proportion parameter is a Q15n16 fixed-point number where the fractional
115  n16 part represents almost -1 to almost 1, modulating the phase by one whole table length in
116  each direction.
117  @return a sample from the table.*/
118  inline
119  int8_t phMod(Q15n16 phmod_proportion) {return current_osc->phMod(phmod_proportion);}
120 
121 
122  /** Set the MetaOsc frequency with an unsigned int.
123  @param frequency to play the wave table.*/
124  inline
125  void setFreq(int frequency, bool apply = true)
126  {
127  if (frequency < cutoff_freqs[0]) //getting out the extreme cases
128  {
129  oscillators[0]->setPhaseFractional(current_osc->getPhaseFractional());
130  current_osc = oscillators[0];
131  current_osc->setFreq(frequency);
132  }
133 
134  else if (frequency > cutoff_freqs[N_OSCIL-1])
135  {
136  oscillators[N_OSCIL-1]->setPhaseFractional(current_osc->getPhaseFractional());
137  current_osc = oscillators[N_OSCIL-1];
138  current_osc->setFreq(frequency);
139  }
140  else // dichotomic search
141  {
142  byte low_point = 0, high_point = N_OSCIL-1, mid_point = (N_OSCIL-1)>>1;
143  while(low_point != high_point)
144  {
145  if (frequency > cutoff_freqs[mid_point]) low_point = mid_point+1;
146  else if (frequency < cutoff_freqs[mid_point]) high_point = mid_point;
147  else
148  {
149  break;
150  }
151  mid_point = (low_point + high_point)>>1;
152  }
153  oscillators[mid_point]->setPhaseFractional(current_osc->getPhaseFractional());
154  current_osc = oscillators[mid_point];
155  if (apply) current_osc->setFreq(frequency);
156  }
157 
158  }
159 
160 
161  /** Set the MetaOsc frequency with a float.
162  @param frequency to play the wave table.*/
163  inline
164  void setFreq(float frequency)
165  {
166  setFreq((int) frequency, false);
167  current_osc->setFreq(frequency);
168  }
169 
170 
171  /** Set the MetaOsc frequency with a Q24n8 fixed-point number format.
172  @param frequency to play the wave table.*/
173  inline
174  void setFreq_Q24n8(Q24n8 frequency)
175  {
176  setFreq((int) (frequency>>8), false);
177  current_osc->setFreq_Q24n8(frequency);
178  }
179 
180 
181  /** Set the MetaOsc frequency with a Q16n16 fixed-point number format.
182  @param frequency to play the wave table.*/
183  inline
184  void setFreq_Q16n16(Q16n16 frequency)
185  {
186  setFreq((int) (frequency>>16), false);
187  current_osc->setFreq_Q16n16(frequency);
188  }
189 
190 
191  /** Returns the sample at the given table index of the current Oscil.
192  @param index between 0 and the table size.The
193  index rolls back around to 0 if it's larger than the table size.
194  @return the sample at the given table index.
195  */
196  inline
197  int8_t atIndex(unsigned int index) {return current_osc->atIndex(index);}
198 
199 
200  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
201  @param frequency for which you want to calculate a phase increment value.
202  @return the phase increment value which will produce a given frequency.*/
203  inline
204  unsigned long phaseIncFromFreq(int frequency) {return current_osc->phaseIncFromFreq(frequency);}
205 
206  /** Set a specific phase increment.
207  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
208  */
209  inline
210  void setPhaseInc(unsigned long phaseinc_fractional) {current_osc->setPhaseInc(phaseinc_fractional);}
211 
212 
213 
214  private:
215  Oscil<NUM_TABLE_CELLS, UPDATE_RATE> * oscillators[N_OSCIL];
216  Oscil<NUM_TABLE_CELLS, UPDATE_RATE> * current_osc = NULL;
217  int cutoff_freqs[N_OSCIL];
218  byte current_rank = 0;
219 
220 };
221 
222 /**
223 @example 06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino
224 This example demonstrates the Meta_Oscil class.
225 */
226 
227 #endif /* META_OSCIL_H */
void setPhaseInc(unsigned long phaseinc_fractional)
Set a specific phase increment.
Definition: MetaOscil.h:210
+
void setFreq(int frequency, bool apply=true)
Set the MetaOsc frequency with an unsigned int.
Definition: MetaOscil.h:125
+
void setFreq(float frequency)
Set the MetaOsc frequency with a float.
Definition: MetaOscil.h:164
+
void setFreq_Q24n8(Q24n8 frequency)
Set the MetaOsc frequency with a Q24n8 fixed-point number format.
Definition: MetaOscil.h:174
+
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:59
+
void setCutoffFreqs(int first, T... elements)
Set all the cutoff frequencies for changing between Oscil.
Definition: MetaOscil.h:65
+
void setCutoffFreq(int freq, byte rank)
Set or change the cutoff frequency of one Oscil.
Definition: MetaOscil.h:78
+
int8_t atIndex(unsigned int index)
Returns the sample at the given table index of the current Oscil.
Definition: MetaOscil.h:197
+
void setOscils(Oscil< NUM_TABLE_CELLS, UPDATE_RATE > *first, T... elements)
Set all Oscil of a MetaOscil.
Definition: MetaOscil.h:51
+
unsigned long getPhaseFractional()
Get the phase of the currently playin Oscil in fractional format.
Definition: MetaOscil.h:108
+
int8_t phMod(Q15n16 phmod_proportion)
Returns the next sample given a phase modulation value.
Definition: MetaOscil.h:119
+
void setPhaseFractional(unsigned long phase)
Set the phase of the currently playing Oscil in fractional format.
Definition: MetaOscil.h:102
+
MetaOscil(Oscil< NUM_TABLE_CELLS, UPDATE_RATE > *first, T *... elements)
Constructor Declare a MetaOscil containing any number of Oscil pointers.
Definition: MetaOscil.h:32
+
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:43
+
void setPhase(unsigned int phase)
Set the phase of the currently playing Oscil.
Definition: MetaOscil.h:97
+
unsigned long phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: MetaOscil.h:204
+
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:44
+
void setTable(const int8_t *TABLE_NAME, byte rank)
Change the sound table which will be played by the Oscil of rank.
Definition: MetaOscil.h:92
+
MetaOscil is a wrapper for several Oscil.
Definition: MetaOscil.h:25
+
int8_t next()
Updates the phase according to the current frequency and returns the sample at the new phase position...
Definition: MetaOscil.h:87
+
void setFreq_Q16n16(Q16n16 frequency)
Set the MetaOsc frequency with a Q16n16 fixed-point number format.
Definition: MetaOscil.h:184
-
1 /*
2  * MozziGuts.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef MOZZIGUTS_H_
13 #define MOZZIGUTS_H_
14 
15 //#define F_CPU 8000000 // testing
16 
17 #if ARDUINO >= 100
18  #include "Arduino.h"
19 #else
20  #include "WProgram.h"
21 #endif
22 
23 #include "hardware_defines.h"
24 
25 #if IS_TEENSY3() || IS_TEENSY4()
26 // required from http://github.com/pedvide/ADC for Teensy 3.*
27 #include <ADC.h>
28 #endif
29 
30 #include "mozzi_analog.h"
31 
32 #if not defined (CONTROL_RATE)
33 /** @ingroup core
34 Control rate setting.
35 Mozzi's CONTROL_RATE sets how many times per second updateControl() is called.
36 CONTROL_RATE has a default of 64 Hz, but it can be changed at the top of your sketch,
37 (before the \#includes), for example: \#define CONTROL_RATE 256.
38 It is useful to have CONTROL_RATE set at a power of 2 (such as 64,128,256 etc),
39 to have exact timing of audio and control operations.
40 Non-power-of-2 CONTROL_RATE can cause glitches due to audio and control
41 events not lining up precisely. If this happens a power of two CONTROL_RATE might solve it.
42 Try to keep CONTROL_RATE low, for efficiency, though higher rates up to about 1000
43 can sometimes give smoother results, avoiding the need to interpolate
44 sensitive variables at audio rate in updateAudio().
45 */
46 #define CONTROL_RATE 64
47 #endif
48 
49 
50 
51 /** @ingroup core
52 Used to set AUDIO_MODE to STANDARD, STANDARD_PLUS, or HIFI.
53 
54 STANDARD / STANDARD_PLUS
55 ---------------
56 Use \#define AUDIO_MODE STANDARD_PLUS in Mozzi/config.h to select this
57 output configuration, which is nearly 9 bit sound (-244 to 243) at 16384 Hz sample rate (AUDIO_RATE) and
58 32768 Hz PWM rate. It uses Timer 1 for PWM and the sample updating routine (as an interrupt).
59 
60 STANDARD is obsolete now, replaced by STANDARD_PLUS which is the default audio mode.
61 STANDARD mode uses 16384 Hz PWM rate with an output interrupt at the same frequency.
62 Some people can hear the PWM carrier frequency as an annoying whine.
63 
64 STANDARD_PLUS mode uses 32768 Hz PWM rate, so the PWM carrier is out of hearing range.
65 In this mode every alternate interrupt is used for the sample update (unless you /#define AUDIO_RATE 32768 in mozzi_config.h),
66 which makes it slightly less efficient than STANDARD, but almost always better.
67 
68 Advantages: Only uses one timer for audio, and one output pin.
69 Disadvantages: low dynamic range.
70 
71 Below is a list of the Digital Pins used by Mozzi for STANDARD and STANDARD_PLUS audio out on different boards.
72 Those which have been tested and reported to work have an x.
73 Feedback about others is welcome.
74 
75 Model | Pin | Tested
76 ----- | --- | ------
77 Arduino Uno | 9 | yes
78 Arduino Duemilanove | 9 | yes
79 Arduino Nano | 9 | yes
80 Arduino Pro Mini | 9 | yes
81 Arduino Leonardo | 9 | yes
82 Arduino Mega | 11 | yes
83 Freetronics EtherMega | 11 | yes
84 Ardweeny | 9 | yes
85 Boarduino | 9 | yes
86 Teensy | 14 | -
87 Teensy2 | B5 | yes
88 Teensy2++ | B5(25) | yes
89 Teensy 3.0 3.1 LC 3.2 | DAC/D | yes
90 Teensy 3.4, 3.5 | DAC/D | -
91 Teensy 4.0 4.1 | A8 | yes
92 Gemma M0 | A0 | yes
93 Adafruit Playground Express | Built in Speaker | yes
94 Sanguino | 13 | -
95 STM32duino (see "Hardware specific notes", below) | PB8 | yes
96 ESP8266 *see details in README* | GPIO2 | yes
97 RP2040 | 0 | yes
98 
99 
100 On Teensy 3.* STANDARD and STANDARD_PLUS are the same, providing 16384Hz sample rate and 12 bit resolution on pin A14/ADC.
101 The Teensy 3.* DAC output does not rely on PWM.
102 
103 
104 @ingroup core
105 
106 Used to set AUDIO_MODE to HIFI.
107 
108 HIFI for AVR and STM32 (not for Teensy 3.*)
109 ----
110 Use \#define AUDIO_MODE HIFI in Mozzi/config.h to set the audio mode to HIFI for output 14 bit sound at 16384 Hz sample rate and 125kHz PWM rate.
111 The high PWM rate of HIFI mode places the carrier frequency beyond audible range.
112 
113 Also, 14 bits of dynamic range in HIFI mode provides more definition than the nearly 9 bits in STANDARD_PLUS mode.
114 HIFI mode takes about the same amount of processing time as STANDARD_PLUS mode, and should sound clearer and brighter.
115 However, it requires an extra timer to be used on the Arduino, which could increase the chances of
116 conflicts with other libraries or processes if they rely on Timer 2.
117 
118 Timer 1 is used to provide the PWM output at 125kHz.
119 Timer 2 generates an interrupt at AUDIO_RATE 16384 Hz, which sets the Timer1 PWM levels.
120 HIFI mode uses 2 output pins, and sums their outputs with resistors, so is slightly less convenient for
121 rapid prototyping where you could listen to STANDARD_PLUS mode by connecting the single output pin
122 directly to a speaker or audio input (though a resistor of about 100 ohms is recommended).
123 
124 The resistors needed for HIFI output are 3.9k and 499k, with 0.5% or better tolerance.
125 If you can only get 1% resistors, use a multimeter to find the most accurate.
126 Use two 1M resistors in parallel if you can't find 499k.
127 
128 On 328 based Arduino boards, output is on Timer1, with the high byte on Pin 9 and low byte on Pin 10.
129 Add the signals through a 3.9k resistor on high byte pin (9) and 499k resistor on low byte pin (10).
130 Also, a 4.7nF capacitor is recommended between the summing junction of the resistors and ground.
131 
132 This dual PWM technique is discussed on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/
133 Also, there are higher quality output circuits are on the site.
134 
135 Advantages: should be higher quality sound than STANDARD_PLUS mode. Doesn't need a notch filter on
136 the audio signal (like STANDARD which is now obsolete) because the carrier frequency is out of hearing range.
137 
138 Disadvantages: requires 2 pins, 2 resistors and a capacitor, so it's not so quick to set up compared
139 to a rough, direct single-pin output in STANDARD_PLUS mode.
140 
141 Pins and where to put the resistors on various boards for HIFI mode.
142 Boards tested in HIFI mode have an x, though most of these have been tested in STANDARD_PLUS mode
143 and there's no reason for them not to work in HIFI (unless the pin number is wrong or something).
144 Any reports are welcome. \n
145 
146 resistor.....3.9k......499k \n
147 x................9..........10...............Arduino Uno \n
148 x................9..........10...............Arduino Duemilanove \n
149 x................9..........10...............Arduino Nano \n
150 x................9..........10...............Arduino Leonardo \n
151 x................9..........10...............Ardweeny \n
152 x................9..........10...............Boarduino \n
153 x...............11.........12...............Freetronics EtherMega \n
154 .................11.........12...............Arduino Mega \n
155 .................14.........15...............Teensy \n
156 .............B5(14)...B6(15)...........Teensy2 \n
157 x...........B5(25)...B6(26)...........Teensy2++ \n
158 .................13.........12...............Sanguino \n
159 
160 HIFI is not available/not required on Teensy 3.* or ARM.
161 */
162 
163 //enum audio_modes {STANDARD,STANDARD_PLUS,HIFI};
164 #define STANDARD 0
165 #define STANDARD_PLUS 1
166 #define HIFI 2
167 
168 //enum audio_channels {MONO,STEREO,...};
169 #define MONO 1
170 #define STEREO 2
171 
172 #include "mozzi_config.h" // User can change the config file to set audio mode
173 
174 #if (AUDIO_MODE == STANDARD) && (AUDIO_RATE == 32768)
175 #error AUDIO_RATE 32768 does not work when AUDIO_MODE is STANDARD, try setting the AUDIO_MODE to STANDARD_PLUS in Mozzi/mozzi_config.h
176 #endif
177 
178 #if (STEREO_HACK == true)
179 #warning Use of STEREO_HACK is deprecated. Use AUDIO_CHANNELS STEREO, instead.
180 #define AUDIO_CHANNELS STEREO
181 #endif
182 #if !defined(AUDIO_CHANNELS)
183 #define AUDIO_CHANNELS MONO
184 #endif
185 
186 #define CLOCK_TICKS_PER_AUDIO_TICK (F_CPU / AUDIO_RATE)
187 
188 
189 #if AUDIO_RATE == 16384
190 #define AUDIO_RATE_AS_LSHIFT 14
191 #define MICROS_PER_AUDIO_TICK 61 // 1000000 / 16384 = 61.035, ...* 256 = 15625
192 #elif AUDIO_RATE == 32768
193 #define AUDIO_RATE_AS_LSHIFT 15
194 #define MICROS_PER_AUDIO_TICK 31 // = 1000000 / 32768 = 30.518, ...* 256 = 7812.6
195 #endif
196 
197 // for compatibility with old (local) versions of mozzi_config.h
198 #if !defined(EXTERNAL_AUDIO_OUTPUT)
199 #define EXTERNAL_AUDIO_OUTPUT false
200 #endif
201 
202 #if (EXTERNAL_AUDIO_OUTPUT != true)
203 #if IS_TEENSY3()
204 #include "AudioConfigTeensy3_12bit.h"
205 #elif IS_TEENSY4()
206 #include "AudioConfigTeensy4.h"
207 #elif IS_STM32()
208 #include "AudioConfigSTM32.h"
209 #elif IS_ESP8266()
210 #include "AudioConfigESP.h"
211 #elif IS_ESP32()
212 #include "AudioConfigESP32.h"
213 #elif IS_SAMD21()
214 #include "AudioConfigSAMD21.h"
215 #elif IS_RP2040()
216 #include "AudioConfigRP2040.h"
217 #elif IS_AVR() && (AUDIO_MODE == STANDARD)
218 #include "AudioConfigStandard9bitPwm.h"
219 #elif IS_AVR() && (AUDIO_MODE == STANDARD_PLUS)
220 #include "AudioConfigStandardPlus.h"
221 #elif IS_AVR() && (AUDIO_MODE == HIFI)
222 #include "AudioConfigHiSpeed14bitPwm.h"
223 #endif
224 #else // EXTERNAL_AUDIO_OUTPUT==true
225 #if !defined(EXTERNAL_AUDIO_BITS)
226 #define EXTERNAL_AUDIO_BITS 16
227 #endif
228 #define AUDIO_BITS EXTERNAL_AUDIO_BITS
229 #define AUDIO_BIAS (1 << (AUDIO_BITS - 1))
230 #endif
231 
232 #if (STEREO_HACK == true)
233 extern int audio_out_1, audio_out_2;
234 #endif
235 
236 #include "AudioOutput.h"
237 
238 // common numeric types
239 typedef unsigned char uchar;
240 typedef unsigned int uint;
241 typedef unsigned long ulong;
242 
243 #if defined(__AVR__)
244 typedef unsigned char byte; // for arduino ide
245 typedef unsigned char uint8_t;
246 typedef signed char int8_t;
247 typedef unsigned int uint16_t;
248 typedef signed int int16_t;
249 typedef unsigned long uint32_t;
250 typedef signed long int32_t;
251 #else
252 // Other supported arches add typedefs, here, unless already defined for that platform needed
253 #endif
254 
255 
256 /** @ingroup core
257 Sets up the timers for audio and control rate processes, storing the timer
258 registers so they can be restored when Mozzi stops. startMozzi() goes in your sketch's
259 setup() routine.
260 
261 Contrary to earlier versions of Mozzi, this version does not take over Timer 0, and thus Arduino
262 functions delay(), millis(), micros() and delayMicroseconds() remain usable in theory. That said,
263 you should avoid these functions, as they are slow (or even blocking). For measuring time, refer
264 to mozziMircos(). For delaying events, you can use Mozzi's EventDelay() unit instead
265 (not to be confused with AudioDelay()).
266 
267 In STANDARD mode, startMozzi() starts Timer 1 for PWM output and audio output interrupts,
268 and in STANDARD_PLUS and HIFI modes, Mozzi uses Timer 1 for PWM and Timer2 for audio interrupts.
269 
270 The audio rate defaults to 16384 Hz, but you can experiment with 32768 Hz by changing AUDIO_RATE in mozzi_config.h.
271 
272 @param control_rate_hz Sets how often updateControl() is called. It must be a power of 2.
273 If no parameter is provided, control_rate_hz is set to CONTROL_RATE,
274 which has a default value of 64 (you can re-\#define it in your sketch).
275 The practical upper limit for control rate depends on how busy the processor is,
276 and you might need to do some tests to find the best setting.
277 
278 @note startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(),
279 which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack).
280 They are all called automatically and hidden away because it keeps things simple for a STANDARD_PLUS set up,
281 but if it turns out to be confusing, they might need to become visible again.
282 */
283 void startMozzi(int control_rate_hz = CONTROL_RATE);
284 
285 
286 
287 /** @ingroup core
288 Stops audio and control interrupts and restores the timers to the values they
289 had before Mozzi was started. This could be useful when using sensor libraries
290 which depend on the same timers as Mozzi.
291 
292 A potentially better option for resolving timer conflicts involves using
293 non-blocking methods, such as demonstrated by the twowire_nonblock code in the
294 forked version of Mozzi on github, so sound production can continue while
295 reading sensors.
296 
297 As it is, stopMozzi restores all the Timers used by Mozzi to their previous
298 settings. Another scenario which could be easily hacked in MozziGuts.cpp could
299 involve individually saving and restoring particular Timer registers depending
300 on which one(s) are required for other tasks. */
301 void stopMozzi();
302 
303 
304 /** @ingroup core
305 Obsolete function, use stopMozzi() instead.
306 */
307 void pauseMozzi();
308 
309 //TB2017-19
310 /** @ingroup core
311 Obsolete function, use startMozzi() instead.
312 Restores Mozzi audio and control interrupts, if they have been temporarily
313 disabled with pauseMozzi().
314 */
315 void unPauseMozzi();
316 
317 
318 /** @ingroup core
319 This is where you put your audio code. updateAudio() has to keep up with the
320 AUDIO_RATE of 16384 Hz, so to keep things running smoothly, avoid doing any
321 calculations here which could be done in setup() or updateControl().
322 @return an audio sample. In STANDARD modes this is between -244 and 243 inclusive.
323 In HIFI mode, it's a 14 bit number between -16384 and 16383 inclusive.
324 */
326 
327 /** @ingroup core
328 This is where you put your control code. You need updateControl() somewhere in
329 your sketch, even if it's empty. updateControl() is called at the control rate
330 you set in startMozzi(). To save processor load, avoid any calculations here
331 which could be done in setup().
332 */
333 void updateControl();
334 
335 
336 /** @ingroup core
337 This is required in Arduino's loop(). If there is room in Mozzi's output buffer,
338 audioHook() calls updateAudio() once and puts the result into the output
339 buffer. Also, if \#define USE_AUDIO_INPUT true is in Mozzi/mozzi_config.h,
340 audioHook() takes care of moving audio input from the input buffer so it can be
341 accessed with getAudioInput() in your updateAudio() routine.
342 If other functions are called in loop() along with audioHook(), see if
343 they can be called less often by moving them into updateControl(),
344 to save processing power. Otherwise it may be most efficient to
345 calculate a block of samples at a time by putting audioHook() in a loop of its
346 own, rather than calculating only 1 sample for each time your other functions
347 are called.
348 */
349 void audioHook();
350 
351 
352 
353 /** @ingroup analog
354 This returns audio input from the input buffer, if
355 \#define USE_AUDIO_INPUT true is in the Mozzi/mozzi_config.h file.
356 The pin used for audio input is set in Mozzi/mozzi_config.h with
357 \#define AUDIO_INPUT_PIN 0 (or other analog input pin).
358 The audio signal needs to be in the range 0 to 5 volts.
359 Circuits and discussions about biasing a signal
360 in the middle of this range can be found at
361 http://electronics.stackexchange.com/questions/14404/dc-biasing-audio-signal
362 and
363 http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/ .
364 A circuit and instructions for amplifying and biasing a microphone signal can be found at
365 http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS
366 @return audio data from the input buffer
367 */
368 #if (USE_AUDIO_INPUT == true)
369 int getAudioInput();
370 #endif
371 
372 
373 /** @ingroup core
374 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
375 and also it is synchronized with the currently processed audio sample (which, due to the audio
376 output buffer, could diverge up to 256/AUDIO_RATE seconds from the current time).
377 audioTicks() is updated each time an audio sample
378 is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when AUDIO_RATE is
379 16384 Hz).
380 @return the number of audio ticks since the program began.
381 */
382 unsigned long audioTicks();
383 
384 
385 
386 /** @ingroup core
387 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
388 and also it is synchronized with the currently processed audio sample (which, due to the audio
389 output buffer, could diverge up to 256/AUDIO_RATE seconds from the current time).
390 audioTicks() is updated each time an audio sample
391 is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when AUDIO_RATE is
392 16384 Hz).
393 @return the approximate number of microseconds since the program began.
394 @todo incorporate mozziMicros() in a more accurate EventDelay()?
395 */
396 unsigned long mozziMicros();
397 
398 #endif /* MOZZIGUTS_H_ */
unsigned long mozziMicros()
An alternative for Arduino time functions like micros() and millis().
Definition: MozziGuts.cpp:229
-
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
#define AUDIO_MODE
AUDIO_MODE holds the audio mode setting.
Definition: mozzi_config.h:28
-
#define AUDIO_CHANNELS
This sets allows to change from a single/mono audio output channel to stereo output.
Definition: mozzi_config.h:92
-
#define HIFI
Definition: MozziGuts.h:166
-
#define IS_SAMD21()
-
AudioOutput_t updateAudio()
This is where you put your audio code.
-
#define IS_TEENSY4()
+
1 /*
2  * MozziGuts.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef MOZZIGUTS_H_
13 #define MOZZIGUTS_H_
14 
15 #include "Arduino.h"
16 
17 #include "MozziConfigValues.h"
18 
19 #if !(defined(MOZZI_H_) || defined(MOZZI_HEADERS_ONLY_H_))
20 #warning Direct inclusion of MozziGuts.h is deprecated. Use Mozzi.h, instead, and read about porting to Mozzi 2.0
21 #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_1_1
22 #endif
23 
24 #include "hardware_defines.h"
25 
26 #if IS_TEENSY3() || IS_TEENSY4()
27 // required from http://github.com/pedvide/ADC for Teensy 3.*
28 #include <ADC.h>
29 #endif
30 
31 #include "internal/config_checks_generic.h"
32 
33 #include "mozzi_analog.h"
34 #include "AudioOutput.h"
35 
36 // TODO Mozzi 2.0: These typedef probably obsolete?
37 // common numeric types
38 typedef unsigned char uchar;
39 typedef unsigned int uint;
40 typedef unsigned long ulong;
41 
42 #if defined(__AVR__)
43 typedef unsigned char byte; // for arduino ide
44 typedef unsigned char uint8_t;
45 typedef signed char int8_t;
46 typedef unsigned int uint16_t;
47 typedef signed int int16_t;
48 typedef unsigned long uint32_t;
49 typedef signed long int32_t;
50 #else
51 // Other supported arches add typedefs, here, unless already defined for that platform needed
52 #endif
53 
54 /*! @defgroup core Mozzi Core Functions
55 
56 @ingroup core
57 Sets up the timers for audio and control rate processes, storing the timer
58 registers so they can be restored when Mozzi stops. startMozzi() goes in your sketch's
59 setup() routine.
60 
61 This function intializes the timer(s) needed to move audio samples to the output according to the
62 configured @ref MOZZI_AUDIO_MODE .
63 
64 @param control_rate_hz Sets how often updateControl() is called. It must be a power of 2.
65 If no parameter is provided, control_rate_hz is set to MOZZI_CONTROL_RATE,
66 which has a default value of 64 (you can re-\#define it in your sketch).
67 The practical upper limit for control rate depends on how busy the processor is,
68 and you might need to do some tests to find the best setting.
69 
70 @note startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(),
71 which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack).
72 They are all called automatically and hidden away because it keeps things simple for a STANDARD_PLUS set up,
73 but if it turns out to be confusing, they might need to become visible again.
74 */
75 void startMozzi(int control_rate_hz = MOZZI_CONTROL_RATE);
76 
77 
78 
79 /** @ingroup core
80 Stops audio and control interrupts and restores the timers to the values they
81 had before Mozzi was started. This could be useful when using sensor libraries
82 which depend on the same timers as Mozzi.
83 
84 A potentially better option for resolving timer conflicts involves using
85 non-blocking methods, such as demonstrated by the twowire_nonblock code in the
86 forked version of Mozzi on github, so sound production can continue while
87 reading sensors.
88 
89 As it is, stopMozzi restores all the Timers used by Mozzi to their previous
90 settings. Another scenario which could be easily hacked in MozziGuts.hpp could
91 involve individually saving and restoring particular Timer registers depending
92 on which one(s) are required for other tasks.
93 
94 @note This function is not actually implemented on all platforms.
95 */
96 void stopMozzi();
97 
98 
100 AudioOutput_t updateAudio();
101 #else
102 /** @ingroup core
103 This is where you put your audio code. updateAudio() has to keep up with the
104 MOZZI_AUDIO_RATE of 16384 or 32768 Hz, so to keep things running smoothly, avoid doing any
105 calculations here which could be done in setup() or updateControl().
106 @return an audio sample.
107 
108 While is possible (in mono sketches) to return a plain unscaled int, it is generally best to return
109 auto-scaled samples using MonoOutput::from8Bit(), MonoOutput::from16Bit(), MonoOutput::fromNbit(), or
110 their StereoOutput equivalents.
111 */
112 AudioOutput updateAudio();
113 #endif
114 
115 /** @ingroup core
116 This is where you put your control code. You need updateControl() somewhere in
117 your sketch, even if it's empty. updateControl() is called at the control rate
118 you set in startMozzi(). To save processor load, avoid any calculations here
119 which could be done in setup().
120 */
121 void updateControl();
122 
123 
124 /** @ingroup core
125 This is required in Arduino's loop(). If there is room in Mozzi's output buffer,
126 audioHook() calls updateAudio() once and puts the result into the output
127 buffer. Also, if \@ref MOZZI_AUDIO_INPUT is enabled in the config,
128 audioHook() takes care of moving audio input from the input buffer so it can be
129 accessed with getAudioInput() in your updateAudio() routine.
130 If other functions are called in loop() along with audioHook(), see if
131 they can be called less often by moving them into updateControl(),
132 to save processing power. Otherwise it may be most efficient to
133 calculate a block of samples at a time by putting audioHook() in a loop of its
134 own, rather than calculating only 1 sample for each time your other functions
135 are called.
136 */
137 void audioHook();
138 
139 
140 
141 /** @ingroup analog
142 This returns audio input from the input buffer, if
143 \@ref MOZZI_AUDIO_INPUT is enabled in the config (see also the related option MOZZI_AUDIO_INPUT_PIN).
144 
145 The audio signal needs to be in the range 0 to VCC volts (i.e. 5 volts on Arduino Uno R3).
146 Circuits and discussions about biasing a signal
147 in the middle of this range can be found at
148 http://electronics.stackexchange.com/questions/14404/dc-biasing-audio-signal
149 and
150 http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/ .
151 A circuit and instructions for amplifying and biasing a microphone signal can be found at
152 http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS
153 @return audio data from the input buffer
154 */
156 int getAudioInput();
157 #endif
158 
159 
160 /** @ingroup core
161 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
162 and also it is synchronized with the currently processed audio sample (which, due to the audio
163 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
164 audioTicks() is updated each time an audio sample
165 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
166 16384 Hz).
167 @return the number of audio ticks since the program began.
168 */
169 unsigned long audioTicks();
170 
171 
172 
173 /** @ingroup core
174 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
175 and also it is synchronized with the currently processed audio sample (which, due to the audio
176 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
177 audioTicks() is updated each time an audio sample
178 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
179 16384 Hz).
180 @return the approximate number of microseconds since the program began.
181 @todo incorporate mozziMicros() in a more accurate EventDelay()?
182 */
183 unsigned long mozziMicros();
184 
185 #ifndef _MOZZI_HEADER_ONLY
186 #include "internal/MozziGuts.hpp"
187 #endif
188 
189 #endif /* MOZZIGUTS_H_ */
unsigned long mozziMicros()
An alternative for Arduino time functions like micros() and millis().
Definition: MozziGuts.hpp:255
+
#define MOZZI_CONTROL_RATE
Control rate setting.
+
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
Definition: MozziGuts.hpp:291
+
#define MOZZI_AUDIO_INPUT_NONE
+
#define IS_TEENSY4()
void updateControl()
This is where you put your control code.
-
#define AUDIO_RATE
Holds the audio rate setting.
Definition: mozzi_config.h:62
-
#define IS_STM32()
-
#define STANDARD_PLUS
Definition: MozziGuts.h:165
-
void audioHook()
This is required in Arduino&#39;s loop().
Definition: MozziGuts.cpp:190
-
#define IS_AVR()
-
#define IS_TEENSY3()
-
#define IS_RP2040()
-
void unPauseMozzi()
Obsolete function, use startMozzi() instead.
-
unsigned long audioTicks()
An alternative for Arduino time functions like micros() and millis().
Definition: MozziGuts.cpp:219
-
#define AudioOutput_t
Representation of an single audio output sample/frame.
Definition: AudioOutput.h:77
-
void pauseMozzi()
Obsolete function, use stopMozzi() instead.
-
void startMozzi(int control_rate_hz=CONTROL_RATE)
Sets up the timers for audio and control rate processes, storing the timer registers so they can be r...
Definition: MozziGuts.cpp:234
-
#define STANDARD
Used to set AUDIO_MODE to STANDARD, STANDARD_PLUS, or HIFI.
Definition: MozziGuts.h:164
-
#define EXTERNAL_AUDIO_OUTPUT
Defining this option as true in mozzi_config.h allows to completely customize the audio output...
Definition: mozzi_config.h:99
-
#define IS_ESP8266()
-
#define IS_ESP32()
+
void audioHook()
This is required in Arduino&#39;s loop().
Definition: MozziGuts.hpp:218
+
#define MOZZI_IS(X,...)
Definition: mozzi_macros.h:51
+
#define IS_TEENSY3()
+
AudioOutput_t updateAudio()
This is where you put your audio code.
+
#define MOZZI_MONO
This file keeps a list of named configuration values.
+
#define MOZZI_COMPATIBILITY_1_1
+
#define MOZZI_AUDIO_CHANNELS
+
unsigned long audioTicks()
An alternative for Arduino time functions like micros() and millis().
Definition: MozziGuts.hpp:245
+
#define MOZZI_AUDIO_INPUT
Whether to enable built in audio input feature.
+
#define MOZZI_COMPATIBILITY_LEVEL
Mozzi generally tries to keep your old sketches working, but we continue to find new (and hopefully b...
+
#define _MOZZI_HEADER_ONLY
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #include "FrequencyTimer2.h"
14 #include "TimerOne.h"
15 
16 #if (F_CPU != 16000000)
17 #warning
18  "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino! Results may vary with other speeds."
19 #endif
20 
21 ////// BEGIN analog input code ////////
22 #define MOZZI_FAST_ANALOG_IMPLEMENTED
23 extern uint8_t analog_reference;
24 
25 #define getADCReading() ADC /* officially (ADCL | (ADCH << 8)) but the compiler works it out */
26 #define channelNumToIndex(channel) channel
27 uint8_t adcPinToChannelNum(uint8_t pin) {
28 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
29  if (pin >= 54) pin -= 54; // allow for channel or pin numbers
30 #elif defined(__AVR_ATmega32U4__)
31  if (pin >= 18) pin -= 18; // allow for channel or pin numbers
32  pin = analogPinToChannel(pin); // moved from extra #if which was below in Arduino code, and redefined in mozzi_analog.h, with notes
33 #elif defined(__AVR_ATmega1284__)
34  if (pin >= 24) pin -= 24; // allow for channel or pin numbers
35 #else
36  if (pin >= 14) pin -= 14; // allow for channel or pin numbers
37 #endif
38  return pin;
39 }
40 
41 void adcStartConversion(uint8_t channel) {
42 #if defined(__AVR_ATmega32U4__)
43  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((channel >> 3) & 0x01) << MUX5);
44 #elif defined(ADCSRB) && defined(MUX5)
45  // the MUX5 bit of ADCSRB selects whether we're reading from channels
46  // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
47  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((channel >> 3) & 0x01) << MUX5);
48 #endif
49 
50 // from wiring_analog.c:
51 // set the analog reference (high two bits of ADMUX) and select the
52 // channel (low 4 bits). this also sets ADLAR (left-adjust result)
53 // to 0 (the default).
54 #if defined(ADMUX)
55 # if defined(TEENSYDUINO) // analog_reference is not part TEENSY 2.0 codebase
56  ADMUX = (1 << REFS0) | (channel & 0x07); // TB2017 this overwrote analog_reference
57 # else
58  ADMUX = (analog_reference << 6) | (channel & 0x07);
59 # endif
60 #endif
61 #if defined(ADCSRA) && defined(ADCL)
62  // start the conversion
63  ADCSRA |= (1 << ADSC);
64 #endif
65 }
66 
67 static void startSecondADCReadOnCurrentChannel() {
68  ADCSRA |= (1 << ADSC); // start a second conversion on the current channel
69 }
70 
71 /*
72 void adcEnableInterrupt(){
73  ADCSRA |= (1 << ADIE);
74 }
75 */
76 
77 ISR(ADC_vect, ISR_BLOCK)
78 {
79  advanceADCStep();
80 }
81 
82 void setupFastAnalogRead(int8_t speed) {
83  if (speed == FAST_ADC){ // divide by 16
84  ADCSRA |= (1 << ADPS2);
85  ADCSRA &= ~(1 << ADPS1);
86  ADCSRA &= ~(1 << ADPS0);
87  } else if(speed == FASTER_ADC){ // divide by 8
88  ADCSRA &= ~(1 << ADPS2);
89  ADCSRA |= (1 << ADPS1);
90  ADCSRA |= (1 << ADPS0);
91  } else if(speed == FASTEST_ADC){ // divide by 4
92  ADCSRA &= ~(1 << ADPS2);
93  ADCSRA |= (1 << ADPS1);
94  ADCSRA &= ~(1 << ADPS0);
95  }
96 }
97 
98 void setupMozziADC(int8_t speed) {
99  ADCSRA |= (1 << ADIE); // adc Enable Interrupt
100  adcDisconnectAllDigitalIns();
101 }
102 
103 ////// END analog input code ////////
104 
105 
106 
107 //// BEGIN AUDIO OUTPUT code ///////
108 /*
109 ATmega328 technical manual, Section 12.7.4:
110 The dual-slope operation [of phase correct pwm] has lower maximum operation
111 frequency than single slope operation. However, due to the symmetric feature
112 of the dual-slope PWM modes, these modes are preferred for motor control
113 applications.
114 Due to the single-slope operation, the operating frequency of the
115 fast PWM mode can be twice as high as the phase correct PWM mode that use
116 dual-slope operation. This high frequency makes the fast PWM mode well suited
117 for power regulation, rectification, and DAC applications. High frequency allows
118 physically small sized external components (coils, capacitors)..
119 
120 DAC, that's us! Fast PWM.
121 
122 PWM frequency tests
123 62500Hz, single 8 or dual 16 bits, bad aliasing
124 125000Hz dual 14 bits, sweet
125 250000Hz dual 12 bits, gritty, if you're gonna have 2 pins, have 14 bits
126 500000Hz dual 10 bits, grittier
127 16384Hz single nearly 9 bits (original mode) not bad for a single pin, but
128 carrier freq noise can be an issue
129 */
130 
131 // to store backups of timer registers so Mozzi can be stopped and pre_mozzi
132 // timer values can be restored
133 static uint8_t pre_mozzi_TCCR1A, pre_mozzi_TCCR1B, pre_mozzi_OCR1A,
134  pre_mozzi_TIMSK1;
135 
136 #if (AUDIO_MODE == HIFI)
137 #if defined(TCCR2A)
138 static uint8_t pre_mozzi_TCCR2A, pre_mozzi_TCCR2B, pre_mozzi_OCR2A,
139  pre_mozzi_TIMSK2;
140 #elif defined(TCCR2)
141 static uint8_t pre_mozzi_TCCR2, pre_mozzi_OCR2, pre_mozzi_TIMSK;
142 #elif defined(TCCR4A)
143 static uint8_t pre_mozzi_TCCR4A, pre_mozzi_TCCR4B, pre_mozzi_TCCR4C,
144  pre_mozzi_TCCR4D, pre_mozzi_TCCR4E, pre_mozzi_OCR4C, pre_mozzi_TIMSK4;
145 #endif
146 #endif
147 
148 static void backupPreMozziTimer1() {
149  // backup pre-mozzi register values for pausing later
150  pre_mozzi_TCCR1A = TCCR1A;
151  pre_mozzi_TCCR1B = TCCR1B;
152  pre_mozzi_OCR1A = OCR1A;
153  pre_mozzi_TIMSK1 = TIMSK1;
154 }
155 
156 #if (AUDIO_MODE == HIFI)
157 #if defined(TCCR2A)
158 static uint8_t mozzi_TCCR2A, mozzi_TCCR2B, mozzi_OCR2A, mozzi_TIMSK2;
159 #elif defined(TCCR2)
160 static uint8_t mozzi_TCCR2, mozzi_OCR2, mozzi_TIMSK;
161 #elif defined(TCCR4A)
162 static uint8_t mozzi_TCCR4A, mozzi_TCCR4B, mozzi_TCCR4C, mozzi_TCCR4D,
163  mozzi_TCCR4E, mozzi_OCR4C, mozzi_TIMSK4;
164 #endif
165 #endif
166 
167 #if (EXTERNAL_AUDIO_OUTPUT == true)
168 static void startAudio() {
169  backupPreMozziTimer1();
170  Timer1.initializeCPUCycles(
171  F_CPU / AUDIO_RATE,
172  PHASE_FREQ_CORRECT); // set period, phase and frequency correct
173  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using
174  // Timer1.attachInterrupt())
175 }
176 
177 ISR(TIMER1_OVF_vect, ISR_BLOCK) {
178  defaultAudioOutput();
179 }
180 #elif (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS)
181 # if (AUDIO_MODE == STANDARD_PLUS)
182 # include "AudioConfigStandardPlus.h"
183 # else
184 # include "AudioConfigStandard9bitPwm.h"
185 # endif
186 inline void audioOutput(const AudioOutput f)
187 {
189 # if (AUDIO_CHANNELS > 1)
190  AUDIO_CHANNEL_2_OUTPUT_REGISTER = f.r()+AUDIO_BIAS;
191 # endif
192 }
193 
194 static void startAudio() {
195  backupPreMozziTimer1();
196 
197  pinMode(AUDIO_CHANNEL_1_PIN, OUTPUT); // set pin to output for audio
198  // pinMode(AUDIO_CHANNEL_2_PIN, OUTPUT); // set pin to output for audio
199 # if (AUDIO_MODE == STANDARD)
200  Timer1.initializeCPUCycles(
201  F_CPU / AUDIO_RATE,
202  PHASE_FREQ_CORRECT); // set period, phase and frequency correct
203 # else // (AUDIO_MODE == STANDARD_PLUS)
204  Timer1.initializeCPUCycles(F_CPU / PWM_RATE,
205  FAST); // fast mode enables higher PWM rate
206 # endif
207  Timer1.pwm(AUDIO_CHANNEL_1_PIN,
208  AUDIO_BIAS); // pwm pin, 50% of Mozzi's duty cycle, ie. 0 signal
209 # if (AUDIO_CHANNELS > 1)
210  Timer1.pwm(AUDIO_CHANNEL_2_PIN, AUDIO_BIAS); // sets pin to output
211 # endif
212  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using
213  // Timer1.attachInterrupt())
214 }
215 
216 /* Interrupt service routine moves sound data from the output buffer to the
217 Arduino output register, running at AUDIO_RATE. */
218 
219 ISR(TIMER1_OVF_vect, ISR_BLOCK) {
220 # if (AUDIO_MODE == STANDARD_PLUS) && (AUDIO_RATE == 16384) // only update every second ISR, if lower audio rate
221  static boolean alternate;
222  alternate = !alternate;
223  if (alternate) return;
224 # endif
225 
226  defaultAudioOutput();
227 }
228 
229 #elif (AUDIO_MODE == HIFI)
230 # if (EXTERNAL_AUDIO_OUTPUT != true)
231 # include "AudioConfigHiSpeed14bitPwm.h"
232 inline void audioOutput(const AudioOutput f) {
233  // read about dual pwm at
234  // http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/
235  // sketches at http://wiki.openmusiclabs.com/wiki/PWMDAC,
236  // http://wiki.openmusiclabs.com/wiki/MiniArDSP
237  // if (!output_buffer.isEmpty()){
238  //unsigned int out = output_buffer.read();
239  // 14 bit, 7 bits on each pin
240  // AUDIO_CHANNEL_1_highByte_REGISTER = out >> 7; // B00111111 10000000 becomes
241  // B1111111
242  // try to avoid looping over 7 shifts - need to check timing or disassemble to
243  // see what really happens unsigned int out_high = out<<1; // B00111111
244  // 10000000 becomes B01111111 00000000
245  // AUDIO_CHANNEL_1_highByte_REGISTER = out_high >> 8; // B01111111 00000000
246  // produces B01111111 AUDIO_CHANNEL_1_lowByte_REGISTER = out & 127;
247  /* Atmega manual, p123
248  The high byte (OCR1xH) has to be written first.
249  When the high byte I/O location is written by the CPU,
250  the TEMP Register will be updated by the value written.
251  Then when the low byte (OCR1xL) is written to the lower eight bits,
252  the high byte will be copied into the upper 8-bits of
253  either the OCR1x buffer or OCR1x Compare Register in
254  the same system clock cycle.
255  */
256  AUDIO_CHANNEL_1_highByte_REGISTER = (f.l()+AUDIO_BIAS) >> AUDIO_BITS_PER_REGISTER;
257  AUDIO_CHANNEL_1_lowByte_REGISTER = (f.l()+AUDIO_BIAS) & ((1 << AUDIO_BITS_PER_REGISTER) - 1);
258 }
259 # endif
260 
261 static void setupTimer2();
262 static void startAudio() {
263  backupPreMozziTimer1();
264  // pwm on timer 1
265  pinMode(AUDIO_CHANNEL_1_highByte_PIN,
266  OUTPUT); // set pin to output for audio, use 3.9k resistor
267  pinMode(AUDIO_CHANNEL_1_lowByte_PIN,
268  OUTPUT); // set pin to output for audio, use 499k resistor
269  Timer1.initializeCPUCycles(
270  F_CPU / 125000,
271  FAST); // set period for 125000 Hz fast pwm carrier frequency = 14 bits
272  Timer1.pwm(AUDIO_CHANNEL_1_highByte_PIN,
273  0); // pwm pin, 0% duty cycle, ie. 0 signal
274  Timer1.pwm(AUDIO_CHANNEL_1_lowByte_PIN,
275  0); // pwm pin, 0% duty cycle, ie. 0 signal
276  // audio output interrupt on timer 2, sets the pwm levels of timer 1
277  setupTimer2();
278 }
279 
280 /* set up Timer 2 using modified FrequencyTimer2 library */
281 void dummy() {}
282 
283 static void backupPreMozziTimer2() {
284  // backup Timer2 register values
285 #if defined(TCCR2A)
286  pre_mozzi_TCCR2A = TCCR2A;
287  pre_mozzi_TCCR2B = TCCR2B;
288  pre_mozzi_OCR2A = OCR2A;
289  pre_mozzi_TIMSK2 = TIMSK2;
290 #elif defined(TCCR2)
291  pre_mozzi_TCCR2 = TCCR2;
292  pre_mozzi_OCR2 = OCR2;
293  pre_mozzi_TIMSK = TIMSK;
294 #elif defined(TCCR4A)
295  pre_mozzi_TCCR4B = TCCR4A;
296  pre_mozzi_TCCR4B = TCCR4B;
297  pre_mozzi_TCCR4B = TCCR4C;
298  pre_mozzi_TCCR4B = TCCR4D;
299  pre_mozzi_TCCR4B = TCCR4E;
300  pre_mozzi_OCR4C = OCR4C;
301  pre_mozzi_TIMSK4 = TIMSK4;
302 #endif
303 }
304 
305 // audio output interrupt on timer 2 (or 4 on ATMEGA32U4 cpu), sets the pwm
306 // levels of timer 2
307 static void setupTimer2() {
308  backupPreMozziTimer2(); // to reset while pausing
309  unsigned long period = F_CPU / AUDIO_RATE;
310  FrequencyTimer2::setPeriodCPUCycles(period);
311  FrequencyTimer2::setOnOverflow(dummy);
312  FrequencyTimer2::enable();
313 }
314 
315 #if defined(TIMER2_COMPA_vect)
316 ISR(TIMER2_COMPA_vect)
317 #elif defined(TIMER2_COMP_vect)
318 ISR(TIMER2_COMP_vect)
319 #elif defined(TIMER4_COMPA_vect)
320 ISR(TIMER4_COMPA_vect)
321 #else
322 #error
323  "This board does not have a hardware timer which is compatible with FrequencyTimer2"
324 void dummy_function(void)
325 #endif
326 {
327  defaultAudioOutput();
328 }
329 
330 // end of HIFI
331 
332 #endif
333 
334 //-----------------------------------------------------------------------------------------------------------------
335 
336 
337 void stopMozzi() {
338  noInterrupts();
339 
340  // restore backed up register values
341  TCCR1A = pre_mozzi_TCCR1A;
342  TCCR1B = pre_mozzi_TCCR1B;
343  OCR1A = pre_mozzi_OCR1A;
344 
345  TIMSK1 = pre_mozzi_TIMSK1;
346 
347 #if (AUDIO_MODE == HIFI)
348 #if defined(TCCR2A)
349  TCCR2A = pre_mozzi_TCCR2A;
350  TCCR2B = pre_mozzi_TCCR2B;
351  OCR2A = pre_mozzi_OCR2A;
352  TIMSK2 = pre_mozzi_TIMSK2;
353 #elif defined(TCCR2)
354  TCCR2 = pre_mozzi_TCCR2;
355  OCR2 = pre_mozzi_OCR2;
356  TIMSK = pre_mozzi_TIMSK;
357 #elif defined(TCCR4A)
358  TCCR4B = pre_mozzi_TCCR4A;
359  TCCR4B = pre_mozzi_TCCR4B;
360  TCCR4B = pre_mozzi_TCCR4C;
361  TCCR4B = pre_mozzi_TCCR4D;
362  TCCR4B = pre_mozzi_TCCR4E;
363  OCR4C = pre_mozzi_OCR4C;
364  TIMSK4 = pre_mozzi_TIMSK4;
365 #endif
366 #endif
367  interrupts();
368 }
369 
370 // Unmodified TimerOne.cpp has TIMER3_OVF_vect.
371 // Watch out if you update the library file.
372 // The symptom will be no sound.
373 // ISR(TIMER1_OVF_vect)
374 // {
375 // Timer1.isrCallback();
376 // }
377 //// END AUDIO OUTPUT code ///////
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
#define AUDIO_CHANNEL_1_OUTPUT_REGISTER
-
#define AUDIO_CHANNEL_1_PIN
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
-
#define AUDIO_BIAS
Definition: MozziGuts.h:229
+
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #include "utility/FrequencyTimer2.h"
14 #include "utility/TimerOne.h"
15 
16 #if (F_CPU != 16000000)
17 #warning
18  "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino! Results may vary with other speeds."
19 #endif
20 
21 ////// BEGIN analog input code ////////
22 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
23 extern uint8_t analog_reference;
24 
25 ISR(ADC_vect, ISR_BLOCK)
26 {
27  MozziPrivate::advanceADCStep();
28 }
29 
30 namespace MozziPrivate {
31 #define getADCReading() ADC /* officially (ADCL | (ADCH << 8)) but the compiler works it out */
32 #define channelNumToIndex(channel) channel
33 uint8_t adcPinToChannelNum(uint8_t pin) {
34 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
35  if (pin >= 54) pin -= 54; // allow for channel or pin numbers
36 #elif defined(__AVR_ATmega32U4__)
37  if (pin >= 18) pin -= 18; // allow for channel or pin numbers
38 # if defined(CORE_TEENSY) // special handling for Teensy2, which does not (did not?) have an analogPinToChannel() define (see https://github.com/sensorium/Mozzi/issues/10)
39  static const uint8_t PROGMEM adc_mapping[] = {
40  // 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8
41  0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8, 10, 11, 12, 13, 7, 6, 5, 4, 1, 0, 8
42  };
43  pin = pgm_read_byte(adc_mapping + (P));
44 # else
45  pin = analogPinToChannel(pin);
46 # endif
47 #elif defined(__AVR_ATmega1284__)
48  if (pin >= 24) pin -= 24; // allow for channel or pin numbers
49 #else
50  if (pin >= 14) pin -= 14; // allow for channel or pin numbers
51 #endif
52  return pin;
53 }
54 
55 void adcStartConversion(uint8_t channel) {
56 #if defined(__AVR_ATmega32U4__)
57  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((channel >> 3) & 0x01) << MUX5);
58 #elif defined(ADCSRB) && defined(MUX5)
59  // the MUX5 bit of ADCSRB selects whether we're reading from channels
60  // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
61  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((channel >> 3) & 0x01) << MUX5);
62 #endif
63 
64 // from wiring_analog.c:
65 // set the analog reference (high two bits of ADMUX) and select the
66 // channel (low 4 bits). this also sets ADLAR (left-adjust result)
67 // to 0 (the default).
68 #if defined(ADMUX)
69 # if defined(TEENSYDUINO) // analog_reference is not part TEENSY 2.0 codebase
70  ADMUX = (1 << REFS0) | (channel & 0x07); // TB2017 this overwrote analog_reference
71 # else
72  ADMUX = (analog_reference << 6) | (channel & 0x07);
73 # endif
74 #endif
75 #if defined(ADCSRA) && defined(ADCL)
76  // start the conversion
77  ADCSRA |= (1 << ADSC);
78 #endif
79 }
80 
81 static void startSecondADCReadOnCurrentChannel() {
82  ADCSRA |= (1 << ADSC); // start a second conversion on the current channel
83 }
84 
85 /*
86 void adcEnableInterrupt(){
87  ADCSRA |= (1 << ADIE);
88 }
89 */
90 
91 void setupMozziADC(int8_t speed) {
92  ADCSRA |= (1 << ADIE); // adc Enable Interrupt
93  adcDisconnectAllDigitalIns();
94  setupFastAnalogRead(speed);
95 }
96 
97 void setupFastAnalogRead(int8_t speed) {
98  if (speed == FAST_ADC){ // divide by 16
99  ADCSRA |= (1 << ADPS2);
100  ADCSRA &= ~(1 << ADPS1);
101  ADCSRA &= ~(1 << ADPS0);
102  } else if(speed == FASTER_ADC){ // divide by 8
103  ADCSRA &= ~(1 << ADPS2);
104  ADCSRA |= (1 << ADPS1);
105  ADCSRA |= (1 << ADPS0);
106  } else if(speed == FASTEST_ADC){ // divide by 4
107  ADCSRA &= ~(1 << ADPS2);
108  ADCSRA |= (1 << ADPS1);
109  ADCSRA &= ~(1 << ADPS0);
110  }
111 }
112 }
113 
114 #endif
115 
116 ////// END analog input code ////////
117 
118 
119 namespace MozziPrivate {
120 //// BEGIN AUDIO OUTPUT code ///////
121 /*
122 ATmega328 technical manual, Section 12.7.4:
123 The dual-slope operation [of phase correct pwm] has lower maximum operation
124 frequency than single slope operation. However, due to the symmetric feature
125 of the dual-slope PWM modes, these modes are preferred for motor control
126 applications.
127 Due to the single-slope operation, the operating frequency of the
128 fast PWM mode can be twice as high as the phase correct PWM mode that use
129 dual-slope operation. This high frequency makes the fast PWM mode well suited
130 for power regulation, rectification, and DAC applications. High frequency allows
131 physically small sized external components (coils, capacitors)..
132 
133 DAC, that's us! Fast PWM.
134 
135 PWM frequency tests
136 62500Hz, single 8 or dual 16 bits, bad aliasing
137 125000Hz dual 14 bits, sweet
138 250000Hz dual 12 bits, gritty, if you're gonna have 2 pins, have 14 bits
139 500000Hz dual 10 bits, grittier
140 16384Hz single nearly 9 bits (original mode) not bad for a single pin, but
141 carrier freq noise can be an issue
142 */
143 
144 // to store backups of timer registers so Mozzi can be stopped and pre_mozzi
145 // timer values can be restored
146 static uint8_t pre_mozzi_TCCR1A, pre_mozzi_TCCR1B, pre_mozzi_OCR1A,
147  pre_mozzi_TIMSK1;
148 
149 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
150 #if defined(TCCR2A)
151 static uint8_t pre_mozzi_TCCR2A, pre_mozzi_TCCR2B, pre_mozzi_OCR2A,
152  pre_mozzi_TIMSK2;
153 #elif defined(TCCR2)
154 static uint8_t pre_mozzi_TCCR2, pre_mozzi_OCR2, pre_mozzi_TIMSK;
155 #elif defined(TCCR4A)
156 static uint8_t pre_mozzi_TCCR4A, pre_mozzi_TCCR4B, pre_mozzi_TCCR4C,
157  pre_mozzi_TCCR4D, pre_mozzi_TCCR4E, pre_mozzi_OCR4C, pre_mozzi_TIMSK4;
158 #endif
159 #endif
160 
161 static void backupPreMozziTimer1() {
162  // backup pre-mozzi register values for pausing later
163  pre_mozzi_TCCR1A = TCCR1A;
164  pre_mozzi_TCCR1B = TCCR1B;
165  pre_mozzi_OCR1A = OCR1A;
166  pre_mozzi_TIMSK1 = TIMSK1;
167 }
168 
169 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
170 #if defined(TCCR2A)
171 static uint8_t mozzi_TCCR2A, mozzi_TCCR2B, mozzi_OCR2A, mozzi_TIMSK2;
172 #elif defined(TCCR2)
173 static uint8_t mozzi_TCCR2, mozzi_OCR2, mozzi_TIMSK;
174 #elif defined(TCCR4A)
175 static uint8_t mozzi_TCCR4A, mozzi_TCCR4B, mozzi_TCCR4C, mozzi_TCCR4D,
176  mozzi_TCCR4E, mozzi_OCR4C, mozzi_TIMSK4;
177 #endif
178 #endif
179 
180 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
181 static void startAudio() {
182  backupPreMozziTimer1();
183  Timer1.initializeCPUCycles(
184  (F_CPU/MOZZI_AUDIO_RATE)-1, // the -1 here is a result of empirical tests
185  // that showed that it brings the resulting frequency
186  // closer to what is expected.
187  // see: https://github.com/sensorium/Mozzi/pull/202
188 
189  PHASE_FREQ_CORRECT); // set period, phase and frequency correct
190  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using
191  // Timer1.attachInterrupt())
192 }
193 
194 } // namespace MozziPrivate
195 
196 ISR(TIMER1_OVF_vect, ISR_BLOCK) {
197  MozziPrivate::defaultAudioOutput();
198 }
199 
200 namespace MozziPrivate {
201 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
202 static void startAudio() {}
203 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
204 inline void audioOutput(const AudioOutput f)
205 {
206  MOZZI_AUDIO_PIN_1_REGISTER = f.l()+MOZZI_AUDIO_BIAS;
207 # if (MOZZI_AUDIO_CHANNELS > 1)
208  MOZZI_AUDIO_PIN_2_REGISTER = f.r()+MOZZI_AUDIO_BIAS;
209 # endif
210 }
211 
212 static void startAudio() {
213  backupPreMozziTimer1();
214 
215  pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); // set pin to output for audio
216 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) && (MOZZI_PWM_RATE < 32768) // Formerly known as the - long since deprecated - "STANDARD" mode
217  Timer1.initializeCPUCycles(
218  (F_CPU/MOZZI_AUDIO_RATE)-1,// the -1 here is a result of empirical tests
219  // that showed that it brings the resulting frequency
220  // closer to what is expected.
221  // see: https://github.com/sensorium/Mozzi/pull/202
222  PHASE_FREQ_CORRECT); // set period, phase and frequency correct
223 # else // Formerly known as "STANDARD_PLUS" mode
224  Timer1.initializeCPUCycles((F_CPU/MOZZI_PWM_RATE)-1, // the -1 here is a result of empirical tests
225  // that showed that it brings the resulting frequency
226  // closer to what is expected.
227  // see: https://github.com/sensorium/Mozzi/pull/202
228  FAST); // fast mode enables higher PWM rate
229 # endif
230  Timer1.pwm(MOZZI_AUDIO_PIN_1,
231  MOZZI_AUDIO_BIAS); // pwm pin, 50% of Mozzi's duty cycle, ie. 0 signal
232 # if (MOZZI_AUDIO_CHANNELS > 1)
233  pinMode(MOZZI_AUDIO_PIN_2, OUTPUT); // set pin to output for audio
234  Timer1.pwm(MOZZI_AUDIO_PIN_2, MOZZI_AUDIO_BIAS);
235 # endif
236  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using
237  // Timer1.attachInterrupt())
238 }
239 
240 } // namespace MozziPrivate
241 
242 /* Interrupt service routine moves sound data from the output buffer to the
243 Arduino output register, running at MOZZI_AUDIO_RATE. */
244 ISR(TIMER1_OVF_vect, ISR_BLOCK) {
245 # if (MOZZI_AUDIO_RATE < MOZZI_PWM_RATE) // only update every second ISR, if lower audio rate
246  static_assert(2l*MOZZI_AUDIO_RATE == MOZZI_PWM_RATE, "audio rate must the same, or exactly half of the pwm rate!");
247  static boolean alternate;
248  alternate = !alternate;
249  if (alternate) return;
250 # endif
251 
252  MozziPrivate::defaultAudioOutput();
253 }
254 
255 namespace MozziPrivate {
256 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
257 inline void audioOutput(const AudioOutput f) {
258  // read about dual pwm at
259  // http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/
260  // sketches at http://wiki.openmusiclabs.com/wiki/PWMDAC,
261  // http://wiki.openmusiclabs.com/wiki/MiniArDSP
262  // if (!output_buffer.isEmpty()){
263  //unsigned int out = output_buffer.read();
264  // 14 bit, 7 bits on each pin
265  // MOZZI_AUDIO_PIN_1_REGISTER = out >> 7; // B00111111 10000000 becomes
266  // B1111111
267  // try to avoid looping over 7 shifts - need to check timing or disassemble to
268  // see what really happens unsigned int out_high = out<<1; // B00111111
269  // 10000000 becomes B01111111 00000000
270  // MOZZI_AUDIO_PIN_1_REGISTER = out_high >> 8; // B01111111 00000000
271  // produces B01111111 MOZZI_AUDIO_PIN_1_LOW_REGISTER = out & 127;
272  /* Atmega manual, p123
273  The high byte (OCR1xH) has to be written first.
274  When the high byte I/O location is written by the CPU,
275  the TEMP Register will be updated by the value written.
276  Then when the low byte (OCR1xL) is written to the lower eight bits,
277  the high byte will be copied into the upper 8-bits of
278  either the OCR1x buffer or OCR1x Compare Register in
279  the same system clock cycle.
280  */
281  MOZZI_AUDIO_PIN_1_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_CHANNEL;
282  MOZZI_AUDIO_PIN_1_LOW_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1);
283 }
284 
285 static void setupTimer2();
286 static void startAudio() {
287  backupPreMozziTimer1();
288  // pwm on timer 1
289  pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); // set pin to output for audio, use 3.9k resistor
290  pinMode(MOZZI_AUDIO_PIN_1_LOW, OUTPUT); // set pin to output for audio, use 499k resistor
291  Timer1.initializeCPUCycles(
292  F_CPU/125000,
293  FAST); // set period for 125000 Hz fast pwm carrier frequency = 14 bits
294  Timer1.pwm(MOZZI_AUDIO_PIN_1, 0); // pwm pin, 0% duty cycle, ie. 0 signal
295  Timer1.pwm(MOZZI_AUDIO_PIN_1_LOW, 0);
296  // audio output interrupt on timer 2, sets the pwm levels of timer 1
297  setupTimer2();
298 }
299 
300 /* set up Timer 2 using modified FrequencyTimer2 library */
301 void dummy() {}
302 
303 static void backupPreMozziTimer2() {
304  // backup Timer2 register values
305 #if defined(TCCR2A)
306  pre_mozzi_TCCR2A = TCCR2A;
307  pre_mozzi_TCCR2B = TCCR2B;
308  pre_mozzi_OCR2A = OCR2A;
309  pre_mozzi_TIMSK2 = TIMSK2;
310 #elif defined(TCCR2)
311  pre_mozzi_TCCR2 = TCCR2;
312  pre_mozzi_OCR2 = OCR2;
313  pre_mozzi_TIMSK = TIMSK;
314 #elif defined(TCCR4A)
315  pre_mozzi_TCCR4B = TCCR4A;
316  pre_mozzi_TCCR4B = TCCR4B;
317  pre_mozzi_TCCR4B = TCCR4C;
318  pre_mozzi_TCCR4B = TCCR4D;
319  pre_mozzi_TCCR4B = TCCR4E;
320  pre_mozzi_OCR4C = OCR4C;
321  pre_mozzi_TIMSK4 = TIMSK4;
322 #endif
323 }
324 
325 // audio output interrupt on timer 2 (or 4 on ATMEGA32U4 cpu), sets the pwm
326 // levels of timer 2
327 static void setupTimer2() {
328  backupPreMozziTimer2(); // to reset while pausing
329  unsigned long period = F_CPU / MOZZI_AUDIO_RATE;
330  FrequencyTimer2::setPeriodCPUCycles(period);
331  FrequencyTimer2::setOnOverflow(dummy);
332  FrequencyTimer2::enable();
333 }
334 
335 } // namespace MozziPrivate
336 
337 #if defined(TIMER2_COMPA_vect)
338 ISR(TIMER2_COMPA_vect)
339 #elif defined(TIMER2_COMP_vect)
340 ISR(TIMER2_COMP_vect)
341 #elif defined(TIMER4_COMPA_vect)
342 ISR(TIMER4_COMPA_vect)
343 #else
344 #error
345  "This board does not have a hardware timer which is compatible with FrequencyTimer2"
346 void dummy_function(void)
347 #endif
348 {
349  MozziPrivate::defaultAudioOutput();
350 }
351 
352 // end of HIFI
353 
354 namespace MozziPrivate {
355 
356 #endif
357 
358 //-----------------------------------------------------------------------------------------------------------------
359 
360 
361 void stopMozzi() {
362  noInterrupts();
363 
364  // restore backed up register values
365  TCCR1A = pre_mozzi_TCCR1A;
366  TCCR1B = pre_mozzi_TCCR1B;
367  OCR1A = pre_mozzi_OCR1A;
368 
369  TIMSK1 = pre_mozzi_TIMSK1;
370 
371 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
372 #if defined(TCCR2A)
373  TCCR2A = pre_mozzi_TCCR2A;
374  TCCR2B = pre_mozzi_TCCR2B;
375  OCR2A = pre_mozzi_OCR2A;
376  TIMSK2 = pre_mozzi_TIMSK2;
377 #elif defined(TCCR2)
378  TCCR2 = pre_mozzi_TCCR2;
379  OCR2 = pre_mozzi_OCR2;
380  TIMSK = pre_mozzi_TIMSK;
381 #elif defined(TCCR4A)
382  TCCR4B = pre_mozzi_TCCR4A;
383  TCCR4B = pre_mozzi_TCCR4B;
384  TCCR4B = pre_mozzi_TCCR4C;
385  TCCR4B = pre_mozzi_TCCR4D;
386  TCCR4B = pre_mozzi_TCCR4E;
387  OCR4C = pre_mozzi_OCR4C;
388  TIMSK4 = pre_mozzi_TIMSK4;
389 #endif
390 #endif
391  interrupts();
392 }
393 
394 // Unmodified TimerOne.cpp has TIMER3_OVF_vect.
395 // Watch out if you update the library file.
396 // The symptom will be no sound.
397 // ISR(TIMER1_OVF_vect)
398 // {
399 // Timer1.isrCallback();
400 // }
401 //// END AUDIO OUTPUT code ///////
402 
403 //// BEGIN Random seeding ////////
404 #if defined (__AVR_ATmega644P__)
405 
406 // a less fancy version for gizduino (__AVR_ATmega644P__) which doesn't know INTERNAL
407 static long longRandom()
408 {
409  return ((long)analogRead(0)+63)*(analogRead(1)+97); // added offsets in case analogRead is 0
410 }
411 
412 #else
413 
414 /*
415 longRandom(), used as a seed generator, comes from:
416 http://arduino.cc/forum/index.php/topic,38091.0.html
417 // AUTHOR: Rob Tillaart
418 // PURPOSE: Simple Random functions based upon unreliable internal temp sensor
419 // VERSION: 0.1
420 // DATE: 2011-05-01
421 //
422 // Released to the public domain, use at own risk
423 //
424 */
425 static long longRandom()
426 {
427  //analogReference(INTERNAL);
428  unsigned long rv = 0;
429  for (uint8_t i=0; i< 32; i++) rv |= ((analogRead(8)+1171) & 1L) << i; // added 1171 in case analogRead is 0
430  return rv;
431 }
432 #endif
433 
434 void MozziRandPrivate::autoSeed() {
435  ADCSRA &= ~ (1 << ADIE); // adc Disable Interrupt, re-enable at end
436  // this attempt at remembering analog_reference stops it working
437  // maybe needs a delay after changing analog reference in longRandom (Arduino reference suggests this)
438  // because the analog reads return 0
439  //uint8_t analog_reference_orig = ADMUX&192; // analog_reference is high 2 bits of ADMUX, store this because longRandom sets it to internal
440  x = longRandom();
441  y = longRandom();
442  z = longRandom();
443  //analogReference(analog_reference_orig); // change back to original
444  ADCSRA |= (1 << ADIE); // adc re-Enable Interrupt
445 }
446 
447 //// END Random seeding ////////
448 }
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_ESP32())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 ////// BEGIN analog input code ////////
18 //#define MOZZI_FAST_ANALOG_IMPLEMENTED // not yet
19 #define getADCReading() 0
20 #define channelNumToIndex(channel) channel
21 uint8_t adcPinToChannelNum(uint8_t pin) {
22  return pin;
23 }
24 void adcStartConversion(uint8_t channel) {
25 #warning Fast analog read not implemented on this platform
26 }
27 void startSecondADCReadOnCurrentChannel() {
28 #warning Fast analog read not implemented on this platform
29 }
30 void setupFastAnalogRead(int8_t speed) {
31 #warning Fast analog read not implemented on this platform
32 }
33 void setupMozziADC(int8_t speed) {
34 #warning Fast analog read not implemented on this platform
35 }
36 ////// END analog input code ////////
37 
38 
39 
40 
41 //// BEGIN AUDIO OUTPUT code ///////
42 #include <driver/i2s.h> // for I2S-based output modes
43 #include <driver/timer.h> // for EXTERNAL_AUDIO_OUTPUT
44 
45 #if (EXTERNAL_AUDIO_OUTPUT != true)
46 # include "AudioConfigESP32.h"
47 // On ESP32 we cannot test wether the DMA buffer has room. Instead, we have to use a one-sample mini buffer. In each iteration we
48 // _try_ to write that sample to the DMA buffer, and if successful, we can buffer the next sample. Somewhat cumbersome, but works.
49 // TODO: Should ESP32 gain an implemenation of i2s_available(), we should switch to using that, instead.
50 static bool _esp32_can_buffer_next = true;
52 static uint16_t _esp32_prev_sample[2];
53 # define ESP_SAMPLE_SIZE (2*sizeof(uint16_t))
54 # elif (ESP32_AUDIO_OUT_MODE == PT8211_DAC)
55 static int16_t _esp32_prev_sample[2];
56 # define ESP_SAMPLE_SIZE (2*sizeof(int16_t))
57 # elif (ESP32_AUDIO_OUT_MODE == PDM_VIA_I2S)
58 static uint32_t _esp32_prev_sample[PDM_RESOLUTION];
59 # define ESP_SAMPLE_SIZE (PDM_RESOLUTION*sizeof(uint32_t))
60 # endif
61 
62 inline bool esp32_tryWriteSample() {
63  size_t bytes_written;
64  i2s_write(i2s_num, &_esp32_prev_sample, ESP_SAMPLE_SIZE, &bytes_written, 0);
65  return (bytes_written != 0);
66 }
67 
68 inline bool canBufferAudioOutput() {
69  if (_esp32_can_buffer_next) return true;
70  _esp32_can_buffer_next = esp32_tryWriteSample();
71  return _esp32_can_buffer_next;
72 }
73 
74 inline void audioOutput(const AudioOutput f) {
76  _esp32_prev_sample[0] = (f.l() + AUDIO_BIAS) << 8;
77 # if (AUDIO_CHANNELS > 1)
78  _esp32_prev_sample[1] = (f.r() + AUDIO_BIAS) << 8;
79 # else
80  // For simplicity of code, even in mono, we're writing stereo samples
81  _esp32_prev_sample[1] = _esp32_prev_sample[0];
82 # endif
83 # elif (ESP32_AUDIO_OUT_MODE == PDM_VIA_I2S)
84  for (uint8_t i=0; i<PDM_RESOLUTION; ++i) {
85  _esp32_prev_sample[i] = pdmCode32(f.l() + AUDIO_BIAS);
86  }
87 # else
88  // PT8211 takes signed samples
89  _esp32_prev_sample[0] = f.l();
90  _esp32_prev_sample[1] = f.r();
91 # endif
92  _esp32_can_buffer_next = esp32_tryWriteSample();
93 }
94 #endif
95 
96 #if (BYPASS_MOZZI_OUTPUT_BUFFER != true)
97 void CACHED_FUNCTION_ATTR timer0_audio_output_isr(void *) {
98  TIMERG0.int_clr_timers.t0 = 1;
99  TIMERG0.hw_timer[0].config.alarm_en = 1;
100  defaultAudioOutput();
101 }
102 #endif
103 
104 static void startAudio() {
105 #if (BYPASS_MOZZI_OUTPUT_BUFFER != true) // for external audio output, set up a timer running a audio rate
106  static intr_handle_t s_timer_handle;
107  const int div = 2;
108  timer_config_t config = {
109  .alarm_en = (timer_alarm_t)true,
110  .counter_en = (timer_start_t)false,
111  .intr_type = (timer_intr_mode_t) TIMER_INTR_LEVEL,
112  .counter_dir = TIMER_COUNT_UP,
113  .auto_reload = (timer_autoreload_t) true,
114  .divider = div // For max available precision: The APB_CLK clock signal is running at 80 MHz, i.e. 2/80 uS per tick
115  // Min acceptable value is 2
116  };
117  timer_init(TIMER_GROUP_0, TIMER_0, &config);
118  timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0);
119  timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 80000000UL / AUDIO_RATE / div);
120  timer_enable_intr(TIMER_GROUP_0, TIMER_0);
121  timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer0_audio_output_isr, nullptr, 0, &s_timer_handle);
122  timer_start(TIMER_GROUP_0, TIMER_0);
123 
124 #else
125  static const i2s_config_t i2s_config = {
127  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
129  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
130 # endif
131  .sample_rate = AUDIO_RATE * PDM_RESOLUTION,
132  .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // only the top 8 bits will actually be used by the internal DAC, but using 8 bits straight away seems buggy
133  .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // always use stereo output. mono seems to be buggy, and the overhead is insignifcant on the ESP32
134  .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB), // this appears to be the correct setting for internal DAC and PT8211, but not for other dacs
135  .intr_alloc_flags = 0, // default interrupt priority
136  .dma_buf_count = 8, // 8*128 bytes of buffer corresponds to 256 samples (2 channels, see above, 2 bytes per sample per channel)
137  .dma_buf_len = 128,
138  .use_apll = false
139  };
140 
141  i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
143  static const i2s_pin_config_t pin_config = {
144  .bck_io_num = ESP32_I2S_BCK_PIN,
145  .ws_io_num = ESP32_I2S_WS_PIN,
146  .data_out_num = ESP32_I2S_DATA_PIN,
147  .data_in_num = -1
148  };
149  i2s_set_pin((i2s_port_t)i2s_num, &pin_config);
151  i2s_set_pin((i2s_port_t)i2s_num, NULL);
152  i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
153 # endif
154  i2s_zero_dma_buffer((i2s_port_t)i2s_num);
155 
156 #endif
157 }
158 
159 void stopMozzi() {
160  // TODO: implement me
161 }
162 //// END AUDIO OUTPUT code ///////
#define BYPASS_MOZZI_OUTPUT_BUFFER
-
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
#define PT8211_DAC
-
#define INTERNAL_DAC
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
-
#define PDM_VIA_I2S
Definition: AudioConfigESP.h:9
-
#define ESP32_AUDIO_OUT_MODE
-
#define PDM_RESOLUTION
-
#define AUDIO_BIAS
Definition: MozziGuts.h:229
+
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_ESP32())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 namespace MozziPrivate {
18 ////// BEGIN analog input code ////////
19 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
20 #error not yet implemented
21 
22 #define getADCReading() 0
23 #define channelNumToIndex(channel) channel
24 uint8_t adcPinToChannelNum(uint8_t pin) {
25  return pin;
26 }
27 void adcStartConversion(uint8_t channel) {
28 }
29 void startSecondADCReadOnCurrentChannel() {
30 }
31 void setupMozziADC(int8_t speed) {
32 }
33 void setupFastAnalogRead(int8_t speed) {
34 }
35 
36 #endif
37 ////// END analog input code ////////
38 
39 
40 //// BEGIN AUDIO OUTPUT code ///////
41 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
42 } // namespace MozziPrivate
43 # include <driver/i2s.h> // for I2S-based output modes, including - technically - internal DAC
44 namespace MozziPrivate {
45 const i2s_port_t i2s_num = MOZZI_I2S_PORT;
46 
47 // On ESP32 we cannot test wether the DMA buffer has room. Instead, we have to use a one-sample mini buffer. In each iteration we
48 // _try_ to write that sample to the DMA buffer, and if successful, we can buffer the next sample. Somewhat cumbersome, but works.
49 // TODO: Should ESP32 gain an implemenation of i2s_available(), we should switch to using that, instead.
50 static bool _esp32_can_buffer_next = true;
51 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
52 static uint16_t _esp32_prev_sample[2];
53 # define ESP_SAMPLE_SIZE (2*sizeof(uint16_t))
54 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
55 static int16_t _esp32_prev_sample[2];
56 # define ESP_SAMPLE_SIZE (2*sizeof(int16_t))
57 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
58 static uint32_t _esp32_prev_sample[PDM_RESOLUTION];
59 # define ESP_SAMPLE_SIZE (PDM_RESOLUTION*sizeof(uint32_t))
60 # endif
61 
62 inline bool esp32_tryWriteSample() {
63  size_t bytes_written;
64  i2s_write(i2s_num, &_esp32_prev_sample, ESP_SAMPLE_SIZE, &bytes_written, 0);
65  return (bytes_written != 0);
66 }
67 
68 inline bool canBufferAudioOutput() {
69  if (_esp32_can_buffer_next) return true;
70  _esp32_can_buffer_next = esp32_tryWriteSample();
71  return _esp32_can_buffer_next;
72 }
73 
74 inline void audioOutput(const AudioOutput f) {
75 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
76  _esp32_prev_sample[0] = (f.l() + MOZZI_AUDIO_BIAS) << 8;
77 # if (MOZZI_AUDIO_CHANNELS > 1)
78  _esp32_prev_sample[1] = (f.r() + MOZZI_AUDIO_BIAS) << 8;
79 # else
80  // For simplicity of code, even in mono, we're writing stereo samples
81  _esp32_prev_sample[1] = _esp32_prev_sample[0];
82 # endif
83 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
84  for (uint8_t i=0; i<MOZZI_PDM_RESOLUTION; ++i) {
85  _esp32_prev_sample[i] = pdmCode32(f.l() + MOZZI_AUDIO_BIAS);
86  }
87 # else
88  // PT8211 takes signed samples
89  _esp32_prev_sample[0] = f.l();
90  _esp32_prev_sample[1] = f.r();
91 # endif
92  _esp32_can_buffer_next = esp32_tryWriteSample();
93 }
94 #endif
95 
96 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
97 
98 } // namespace MozziPrivate
99 # include <driver/timer.h>
100 namespace MozziPrivate {
101 
102 void CACHED_FUNCTION_ATTR timer0_audio_output_isr(void *) {
103  TIMERG0.int_clr_timers.t0 = 1;
104  TIMERG0.hw_timer[0].config.alarm_en = 1;
105  defaultAudioOutput();
106 }
107 #endif
108 
109 static void startAudio() {
110 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // for external audio output, set up a timer running a audio rate
111  static intr_handle_t s_timer_handle;
112  const int div = 2;
113  timer_config_t config = {
114  .alarm_en = (timer_alarm_t)true,
115  .counter_en = (timer_start_t)false,
116  .intr_type = (timer_intr_mode_t) TIMER_INTR_LEVEL,
117  .counter_dir = TIMER_COUNT_UP,
118  .auto_reload = (timer_autoreload_t) true,
119  .divider = div // For max available precision: The APB_CLK clock signal is running at 80 MHz, i.e. 2/80 uS per tick
120  // Min acceptable value is 2
121  };
122  timer_init(TIMER_GROUP_0, TIMER_0, &config);
123  timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0);
124  timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 80000000UL / MOZZI_AUDIO_RATE / div);
125  timer_enable_intr(TIMER_GROUP_0, TIMER_0);
126  timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer0_audio_output_isr, nullptr, 0, &s_timer_handle);
127  timer_start(TIMER_GROUP_0, TIMER_0);
128 
129 #elif !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
130  static const i2s_config_t i2s_config = {
131 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
132  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
133 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
134  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
135 # endif
136  .sample_rate = MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION,
137  .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // only the top 8 bits will actually be used by the internal DAC, but using 8 bits straight away seems buggy
138  .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // always use stereo output. mono seems to be buggy, and the overhead is insignifcant on the ESP32
139  .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB), // this appears to be the correct setting for internal DAC and PT8211, but not for other dacs
140  .intr_alloc_flags = 0, // default interrupt priority
141  .dma_buf_count = 8, // 8*128 bytes of buffer corresponds to 256 samples (2 channels, see above, 2 bytes per sample per channel)
142  .dma_buf_len = 128,
143  .use_apll = false
144  };
145 
146  i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
147 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
148  static const i2s_pin_config_t pin_config = {
149  .bck_io_num = MOZZI_I2S_PIN_BCK,
150  .ws_io_num = MOZZI_I2S_PIN_WS,
151  .data_out_num = MOZZI_I2S_PIN_DATA,
152  .data_in_num = -1
153  };
154  i2s_set_pin((i2s_port_t)i2s_num, &pin_config);
155 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
156  i2s_set_pin((i2s_port_t)i2s_num, NULL);
157  i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
158 # endif
159  i2s_zero_dma_buffer((i2s_port_t)i2s_num);
160 
161 #endif
162 }
163 
164 void stopMozzi() {
165  // TODO: implement me
166 }
167 //// END AUDIO OUTPUT code ///////
168 
169 //// BEGIN Random seeding ////////
170 void MozziRandPrivate::autoSeed() {
171  x = esp_random();
172  y = esp_random();
173  z = esp_random();
174 }
175 //// END Random seeding ////////
176 
177 #undef ESP_SAMPLE_SIZE // only used inside this file
178 
179 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_ESP8266())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 ////// BEGIN analog input code ////////
18 //#define MOZZI_FAST_ANALOG_IMPLEMENTED // not yet
19 #define getADCReading() 0
20 #define channelNumToIndex(channel) channel
21 uint8_t adcPinToChannelNum(uint8_t pin) {
22  return pin;
23 }
24 void adcStartConversion(uint8_t channel) {
25 #warning Fast analog read not implemented on this platform
26 }
27 void startSecondADCReadOnCurrentChannel() {
28 #warning Fast analog read not implemented on this platform
29 }
30 void setupFastAnalogRead(int8_t speed) {
31 #warning Fast analog read not implemented on this platform
32 }
33 void setupMozziADC(int8_t speed) {
34 #warning Fast analog read not implemented on this platform
35 }
36 ////// END analog input code ////////
37 
38 
39 
40 //// BEGIN AUDIO OUTPUT code ///////
41 #define LOOP_YIELD yield();
42 
43 #include <uart.h>
44 #include <i2s.h>
45 uint16_t output_buffer_size = 0;
46 
47 #if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user
48 # include "AudioConfigESP.h"
49 
51 # include <i2s.h>
52 inline bool canBufferAudioOutput() {
53  return (i2s_available() >= PDM_RESOLUTION);
54 }
55 inline void audioOutput(const AudioOutput f) {
56  for (uint8_t words = 0; words < PDM_RESOLUTION; ++words) {
57  i2s_write_sample(pdmCode32(f.l()+AUDIO_BIAS));
58  }
59 }
61 # include <i2s.h>
62 inline bool canBufferAudioOutput() {
63  return (i2s_available() >= PDM_RESOLUTION);
64 }
65 inline void audioOutput(const AudioOutput f) {
66  i2s_write_lr(f.l(), f.r()); // Note: i2s_write expects zero-centered output
67 }
68 # else // (ESP_AUDIO_OUT_MODE == PDM_VIA_SERIAL)
69 // NOTE: This intermediate step is needed because the output timer is running at a rate higher than AUDIO_RATE, and we need to rely on the (tiny)
70 // serial buffer itself to achieve appropriate rate control
71 void CACHED_FUNCTION_ATTR esp8266_serial_audio_output() {
72  // Note: That unreadble mess is an optimized version of Serial1.availableForWrite()
73  while ((UART_TX_FIFO_SIZE - ((U1S >> USTXC) & 0xff)) > (PDM_RESOLUTION * 4)) {
74  defaultAudioOutput();
75  }
76 }
77 
78 inline void audioOutput(const AudioOutput f) {
79  // optimized version of: Serial1.write(...);
80  for (uint8_t i = 0; i < PDM_RESOLUTION*4; ++i) {
81  U1F = pdmCode8(f+AUDIO_BIAS);
82  }
83 }
84 # endif
85 #endif
86 
87 static void startAudio() {
88 #if (EXTERNAL_AUDIO_OUTPUT == true) && (BYPASS_MOZZI_OUTPUT_BUFFER != true) // for external audio output, set up a timer running a audio rate
89  timer1_isr_init();
90  timer1_attachInterrupt(defaultAudioOutput);
91  timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP);
92  timer1_write(F_CPU / AUDIO_RATE);
94  Serial1.begin(
95  AUDIO_RATE * (PDM_RESOLUTION * 40), SERIAL_8N1,
96  SERIAL_TX_ONLY); // Note: PDM_RESOLUTION corresponds to packets of 32
97  // encoded bits However, the UART (unfortunately) adds a
98  // start and stop bit each around each byte, thus sending
99  // a total to 40 bits per audio sample per
100  // PDM_RESOLUTION.
101  // set up a timer to copy from Mozzi output_buffer into Serial TX buffer
102  timer1_isr_init();
103  timer1_attachInterrupt(esp8266_serial_audio_output);
104  // UART FIFO buffer size is 128 bytes. To be on the safe side, we keep the
105  // interval to the time needed to write half of that. PDM_RESOLUTION * 4 bytes
106  // per sample written.
107  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
108  timer1_write(F_CPU / (AUDIO_RATE * PDM_RESOLUTION));
109 #else
110  i2s_begin();
111 # if (ESP_AUDIO_OUT_MODE == PDM_VIA_I2S)
112  pinMode(2, INPUT); // Set the two unneeded I2S pins to input mode, to reduce
113  // side effects
114  pinMode(15, INPUT);
115 # endif
116  i2s_set_rate(AUDIO_RATE * PDM_RESOLUTION);
117  if (output_buffer_size == 0)
118  output_buffer_size =
119  i2s_available(); // Do not reset count when stopping / restarting
120 #endif
121 }
122 
123 
124 void stopMozzi() {
126  i2s_end();
127 #else
128  timer1_disable();
129 #endif
130  interrupts();
131 }
132 
133 #if ((ESP_AUDIO_OUT_MODE == PDM_VIA_I2S) && (PDM_RESOLUTION != 1))
134 # define AUDIOTICK_ADJUSTMENT ((output_buffer_size - i2s_available()) / PDM_RESOLUTION)
135 #else
136 # define AUDIOTICK_ADJUSTMENT (output_buffer_size - i2s_available())
137 #endif
138 
139 //// END AUDIO OUTPUT code ///////
#define PDM_VIA_SERIAL
-
#define ESP_AUDIO_OUT_MODE
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
-
#define PDM_VIA_I2S
Definition: AudioConfigESP.h:9
-
#define PDM_RESOLUTION
-
#define AUDIO_BIAS
Definition: MozziGuts.h:229
-
#define EXTERNAL_DAC_VIA_I2S
+
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_ESP8266())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 namespace MozziPrivate {
18 
19 ////// BEGIN analog input code ////////
20 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
21 #error not yet implemented
22 
23 #define getADCReading() 0
24 #define channelNumToIndex(channel) channel
25 uint8_t adcPinToChannelNum(uint8_t pin) {
26  return pin;
27 }
28 void adcStartConversion(uint8_t channel) {
29 }
30 void startSecondADCReadOnCurrentChannel() {
31 }
32 void setupMozziADC(int8_t speed) {
33 }
34 void setupFastAnalogRead(int8_t speed) {
35 }
36 #endif
37 ////// END analog input code ////////
38 
39 //// BEGIN AUDIO OUTPUT code ///////
40 #define LOOP_YIELD yield();
41 
42 } // namespace MozziPrivate
43 #include <uart.h>
44 #include <I2S.h>
45 namespace MozziPrivate {
46 uint16_t output_buffer_size = 0;
47 
48 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC) // i.e. not external
49 
50 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
51 } // namespace MozziPrivate
52 # include <i2s.h>
53 namespace MozziPrivate {
54 inline bool canBufferAudioOutput() {
55  return (i2s_available() >= MOZZI_PDM_RESOLUTION);
56 }
57 inline void audioOutput(const AudioOutput f) {
58  for (uint8_t words = 0; words < MOZZI_PDM_RESOLUTION; ++words) {
59  i2s_write_sample(pdmCode32(f.l()+MOZZI_AUDIO_BIAS));
60  }
61 }
62 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
63 } // namespace MozziPrivate
64 # include <i2s.h>
65 namespace MozziPrivate {
66 inline bool canBufferAudioOutput() {
67  return (i2s_available() >= MOZZI_PDM_RESOLUTION);
68 }
69 inline void audioOutput(const AudioOutput f) {
70  i2s_write_lr(f.l(), f.r()); // Note: i2s_write expects zero-centered output
71 }
72 # else
73 MOZZI_ASSERT_EQUAL(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
74 // NOTE: This intermediate step is needed because the output timer is running at a rate higher than MOZZI_AUDIO_RATE, and we need to rely on the (tiny)
75 // serial buffer itself to achieve appropriate rate control
76 void CACHED_FUNCTION_ATTR esp8266_serial_audio_output() {
77  // Note: That unreadble mess is an optimized version of Serial1.availableForWrite()
78  while ((UART_TX_FIFO_SIZE - ((U1S >> USTXC) & 0xff)) > (MOZZI_PDM_RESOLUTION * 4)) {
79  defaultAudioOutput();
80  }
81 }
82 
83 inline void audioOutput(const AudioOutput f) {
84  // optimized version of: Serial1.write(...);
85  for (uint8_t i = 0; i < MOZZI_PDM_RESOLUTION*4; ++i) {
86  U1F = pdmCode8(f.l()+MOZZI_AUDIO_BIAS);
87  }
88 }
89 # endif
90 #endif
91 
92 static void startAudio() {
93 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // for external audio output, set up a timer running a audio rate
94  timer1_isr_init();
95  timer1_attachInterrupt(defaultAudioOutput);
96  timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP);
97  timer1_write(F_CPU / MOZZI_AUDIO_RATE);
98 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
99  Serial1.begin(
100  MOZZI_AUDIO_RATE * (MOZZI_PDM_RESOLUTION * 40), SERIAL_8N1,
101  SERIAL_TX_ONLY); // Note: PDM_RESOLUTION corresponds to packets of 32
102  // encoded bits However, the UART (unfortunately) adds a
103  // start and stop bit each around each byte, thus sending
104  // a total to 40 bits per audio sample per
105  // PDM_RESOLUTION.
106  // set up a timer to copy from Mozzi output_buffer into Serial TX buffer
107  timer1_isr_init();
108  timer1_attachInterrupt(esp8266_serial_audio_output);
109  // UART FIFO buffer size is 128 bytes. To be on the safe side, we keep the
110  // interval to the time needed to write half of that. PDM_RESOLUTION * 4 bytes
111  // per sample written.
112  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
113  timer1_write(F_CPU / (MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION));
114 #else
115  i2s_begin();
116 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
117  pinMode(2, INPUT); // Set the two unneeded I2S pins to input mode, to reduce
118  // side effects
119  pinMode(15, INPUT);
120 # endif
121  i2s_set_rate(MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION);
122  if (output_buffer_size == 0)
123  output_buffer_size =
124  i2s_available(); // Do not reset count when stopping / restarting
125 #endif
126 }
127 
128 
129 void stopMozzi() {
130 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC)
131  i2s_end();
132 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_EXTERNAL_TIMED)
133  timer1_disable();
134 #endif
135  interrupts();
136 }
137 
138 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) && (MOZZI_PDM_RESOLUTION != 1)
139 # define AUDIOTICK_ADJUSTMENT ((output_buffer_size - i2s_available()) / MOZZI_PDM_RESOLUTION)
140 #else
141 # define AUDIOTICK_ADJUSTMENT (output_buffer_size - i2s_available())
142 #endif
143 
144 //// END AUDIO OUTPUT code ///////
145 
146 //// BEGIN Random seeding ////////
147 } //namespace MozziPrivate
148 #include <esp8266_peri.h>
149 namespace MozziPrivate {
150 void MozziRandPrivate::autoSeed() {
151  x = RANDOM_REG32;
152  // TODO: The XORs may not be needed, but for lack of documentation (that I could find), let's assume RANDOM_REG32
153  // itself might not get updated on every read. NOTE: x, y, and z are initialized to non-zero, before this.
154  y = y ^ RANDOM_REG32;
155  z = z ^ RANDOM_REG32;
156 }
157 //// END Random seeding ////////
158 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 // The main point of this check is to document, what platform & variants this implementation file is for.
14 #if !(IS_RP2040())
15 # error "Wrong implementation included for this platform"
16 #endif
17 
18 
19 ////// BEGIN analog input code ////////
20 
21 #define MOZZI_FAST_ANALOG_IMPLEMENTED
22 
23 /** Implementation notes:
24  * - So nobody on the nets seems to have quite figured out, how to run the RP2040 ADC in "regular" asynchronous mode.
25  * - The ADC sports an interrupt, presumably to be triggered when a conversion is done, but how to connect a callback to that?
26  * - There is, however, an official example on a free running ADC writing to DMA (https://github.com/raspberrypi/pico-examples/blob/master/adc/dma_capture/dma_capture.c ; BSD licensed)
27  * We'll abuse that to connect a callback to the DMA channel, instead.
28 */
29 
30 #include <hardware/adc.h>
31 #include <hardware/dma.h>
32 
33 #define getADCReading() rp2040_adc_result
34 #define channelNumToIndex(channel) channel
35 
36 inline void adc_run_once () { // see rp2040 sdk code for adc_read() vs adc_run()
37  hw_set_bits(&adc_hw->cs, ADC_CS_START_ONCE_BITS); // vs ADC_CS_START_MANY_BITS
38 }
39 
40 uint8_t adcPinToChannelNum(uint8_t pin) {
41  if (pin >= 26) pin -= 26; // allow analog to be called by GP or ADC numbering
42  return pin;
43 
44 }
45 
46 void adcStartConversion(uint8_t channel) {
47  adc_select_input(channel);
48  adc_run_once();
49  // adc_run(true);
50 }
51 
52 void startSecondADCReadOnCurrentChannel() {
53  adc_run_once();
54  // adc_run(true);
55 }
56 
57 void setupFastAnalogRead(int8_t speed) {
58  if (speed == FAST_ADC) {
59  adc_set_clkdiv(2048); // Note: arbritray pick
60  } else if (speed == FASTER_ADC) {
61  adc_set_clkdiv(256); // Note: arbritray pick
62  } else {
63  adc_set_clkdiv(0); // max speed
64  }
65 }
66 
67 void rp2040_adc_queue_handler();
68 
69 static uint16_t rp2040_adc_result = 0;
70 int rp2040_adc_dma_chan;
71 void setupMozziADC(int8_t speed) {
72  for (int i = 0; i < NUM_ANALOG_INPUTS; ++i) {
73  adc_gpio_init(i);
74  }
75 
76  adc_init();
77  adc_fifo_setup(
78  true, // Write each completed conversion to the sample FIFO
79  true, // Enable DMA data request (DREQ)
80  1, // DREQ (and IRQ) asserted when at least 1 sample present
81  false, // Don't want ERR bit
82  false // Keep full sample range
83  );
84 
85  uint dma_chan = dma_claim_unused_channel(true);
86  rp2040_adc_dma_chan = dma_chan;
87  static dma_channel_config cfg = dma_channel_get_default_config(dma_chan);
88 
89  // Reading from constant address, writing to incrementing byte addresses
90  channel_config_set_transfer_data_size(&cfg, DMA_SIZE_16);
91  channel_config_set_read_increment(&cfg, false);
92  channel_config_set_write_increment(&cfg, false); // we don't really want a fifo, just keep reading to the same address
93 
94  // Pace transfers based on availability of ADC samples
95  channel_config_set_dreq(&cfg, DREQ_ADC);
96 
97  dma_channel_configure(dma_chan, &cfg,
98  &rp2040_adc_result, // dst
99  &adc_hw->fifo, // src
100  1, // transfer count
101  true // start immediately
102  );
103 
104  // we want notification, when a sample has arrived
105  dma_channel_set_irq0_enabled(dma_chan, true);
106  irq_add_shared_handler(DMA_IRQ_0, rp2040_adc_queue_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
107  irq_set_enabled(DMA_IRQ_0, true);
108  dma_channel_start(dma_chan);
109 }
110 
111 void rp2040_adc_queue_handler() {
112  if (!dma_channel_get_irq0_status(rp2040_adc_dma_chan)) return; // shared handler may get called on unrelated events
113  dma_channel_acknowledge_irq0(rp2040_adc_dma_chan); // clear interrupt flag
114  //adc_run(false); // adc not running continuous
115  //adc_fifo_drain(); // no need to drain fifo, the dma transfer did that
116  dma_channel_set_trans_count(rp2040_adc_dma_chan, 1, true); // set up for another read
117  advanceADCStep();
118 }
119 ////// END analog input code ////////
120 
121 
122 ////// BEGIN audio output code //////
123 #define LOOP_YIELD tight_loop_contents(); // apparently needed, among other things, to service the alarm pool
124 
125 
126 #if (RP2040_AUDIO_OUT_MODE == PWM_VIA_BARE_CHIP) || (EXTERNAL_AUDIO_OUTPUT == true)
127 #include <hardware/pwm.h>
128 #if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user
129 inline void audioOutput(const AudioOutput f) {
130  pwm_set_gpio_level(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS);
131 #if (AUDIO_CHANNELS > 1)
132  pwm_set_gpio_level(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS);
133 #endif
134 }
135 #endif // #if (EXTERNAL_AUDIO_OUTPUT != true)
136 
137 #include <pico/time.h>
138 /** Implementation notes:
139  * - For the time being this port uses a very crude approach to audio output: PWM updated by a hardware timer running at AUDIO_RATE
140  * - Hardware timer isn't fixed, but rather we claim the first unclaimed one
141  * - Quite pleasently, the RP2040 latches PWM duty cycle, so we do not have to worry about updating whilst in the middle of the previous PWM cycle.
142  * - The more simple add_repeating_timer_us has appers to have far too much jitter
143  * - Using DMA transfers, instead of a manual timer, would be much more elegant, but I'll leave that as an exercise to the reader ;-)
144  * - Not to mention PWM output, etc.
145  */
146 absolute_time_t next_audio_update;
147 uint64_t micros_per_update;
148 uint audio_update_alarm_num;
149 
150 void audioOutputCallback(uint) {
151  do {
152  defaultAudioOutput();
153  next_audio_update = delayed_by_us(next_audio_update, micros_per_update);
154  // NOTE: hardware_alarm_set_target returns true, if the target was already missed. In that case, keep pushing samples, until we have caught up.
155  } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update));
156 }
157 
158 #elif (RP2040_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S)
159 #include <I2S.h>
160 I2S i2s(OUTPUT);
161 
162 
163 inline bool canBufferAudioOutput() {
164  return (i2s.availableForWrite());
165 }
166 
167 inline void audioOutput(const AudioOutput f) {
168 
169 #if (AUDIO_BITS == 8)
170 #if (AUDIO_CHANNELS > 1)
171  i2s.write8(f.l(), f.r());
172 #else
173  i2s.write8(f.l(), 0);
174 #endif
175 
176 #elif (AUDIO_BITS == 16)
177 #if (AUDIO_CHANNELS > 1)
178  i2s.write16(f.l(), f.r());
179 #else
180  i2s.write16(f.l(), 0);
181 #endif
182 
183 #elif (AUDIO_BITS == 24)
184 #if (AUDIO_CHANNELS > 1)
185  i2s.write24(f.l(), f.r());
186 #else
187  i2s.write24(f.l(), 0);
188 #endif
189 
190 #elif (AUDIO_BITS == 32)
191 #if (AUDIO_CHANNELS > 1)
192  i2s.write32(f.l(), f.r());
193 #else
194  i2s.write32(f.l(), 0);
195 #endif
196 #else
197  #error The number of AUDIO_BITS set in AudioConfigRP2040.h is incorrect
198 #endif
199 
200 
201 }
202 #endif
203 
204 
205 static void startAudio() {
206 #if (RP2040_AUDIO_OUT_MODE == PWM_VIA_BARE_CHIP) || (EXTERNAL_AUDIO_OUTPUT == true) // EXTERNAL AUDIO needs the timers set here
207 #if (EXTERNAL_AUDIO_OUTPUT != true)
208  // calling analogWrite for the first time will try to init the pwm frequency and range on all pins. We don't want that happening after we've set up our own,
209  // so we start off with a dummy call to analogWrite:
210  analogWrite(AUDIO_CHANNEL_1_PIN, AUDIO_BIAS);
211  // Set up fast PWM on the output pins
212  // TODO: This is still very crude!
213  pwm_config c = pwm_get_default_config();
214  pwm_config_set_clkdiv(&c, 1); // Fastest we can get: PWM clock running at full CPU speed
215  pwm_config_set_wrap(&c, 1l << AUDIO_BITS); // 11 bits output resolution means FCPU / 2048 values per second, which is around 60kHz for 133Mhz clock speed.
216  pwm_init(pwm_gpio_to_slice_num(AUDIO_CHANNEL_1_PIN), &c, true);
217  gpio_set_function(AUDIO_CHANNEL_1_PIN, GPIO_FUNC_PWM);
218  gpio_set_drive_strength(AUDIO_CHANNEL_1_PIN, GPIO_DRIVE_STRENGTH_12MA); // highest we can get
219 # if (AUDIO_CHANNELS > 1)
220 # if ((AUDIO_CHANNEL_1_PIN / 2) != (AUDIO_CHANNEL_2_PIN / 2))
221 # error Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. Adjust AudioConfigRP2040.h .
222 # endif
223  gpio_set_function(AUDIO_CHANNEL_2_PIN, GPIO_FUNC_PWM);
224  gpio_set_drive_strength(AUDIO_CHANNEL_2_PIN, GPIO_DRIVE_STRENGTH_12MA); // highest we can get
225 # endif
226 #endif
227 
228  for (audio_update_alarm_num = 0; audio_update_alarm_num < 4; ++audio_update_alarm_num) {
229  if (!hardware_alarm_is_claimed(audio_update_alarm_num)) {
230  hardware_alarm_claim(audio_update_alarm_num);
231  hardware_alarm_set_callback(audio_update_alarm_num, audioOutputCallback);
232  break;
233  }
234  }
235  micros_per_update = 1000000l / AUDIO_RATE;
236  do {
237  next_audio_update = make_timeout_time_us(micros_per_update);
238  // See audioOutputCallback(), above. In _theory_ some interrupt stuff might delay us, here, causing us to miss the first beat (and everything that follows)
239  } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update));
240 
241 #elif (RP2040_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S)
242  i2s.setBCLK(BCLK_PIN);
243  i2s.setDATA(DOUT_PIN);
244  i2s.setBitsPerSample(AUDIO_BITS);
245 
246 #if (AUDIO_BITS > 16)
247  i2s.setBuffers(BUFFERS, (size_t) (BUFFER_SIZE/BUFFERS), 0);
248 #else
249  i2s.setBuffers(BUFFERS, (size_t) (BUFFER_SIZE/BUFFERS/2), 0);
250 #endif
251 #if (LSBJ_FORMAT == true)
252  i2s.setLSBJFormat();
253 #endif
254  i2s.begin(AUDIO_RATE);
255 #endif
256 }
257 
258 void stopMozzi() {
259 #if (RP2040_AUDIO_OUT_MODE == PWM_VIA_BARE_CHIP) || (EXTERNAL_AUDIO_OUTPUT == true)
260  hardware_alarm_set_callback(audio_update_alarm_num, NULL);
261 #elif (RP2040_AUDIO_OUT_MODE == EXTERNAL_DAC_VIA_I2S)
262  i2s.end();
263 #endif
264 
265 }
266 ////// END audio output code //////
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
+
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 // The main point of this check is to document, what platform & variants this implementation file is for.
14 #if !(IS_RP2040())
15 # error "Wrong implementation included for this platform"
16 #endif
17 
18 #include <hardware/dma.h>
19 
20 namespace MozziPrivate {
21 
22 ////// BEGIN analog input code ////////
23 
24 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
25 
26 /** Implementation notes:
27  * - So nobody on the nets seems to have quite figured out, how to run the RP2040 ADC in "regular" asynchronous mode.
28  * - The ADC sports an interrupt, presumably to be triggered when a conversion is done, but how to connect a callback to that?
29  * - There is, however, an official example on a free running ADC writing to DMA (https://github.com/raspberrypi/pico-examples/blob/master/adc/dma_capture/dma_capture.c ; BSD licensed)
30  * We'll abuse that to connect a callback to the DMA channel, instead.
31 */
32 
33 } // namespace MozziPrivate
34 
35 #include <hardware/adc.h>
36 
37 namespace MozziPrivate {
38 
39 #define getADCReading() rp2040_adc_result
40 #define channelNumToIndex(channel) channel
41 
42 inline void adc_run_once () { // see rp2040 sdk code for adc_read() vs adc_run()
43  hw_set_bits(&adc_hw->cs, ADC_CS_START_ONCE_BITS); // vs ADC_CS_START_MANY_BITS
44 }
45 
46 uint8_t adcPinToChannelNum(uint8_t pin) {
47  if (pin >= 26) pin -= 26; // allow analog to be called by GP or ADC numbering
48  return pin;
49 
50 }
51 
52 void adcStartConversion(uint8_t channel) {
53  adc_select_input(channel);
54  adc_run_once();
55  // adc_run(true);
56 }
57 
58 void startSecondADCReadOnCurrentChannel() {
59  adc_run_once();
60  // adc_run(true);
61 }
62 
63 void setupFastAnalogRead(int8_t speed) {
64  if (speed == FAST_ADC) {
65  adc_set_clkdiv(2048); // Note: arbritray pick
66  } else if (speed == FASTER_ADC) {
67  adc_set_clkdiv(256); // Note: arbritray pick
68  } else {
69  adc_set_clkdiv(0); // max speed
70  }
71 }
72 
73 void rp2040_adc_queue_handler();
74 
75 static uint16_t rp2040_adc_result = 0;
76 int rp2040_adc_dma_chan;
77 void setupMozziADC(int8_t speed) {
78  for (int i = 0; i < (int) NUM_ANALOG_INPUTS; ++i) {
79  adc_gpio_init(i);
80  }
81 
82  adc_init();
83  adc_fifo_setup(
84  true, // Write each completed conversion to the sample FIFO
85  true, // Enable DMA data request (DREQ)
86  1, // DREQ (and IRQ) asserted when at least 1 sample present
87  false, // Don't want ERR bit
88  false // Keep full sample range
89  );
90 
91  uint dma_chan = dma_claim_unused_channel(true);
92  rp2040_adc_dma_chan = dma_chan;
93  static dma_channel_config cfg = dma_channel_get_default_config(dma_chan);
94 
95  // Reading from constant address, writing to incrementing byte addresses
96  channel_config_set_transfer_data_size(&cfg, DMA_SIZE_16);
97  channel_config_set_read_increment(&cfg, false);
98  channel_config_set_write_increment(&cfg, false); // we don't really want a fifo, just keep reading to the same address
99 
100  // Pace transfers based on availability of ADC samples
101  channel_config_set_dreq(&cfg, DREQ_ADC);
102 
103  dma_channel_configure(dma_chan, &cfg,
104  &rp2040_adc_result, // dst
105  &adc_hw->fifo, // src
106  1, // transfer count
107  true // start immediately
108  );
109 
110  // we want notification, when a sample has arrived
111  dma_channel_set_irq0_enabled(dma_chan, true);
112  irq_add_shared_handler(DMA_IRQ_0, rp2040_adc_queue_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
113  irq_set_enabled(DMA_IRQ_0, true);
114  dma_channel_start(dma_chan);
115 }
116 
117 void rp2040_adc_queue_handler() {
118  if (!dma_channel_get_irq0_status(rp2040_adc_dma_chan)) return; // shared handler may get called on unrelated events
119  dma_channel_acknowledge_irq0(rp2040_adc_dma_chan); // clear interrupt flag
120  //adc_run(false); // adc not running continuous
121  //adc_fifo_drain(); // no need to drain fifo, the dma transfer did that
122  dma_channel_set_trans_count(rp2040_adc_dma_chan, 1, true); // set up for another read
123  advanceADCStep();
124 }
125 
126 #endif // MOZZI_ANALOG_READ
127 
128 ////// END analog input code ////////
129 
130 
131 ////// BEGIN audio output code //////
132 #define LOOP_YIELD tight_loop_contents(); // apparently needed, among other things, to service the alarm pool
133 
134 
135 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
136 #include <hardware/pwm.h>
137 
138 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
139 inline void audioOutput(const AudioOutput f) {
140  pwm_set_gpio_level(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
141 # if (MOZZI_AUDIO_CHANNELS > 1)
142  pwm_set_gpio_level(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS);
143 # endif
144 }
145 # endif // MOZZI_OUTPUT_PWM
146 
147 } // namespace MozziPrivate
148 #include <pico/time.h>
149 namespace MozziPrivate {
150 /** Implementation notes:
151  * - For the time being this port uses a very crude approach to audio output: PWM updated by a hardware timer running at MOZZI_AUDIO_RATE
152  * - Hardware timer isn't fixed, but rather we claim the first unclaimed one
153  * - Quite pleasently, the RP2040 latches PWM duty cycle, so we do not have to worry about updating whilst in the middle of the previous PWM cycle.
154  * - The more simple add_repeating_timer_us has appers to have far too much jitter
155  * - Using DMA transfers, instead of a manual timer, would be much more elegant, but I'll leave that as an exercise to the reader ;-)
156  * - Not to mention PWM output, etc.
157  */
158 absolute_time_t next_audio_update;
159 uint64_t micros_per_update;
160 uint audio_update_alarm_num;
161 
162 void audioOutputCallback(uint) {
163  do {
164  defaultAudioOutput();
165  next_audio_update = delayed_by_us(next_audio_update, micros_per_update);
166  // NOTE: hardware_alarm_set_target returns true, if the target was already missed. In that case, keep pushing samples, until we have caught up.
167  } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update));
168 }
169 
170 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
171 } // namespace MozziPrivate
172 #include <I2S.h>
173 namespace MozziPrivate {
174 I2S i2s(OUTPUT);
175 
176 inline bool canBufferAudioOutput() {
177  return (i2s.availableForWrite());
178 }
179 
180 inline void audioOutput(const AudioOutput f) {
181 
182 # if (MOZZI_AUDIO_BITS == 8)
183 # if (MOZZI_AUDIO_CHANNELS > 1)
184  i2s.write8(f.l(), f.r());
185 # else
186  i2s.write8(f.l(), 0);
187 # endif
188 
189 # elif (MOZZI_AUDIO_BITS == 16)
190 # if (MOZZI_AUDIO_CHANNELS > 1)
191  i2s.write16(f.l(), f.r());
192 # else
193  i2s.write16(f.l(), 0);
194 # endif
195 
196 # elif (MOZZI_AUDIO_BITS == 24)
197 # if (MOZZI_AUDIO_CHANNELS > 1)
198  i2s.write24(f.l(), f.r());
199 # else
200  i2s.write24(f.l(), 0);
201 # endif
202 
203 # elif (MOZZI_AUDIO_BITS == 32)
204 # if (MOZZI_AUDIO_CHANNELS > 1)
205  i2s.write32(f.l(), f.r());
206 # else
207  i2s.write32(f.l(), 0);
208 # endif
209 # else
210 # error Invalid number of MOZZI_AUDIO_BITS configured
211 # endif
212 
213 }
214 #endif
215 
216 
217 static void startAudio() {
218 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
219  // calling analogWrite for the first time will try to init the pwm frequency and range on all pins. We don't want that happening after we've set up our own,
220  // so we start off with a dummy call to analogWrite:
221  analogWrite(MOZZI_AUDIO_PIN_1, MOZZI_AUDIO_BIAS);
222  // Set up fast PWM on the output pins
223  // TODO: This is still very crude!
224  pwm_config c = pwm_get_default_config();
225  pwm_config_set_clkdiv(&c, 1); // Fastest we can get: PWM clock running at full CPU speed
226  pwm_config_set_wrap(&c, 1l << MOZZI_AUDIO_BITS); // 11 bits output resolution means FCPU / 2048 values per second, which is around 60kHz for 133Mhz clock speed.
227  pwm_init(pwm_gpio_to_slice_num(MOZZI_AUDIO_PIN_1), &c, true);
228  gpio_set_function(MOZZI_AUDIO_PIN_1, GPIO_FUNC_PWM);
229  gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get
230 # if (MOZZI_AUDIO_CHANNELS > 1)
231 # if ((MOZZI_AUDIO_PIN_1 / 2) != (MOZZI_AUDIO_PIN_1 / 2))
232 # error Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. Adjust MOZZI_AUDIO_PIN_1/2 .
233 # endif
234  gpio_set_function(MOZZI_AUDIO_PIN_2, GPIO_FUNC_PWM);
235  gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get
236 # endif
237 #endif
238 
239 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
240  for (audio_update_alarm_num = 0; audio_update_alarm_num < 4; ++audio_update_alarm_num) {
241  if (!hardware_alarm_is_claimed(audio_update_alarm_num)) {
242  hardware_alarm_claim(audio_update_alarm_num);
243  hardware_alarm_set_callback(audio_update_alarm_num, audioOutputCallback);
244  break;
245  }
246  }
247  micros_per_update = 1000000l / MOZZI_AUDIO_RATE;
248  do {
249  next_audio_update = make_timeout_time_us(micros_per_update);
250  // See audioOutputCallback(), above. In _theory_ some interrupt stuff might delay us, here, causing us to miss the first beat (and everything that follows)
251  } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update));
252 
253 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
254  i2s.setBCLK(MOZZI_I2S_PIN_BCK);
255  i2s.setDATA(MOZZI_I2S_PIN_DATA);
256  i2s.setBitsPerSample(MOZZI_AUDIO_BITS);
257 
258 # if (MOZZI_AUDIO_BITS > 16)
259  i2s.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS), 0);
260 # else
261  i2s.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS/2), 0);
262 # endif
263 # if MOZZI_IS(MOZZI_I2S_FORMAT, MOZZI_I2S_FORMAT_LSBJ)
264  i2s.setLSBJFormat();
265 # endif
266  i2s.begin(MOZZI_AUDIO_RATE);
267 #endif
268 }
269 
270 void stopMozzi() {
271 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
272  hardware_alarm_set_callback(audio_update_alarm_num, NULL);
273 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
274  i2s.end();
275 #endif
276 
277 }
278 ////// END audio output code //////
279 
280 //// BEGIN Random seeding ////////
281 void MozziRandPrivate::autoSeed() {
282 #warning Automatic random seeding is not implemented on this platform
283 }
284 //// END Random seeding ////////
285 
286 } // namespace MozziPrivate
287 
288 #undef MOZZI_RP2040_BUFFERS
289 #undef MOZZI_RP2040_BUFFER_SIZE
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_SAMD21())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 ////// BEGIN analog input code ////////
18 //#define MOZZI_FAST_ANALOG_IMPLEMENTED // not yet
19 #define getADCReading() 0
20 #define channelNumToIndex(channel) channel
21 uint8_t adcPinToChannelNum(uint8_t pin) {
22  return pin;
23 }
24 void adcStartConversion(uint8_t channel) {
25 #warning Fast analog read not implemented on this platform
26 }
27 void startSecondADCReadOnCurrentChannel() {
28 #warning Fast analog read not implemented on this platform
29 }
30 void setupFastAnalogRead(int8_t speed) {
31 #warning Fast analog read not implemented on this platform
32 }
33 void setupMozziADC(int8_t speed) {
34 #warning Fast analog read not implemented on this platform
35 }
36 ////// END analog input code ////////
37 
38 
39 
40 //// BEGIN AUDIO OUTPUT code ///////
41 // These are ARM SAMD21 Timer 5 routines to establish a sample rate interrupt
42 static bool tcIsSyncing() {
43  return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;
44 }
45 
46 static void tcReset() {
47  // Reset TCx
48  TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
49  while (tcIsSyncing())
50  ;
51  while (TC5->COUNT16.CTRLA.bit.SWRST)
52  ;
53 }
54 /* Not currently used, and does not compile with EXTERNAL_AUDIO_OUTPUT
55 static void tcEnd() {
56  // Disable TC5
57  TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
58  while (tcIsSyncing())
59  ;
60  tcReset();
61  analogWrite(AUDIO_CHANNEL_1_PIN, 0);
62 } */
63 
64 static void tcConfigure(uint32_t sampleRate) {
65  // Enable GCLK for TCC2 and TC5 (timer counter input clock)
66  GCLK->CLKCTRL.reg = (uint16_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 |
67  GCLK_CLKCTRL_ID(GCM_TC4_TC5));
68  while (GCLK->STATUS.bit.SYNCBUSY)
69  ;
70 
71  tcReset();
72 
73  // Set Timer counter Mode to 16 bits
74  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
75 
76  // Set TC5 mode as match frequency
77  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
78 
79  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
80 
81  TC5->COUNT16.CC[0].reg = (uint16_t)(SystemCoreClock / sampleRate - 1);
82  while (tcIsSyncing())
83  ;
84 
85  // Configure interrupt request
86  NVIC_DisableIRQ(TC5_IRQn);
87  NVIC_ClearPendingIRQ(TC5_IRQn);
88  NVIC_SetPriority(TC5_IRQn, 0);
89  NVIC_EnableIRQ(TC5_IRQn);
90 
91  // Enable the TC5 interrupt request
92  TC5->COUNT16.INTENSET.bit.MC0 = 1;
93  while (tcIsSyncing())
94  ;
95 }
96 
97 void TC5_Handler(void) __attribute__((weak, alias("samd21AudioOutput")));
98 
99 #ifdef __cplusplus
100 extern "C" {
101 #endif
102 void samd21AudioOutput() {
103  defaultAudioOutput();
104  TC5->COUNT16.INTFLAG.bit.MC0 = 1;
105 }
106 #ifdef __cplusplus
107 }
108 #endif
109 
110 #if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user
111 #include "AudioConfigSAMD21.h"
112 inline void audioOutput(const AudioOutput f) {
113  analogWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS);
114 }
115 #endif
116 
117 static void startAudio() {
118 #ifdef ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS
119  {
120  static const int CPLAY_SPEAKER_SHUTDOWN = 11;
121  pinMode(CPLAY_SPEAKER_SHUTDOWN, OUTPUT);
122  digitalWrite(CPLAY_SPEAKER_SHUTDOWN, HIGH);
123  }
124 
125 #endif
126  analogWriteResolution(10);
127 #if (EXTERNAL_AUDIO_OUTPUT != true)
128  analogWrite(AUDIO_CHANNEL_1_PIN, 0);
129 #endif
130 
131  tcConfigure(AUDIO_RATE);
132 }
133 
134 void stopMozzi() {
135  // TODO: implement me
136  interrupts();
137 }
138 //// END AUDIO OUTPUT code ///////
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
#define AUDIO_CHANNEL_1_PIN
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
-
#define AUDIO_BIAS
Definition: MozziGuts.h:229
+
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_SAMD21())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 namespace MozziPrivate {
18 
19 ////// BEGIN analog input code ////////
20 #if MOZZI_IS(MOZZI_ANALOG_READ, NOZZI_ANALOG_READ_STANDARD)
21 #error not yet implemented
22 #define getADCReading() 0
23 #define channelNumToIndex(channel) channel
24 uint8_t adcPinToChannelNum(uint8_t pin) {
25  return pin;
26 }
27 void adcStartConversion(uint8_t channel) {
28 }
29 void startSecondADCReadOnCurrentChannel() {
30 }
31 void setupFastAnalogRead(int8_t speed) {
32 }
33 void setupMozziADC(int8_t speed) {
34 }
35 #endif
36 ////// END analog input code ////////
37 
38 
39 
40 //// BEGIN AUDIO OUTPUT code ///////
41 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
42 // These are ARM SAMD21 Timer 5 routines to establish a sample rate interrupt
43 static bool tcIsSyncing() {
44  return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;
45 }
46 
47 static void tcReset() {
48  // Reset TCx
49  TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
50  while (tcIsSyncing())
51  ;
52  while (TC5->COUNT16.CTRLA.bit.SWRST)
53  ;
54 }
55 /* Not currently used, and does not compile with EXTERNAL_AUDIO_OUTPUT
56 static void tcEnd() {
57  // Disable TC5
58  TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
59  while (tcIsSyncing())
60  ;
61  tcReset();
62  analogWrite(AUDIO_CHANNEL_1_PIN, 0);
63 } */
64 
65 static void tcConfigure(uint32_t sampleRate) {
66  // Enable GCLK for TCC2 and TC5 (timer counter input clock)
67  GCLK->CLKCTRL.reg = (uint16_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 |
68  GCLK_CLKCTRL_ID(GCM_TC4_TC5));
69  while (GCLK->STATUS.bit.SYNCBUSY)
70  ;
71 
72  tcReset();
73 
74  // Set Timer counter Mode to 16 bits
75  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
76 
77  // Set TC5 mode as match frequency
78  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
79 
80  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
81 
82  TC5->COUNT16.CC[0].reg = (uint16_t)(SystemCoreClock / sampleRate - 1);
83  while (tcIsSyncing())
84  ;
85 
86  // Configure interrupt request
87  NVIC_DisableIRQ(TC5_IRQn);
88  NVIC_ClearPendingIRQ(TC5_IRQn);
89  NVIC_SetPriority(TC5_IRQn, 0);
90  NVIC_EnableIRQ(TC5_IRQn);
91 
92  // Enable the TC5 interrupt request
93  TC5->COUNT16.INTENSET.bit.MC0 = 1;
94  while (tcIsSyncing())
95  ;
96 }
97 
98 } // namespace MozziPrivate
99 
100 void TC5_Handler(void) __attribute__((weak, alias("samd21AudioOutput")));
101 
102 #ifdef __cplusplus
103 extern "C" {
104 #endif
105 void samd21AudioOutput() {
106  MozziPrivate::defaultAudioOutput();
107  TC5->COUNT16.INTFLAG.bit.MC0 = 1;
108 }
109 #ifdef __cplusplus
110 }
111 #endif
112 
113 namespace MozziPrivate {
114 
115 #endif // MOZZI_AUDIO_MODE
116 
117 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
118 inline void audioOutput(const AudioOutput f) {
119  analogWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
120 }
121 #endif
122 
123 static void startAudio() {
124 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
125 # ifdef ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS
126  {
127  static const int CPLAY_SPEAKER_SHUTDOWN = 11;
128  pinMode(CPLAY_SPEAKER_SHUTDOWN, OUTPUT);
129  digitalWrite(CPLAY_SPEAKER_SHUTDOWN, HIGH);
130  }
131 
132 # endif
133 
134  analogWriteResolution(MOZZI_AUDIO_BITS);
135  analogWrite(MOZZI_AUDIO_PIN_1, 0);
136 #endif
137 
138 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
139  tcConfigure(MOZZI_AUDIO_RATE);
140 #endif
141 }
142 
143 void stopMozzi() {
144  // TODO: implement me
145  interrupts();
146 }
147 //// END AUDIO OUTPUT code ///////
148 
149 //// BEGIN Random seeding ////////
150 void MozziRandPrivate::autoSeed() {
151 #warning Automatic random seeding is not implemented on this platform
152 }
153 //// END Random seeding ////////
154 
155 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #include "HardwareTimer.h"
14 
15 ////// BEGIN analog input code ////////
16 #define MOZZI_FAST_ANALOG_IMPLEMENTED
17 //#include <STM32ADC.h> // Disabled, here. See AudioConfigSTM32.h
18 STM32ADC adc(ADC1);
19 uint8_t stm32_current_adc_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform
20 #define getADCReading() adc.getData()
21 #define channelNumToIndex(channel) STM32PinMap(channel)
22 uint8_t adcPinToChannelNum(uint8_t pin) {
23  return pin;
24 }
25 
26 void adcStartConversion(uint8_t channel) {
27  stm32_current_adc_pin = channel;
28  adc.setPins(&stm32_current_adc_pin, 1);
29  adc.startConversion();
30 }
31 
32 static void startSecondADCReadOnCurrentChannel() {
33  adc.setPins(&stm32_current_adc_pin, 1);
34  adc.startConversion();
35 }
36 
37 void stm32_adc_eoc_handler() {
38  advanceADCStep();
39 }
40 
41 void setupFastAnalogRead(int8_t speed) {
42  // NOTE: These picks are pretty arbitrary. Further available options are 7_5, 28_5, 55_5, 71_5 and 239_5 (i.e. 7.5 ADC cylces, etc.)
43  if (speed == FASTEST_ADC) adc.setSampleRate(ADC_SMPR_1_5);
44  else if (speed == FASTER_ADC) adc.setSampleRate(ADC_SMPR_13_5);
45  else (adc.setSampleRate(ADC_SMPR_41_5));
46 }
47 
48 void setupMozziADC(int8_t speed) {
49  adc.attachInterrupt(stm32_adc_eoc_handler);
50 }
51 
52 
53 inline uint8_t STM32PinMap(uint8_t pin)
54 {
55  if (pin > 15) return pin-8;
56  else return pin;
57 }
58 
59 ////// END analog input code ////////
60 
61 
62 
63 //// BEGIN AUDIO OUTPUT code ///////
64 #if (EXTERNAL_AUDIO_OUTPUT == true)
65 HardwareTimer audio_update_timer(2);
66 #else
67 HardwareTimer audio_update_timer(AUDIO_UPDATE_TIMER);
68 HardwareTimer audio_pwm_timer(AUDIO_PWM_TIMER);
69 
70 #include "AudioConfigSTM32.h"
71 inline void audioOutput(const AudioOutput f) {
72 # if (AUDIO_MODE == HIFI)
73  pwmWrite(AUDIO_CHANNEL_1_PIN, (f.l()+AUDIO_BIAS) & ((1 << AUDIO_BITS_PER_CHANNEL) - 1));
75 # else
76  pwmWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS);
77 # if (AUDIO_CHANNELS > 1)
78  pwmWrite(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS);
79 # endif
80 #endif
81 }
82 #endif
83 
84 static void startAudio() {
85  audio_update_timer.pause();
86  //audio_update_timer.setPeriod(1000000UL / AUDIO_RATE);
87  // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors
88  uint32_t period_cyc = F_CPU / AUDIO_RATE;
89  uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1);
90  uint16_t overflow = (uint16_t)((period_cyc + (prescaler / 2)) / prescaler);
91  audio_update_timer.setPrescaleFactor(prescaler);
92  audio_update_timer.setOverflow(overflow);
93  audio_update_timer.setChannel1Mode(TIMER_OUTPUT_COMPARE);
94  audio_update_timer.setCompare(TIMER_CH1,
95  1); // Interrupt 1 count after each update
96  audio_update_timer.attachCompare1Interrupt(defaultAudioOutput);
97  audio_update_timer.refresh();
98  audio_update_timer.resume();
99 
100 #if (EXTERNAL_AUDIO_OUTPUT != true)
101  pinMode(AUDIO_CHANNEL_1_PIN, PWM);
102 # if (AUDIO_MODE == HIFI)
103  pinMode(AUDIO_CHANNEL_1_PIN_HIGH, PWM);
104 # elif (AUDIO_CHANNELS > 1)
105  pinMode(AUDIO_CHANNEL_2_PIN, PWM);
106 # endif
107 
108 # define MAX_CARRIER_FREQ (F_CPU / (1 << AUDIO_BITS_PER_CHANNEL))
109 # if MAX_CARRIER_FREQ < AUDIO_RATE
110 # error Configured audio resolution is definitely too high at the configured audio rate (and the given CPU speed)
111 # elif MAX_CARRIER_FREQ < (AUDIO_RATE * 3)
112 # warning Configured audio resolution may be higher than optimal at the configured audio rate (and the given CPU speed)
113 # endif
114 
115 # if MAX_CARRIER_FREQ < (AUDIO_RATE * 5)
116  // Generate as fast a carrier as possible
117  audio_pwm_timer.setPrescaleFactor(1);
118 # else
119  // No point in generating arbitrarily high carrier frequencies. In fact, if
120  // there _is_ any headroom, give the PWM pin more time to swing from HIGH to
121  // LOW and BACK, cleanly
122  audio_pwm_timer.setPrescaleFactor((int)MAX_CARRIER_FREQ / (AUDIO_RATE * 5));
123 # endif
124  audio_pwm_timer.setOverflow(
125  1 << AUDIO_BITS_PER_CHANNEL); // Allocate enough room to write all
126  // intended bits
127 #endif
128 }
129 
130 void stopMozzi() {
131  audio_update_timer.pause();
132 }
133 
134 //// END AUDIO OUTPUT code ///////
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
#define AUDIO_BITS_PER_CHANNEL
-
#define AUDIO_CHANNEL_1_PIN
-
#define AUDIO_CHANNEL_1_PIN_HIGH
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
-
#define AUDIO_BIAS
Definition: MozziGuts.h:229
+
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #include "HardwareTimer.h"
14 
15 namespace MozziPrivate {
16 
17 ////// BEGIN analog input code ////////
18 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
19 
20 } // namespace MozziPrivate
21 //#include <STM32ADC.h> // Disabled, here. See hardware_defines.h
22 namespace MozziPrivate {
23 
24 STM32ADC adc(ADC1);
25 uint8_t stm32_current_adc_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform
26 #define getADCReading() adc.getData()
27 #define channelNumToIndex(channel) STM32PinMap(channel)
28 uint8_t adcPinToChannelNum(uint8_t pin) {
29  return pin;
30 }
31 
32 void adcStartConversion(uint8_t channel) {
33  stm32_current_adc_pin = channel;
34  adc.setPins(&stm32_current_adc_pin, 1);
35  adc.startConversion();
36 }
37 
38 static void startSecondADCReadOnCurrentChannel() {
39  adc.setPins(&stm32_current_adc_pin, 1);
40  adc.startConversion();
41 }
42 
43 void stm32_adc_eoc_handler() {
44  advanceADCStep();
45 }
46 
47 void setupMozziADC(int8_t speed) {
48  adc.attachInterrupt(stm32_adc_eoc_handler);
49 }
50 
51 
52 inline uint8_t STM32PinMap(uint8_t pin)
53 {
54  if (pin > 15) return pin-8;
55  else return pin;
56 }
57 
58 void setupFastAnalogRead(int8_t speed) {
59  // NOTE: These picks are pretty arbitrary. Further available options are 7_5, 28_5, 55_5, 71_5 and 239_5 (i.e. 7.5 ADC cylces, etc.)
60  if (speed == FASTEST_ADC) adc.setSampleRate(ADC_SMPR_1_5);
61  else if (speed == FASTER_ADC) adc.setSampleRate(ADC_SMPR_13_5);
62  else (adc.setSampleRate(ADC_SMPR_41_5));
63 }
64 #endif
65 
66 ////// END analog input code ////////
67 
68 
69 
70 //// BEGIN AUDIO OUTPUT code ///////
71 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
72 HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER);
73 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
74 HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER);
75 HardwareTimer audio_pwm_timer(MOZZI_AUDIO_PWM_TIMER);
76 
77 inline void audioOutput(const AudioOutput f) {
78 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
79  pwmWrite(MOZZI_AUDIO_PIN_1, (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_CHANNEL);
80  pwmWrite(MOZZI_AUDIO_PIN_1_LOW, (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1));
81 # else
82  pwmWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
83 # if (MOZZI_AUDIO_CHANNELS > 1)
84  pwmWrite(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS);
85 # endif
86 #endif
87 }
88 #endif
89 
90 static void startAudio() {
91 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
92  audio_update_timer.pause();
93  //audio_update_timer.setPeriod(1000000UL / MOZZI_AUDIO_RATE);
94  // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors
95  uint32_t period_cyc = F_CPU / MOZZI_AUDIO_RATE;
96  uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1);
97  uint16_t overflow = (uint16_t)((period_cyc + (prescaler / 2)) / prescaler);
98  audio_update_timer.setPrescaleFactor(prescaler);
99  audio_update_timer.setOverflow(overflow);
100  audio_update_timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
101  audio_update_timer.setCompare(TIMER_CH1,
102  1); // Interrupt 1 count after each update
103  audio_update_timer.attachInterrupt(TIMER_CH1, defaultAudioOutput);
104  audio_update_timer.refresh();
105  audio_update_timer.resume();
106 #endif
107 
108 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
109  pinMode(MOZZI_AUDIO_PIN_1, PWM);
110 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
111  pinMode(MOZZI_AUDIO_PIN_1_LOW, PWM);
112 # elif (MOZZI_AUDIO_CHANNELS > 1)
113  pinMode(MOZZI_AUDIO_PIN_2, PWM);
114 # endif
115 
116 # define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL))
117 # if MAX_CARRIER_FREQ < MOZZI_AUDIO_RATE
118 # error Configured audio resolution is definitely too high at the configured audio rate (and the given CPU speed)
119 # elif MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 3)
120 # warning Configured audio resolution may be higher than optimal at the configured audio rate (and the given CPU speed)
121 # endif
122 
123 # if MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 5)
124  // Generate as fast a carrier as possible
125  audio_pwm_timer.setPrescaleFactor(1);
126 # else
127  // No point in generating arbitrarily high carrier frequencies. In fact, if
128  // there _is_ any headroom, give the PWM pin more time to swing from HIGH to
129  // LOW and BACK, cleanly
130  audio_pwm_timer.setPrescaleFactor((int)MAX_CARRIER_FREQ / (MOZZI_AUDIO_RATE * 5));
131 # endif
132  audio_pwm_timer.setOverflow(
133  1 << MOZZI_AUDIO_BITS_PER_CHANNEL); // Allocate enough room to write all
134  // intended bits
135 # undef MAX_CARRIER_FREQ // no longer needed
136 #endif
137 }
138 
139 void stopMozzi() {
140 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
141  audio_update_timer.pause();
142 #endif
143 }
144 
145 //// END AUDIO OUTPUT code ///////
146 
147 //// BEGIN Random seeding ////////
148 void MozziRandPrivate::autoSeed() {
149  // Unfortunately the internal temp sensor on STM32s does _not_ appear to create a lot of noise.
150  // Ironically, the calls to calibrate help induce some random noise. You're still fairly likely to produce two equal
151  // random seeds in two subsequent runs, however.
152  adc.enableInternalReading();
153  union {
154  float cf;
155  uint32_t ci;
156  } conv;
157  conv.cf = adc.readTemp();
158  x=x^conv.ci;
159  adc.calibrate();
160  conv.cf = adc.readTemp();
161  y=y^conv.ci;
162  adc.calibrate();
163  conv.cf = adc.readTemp();
164  z=z^conv.ci;
165 }
166 //// END Random seeding ////////
167 
168 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_TEENSY3() || IS_TEENSY4())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 // required from http://github.com/pedvide/ADC for Teensy 3.*
18 #include "IntervalTimer.h"
19 #include <ADC.h>
20 #include "teensyPinMap.h"
21 
22 #if (IS_TEENSY3() && F_CPU != 48000000)
23 #warning
24  "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino and 48MHz on Teensy 3! Results may vary with other speeds."
25 #endif
26 
27 ////// BEGIN analog input code ////////
28 #define MOZZI_FAST_ANALOG_IMPLEMENTED
29 ADC *adc; // adc object
30 uint8_t teensy_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform
31 int8_t teensy_adc=0;
32 #define getADCReading() adc->readSingle(teensy_adc)
33 #define channelNumToIndex(channel) teensyPinMap(channel)
34 uint8_t adcPinToChannelNum(uint8_t pin) {
35  return pin;
36 }
37 
38 void setupFastAnalogRead(int8_t speed) {
39  adc->adc0->setAveraging(0);
40  adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED); // could be HIGH_SPEED, noisier
41 #ifdef ADC_DUAL_ADCS
42  adc->adc1->setAveraging(0);
43  adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED);
44 #endif
45 }
46 
47 void adc0_isr(void)
48 {
49  advanceADCStep();
50 }
51 
52 void setupMozziADC(int8_t speed) {
53  adc = new ADC();
54  adc->adc0->enableInterrupts(adc0_isr);
55 #ifdef ADC_DUAL_ADCS
56  adc->adc1->enableInterrupts(adc0_isr);
57 #endif
58 }
59 
60 void adcStartConversion(uint8_t channel) {
61  teensy_pin = channel; // remember for startSecondADCReadOnCurrentChannel()
62 #ifdef ADC_DUAL_ADCS
63  if (adc->adc0->checkPin(teensy_pin)) teensy_adc = 0;
64  else teensy_adc=1;
65 #endif
66  adc->startSingleRead(teensy_pin,teensy_adc);
67 }
68 
69 static void startSecondADCReadOnCurrentChannel() {
70  adc->startSingleRead(teensy_pin,teensy_adc);
71 }
72 
73 ////// END analog input code ////////
74 
75 
76 
77 //// BEGIN AUDIO OUTPUT code ///////
78 IntervalTimer timer1;
79 
80 #if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user
81 #if IS_TEENSY3()
82 #include "AudioConfigTeensy3_12bit.h"
83 #elif IS_TEENSY4()
84 #include "AudioConfigTeensy4.h"
85 #endif
86 inline void audioOutput(const AudioOutput f) {
87  analogWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS);
88 #if (AUDIO_CHANNELS > 1)
89  analogWrite(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS);
90 #endif
91 }
92 #endif
93 
94 static void startAudio() {
95 #if IS_TEENSY3()
96  analogWriteResolution(12);
97 #elif IS_TEENSY4()
98  analogWriteResolution(10);
99 # if (!EXTERNAL_AUDIO_OUTPUT)
100  analogWriteFrequency(AUDIO_CHANNEL_1_PIN, 146484.38f);
101 # if (AUDIO_CHANNELS > 1)
102  analogWriteFrequency(AUDIO_CHANNEL_2_PIN, 146484.38f);
103 # endif // end #if (AUDIO_CHANNELS > 1)
104 # endif // end #if (!EXTERNAL_AUDIO_OUTPUT)
105 #endif
106  timer1.begin(defaultAudioOutput, 1000000. / AUDIO_RATE);
107 }
108 
109 void stopMozzi() {
110  timer1.end();
111  interrupts();
112 }
113 //// END AUDIO OUTPUT code ///////
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
#define AUDIO_CHANNELS
This sets allows to change from a single/mono audio output channel to stereo output.
Definition: mozzi_config.h:92
-
#define IS_TEENSY4()
-
#define AUDIO_RATE
Holds the audio rate setting.
Definition: mozzi_config.h:62
-
#define IS_TEENSY3()
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
-
#define EXTERNAL_AUDIO_OUTPUT
Defining this option as true in mozzi_config.h allows to completely customize the audio output...
Definition: mozzi_config.h:99
+
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_TEENSY3() || IS_TEENSY4())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 #if (IS_TEENSY3() && F_CPU != 48000000)
18 #warning
19  "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino and 48MHz on Teensy 3! Results may vary with other speeds."
20 #endif
21 
22 namespace MozziPrivate {
23 ////// BEGIN analog input code ////////
24 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
25 // required from http://github.com/pedvide/ADC for Teensy 3.*
26 } //namespace MozziPrivate
27 #include <ADC.h>
28 namespace MozziPrivate {
29 
30 ADC *adc; // adc object
31 uint8_t teensy_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform
32 int8_t teensy_adc=0;
33 #define getADCReading() adc->readSingle(teensy_adc)
34 #define channelNumToIndex(channel) teensyPinMap(channel)
35 uint8_t adcPinToChannelNum(uint8_t pin) {
36  return pin;
37 }
38 
39 void setupFastAnalogRead(int8_t speed) {
40  adc->adc0->setAveraging(0);
41  adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED); // could be HIGH_SPEED, noisier
42 #ifdef ADC_DUAL_ADCS
43  adc->adc1->setAveraging(0);
44  adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED);
45 #endif
46 }
47 
48 } // namespace MozziPrivate
49 void adc0_isr(void)
50 {
51  MozziPrivate::advanceADCStep();
52 }
53 namespace MozziPrivate {
54 
55 void setupMozziADC(int8_t speed) {
56  adc = new ADC();
57  adc->adc0->enableInterrupts(adc0_isr); // TODO: is this even correct? Does the function take a parameter? And is adc0_isr a predefined name, or are we free to move this to MozziPrivate?
58 #ifdef ADC_DUAL_ADCS
59  adc->adc1->enableInterrupts(adc0_isr);
60 #endif
61 }
62 
63 void adcStartConversion(uint8_t channel) {
64  teensy_pin = channel; // remember for startSecondADCReadOnCurrentChannel()
65 #ifdef ADC_DUAL_ADCS
66  if (adc->adc0->checkPin(teensy_pin)) teensy_adc = 0;
67  else teensy_adc=1;
68 #endif
69  adc->startSingleRead(teensy_pin,teensy_adc);
70 }
71 
72 static void startSecondADCReadOnCurrentChannel() {
73  adc->startSingleRead(teensy_pin,teensy_adc);
74 }
75 #endif // MOZZI_ANALOG_READ
76 
77 ////// END analog input code ////////
78 
79 
80 
81 //// BEGIN AUDIO OUTPUT code ///////
82 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
83 } // namespace MozziPrivate
84 #include "IntervalTimer.h"
85 namespace MozziPrivate {
86 IntervalTimer timer1;
87 #endif
88 
89 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC)
90 inline void audioOutput(const AudioOutput f) {
91  analogWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
92 # if (MOZZI_AUDIO_CHANNELS > 1)
93  analogWrite(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS);
94 # endif
95 }
96 #endif
97 
98 static void startAudio() {
99 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC)
100 # if IS_TEENSY3()
101  analogWriteResolution(12);
102 # elif IS_TEENSY4()
103  analogWriteResolution(10);
104  analogWriteFrequency(MOZZI_AUDIO_PIN_1, 146484.38f);
105 # if (MOZZI_AUDIO_CHANNELS > 1)
106  analogWriteFrequency(MOZZI_AUDIO_PIN_2, 146484.38f);
107 # endif // end #if (MOZZI_AUDIO_CHANNELS > 1)
108 # endif // TEENSY3/4
109 #endif
110 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
111  timer1.begin(defaultAudioOutput, 1000000. / MOZZI_AUDIO_RATE);
112 #endif
113 }
114 
115 void stopMozzi() {
116 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
117  timer1.end();
118 #endif
119  interrupts();
120 }
121 //// END AUDIO OUTPUT code ///////
122 
123 //// BEGIN Random seeding ////////
124 void MozziRandPrivate::autoSeed() {
125 #warning Automatic random seeding is not implemented on this platform
126 }
127 //// END Random seeding ////////
128 
129 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 /** README!
14  * This file is meant to be used as a template when adding support for a new platform. Please read these instructions, first.
15  *
16  * Files involved:
17  * 1. Modify hardware_defines.h, adding a macro to detect your target platform
18  * 2. Modify MozziGuts.cpp to include MozziGuts_impl_YOURPLATFORM.hpp
19  * 3. Modify MozziGuts.h to include AudioConfigYOURPLATFORM.h
20  * 4. Copy this file to MozziGuts_impl_YOURPLATFORM.hpp and adjust as necessary
21  * (If your platform is very similar to an existing port, it may instead be better to modify the existing MozziGuts_impl_XYZ.hpp/AudioConfigYOURPLATFORM.h,
22  * instead of steps 2-3.).
23  * Some platforms may need small modifications to other files as well, e.g. mozzi_pgmspace.h
24  *
25  * How to implement MozziGuts_impl_YOURPLATFORM.hpp:
26  * - Follow the NOTEs provided in this file
27  * - Read the doc at the top of AudioOutput.h for a better understanding of the basic audio output framework
28  * - Take a peek at existing implementations for other hardware (e.g. TEENSY3/4 is rather complete while also simple at the time of this writing)
29  * - Wait for more documentation to arrive
30  * - Ask when in doubt
31  * - Don't forget to provide a PR when done (it does not have to be perfect; e.g. many ports skip analog input, initially)
32  */
33 
34 // The main point of this check is to document, what platform & variants this implementation file is for.
35 #if !(IS_MYPLATFORM())
36 # error "Wrong implementation included for this platform"
37 #endif
38 // Add platform specific includes and declarations, here
39 
40 
41 ////// BEGIN analog input code ////////
42 
43 /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of USE_AUDIO_INPUT (if enabled).
44  * This template provides empty/dummy implementations to allow you to skip over this section, initially. Once you have an implementation, be sure to enable the
45  * #define, below: */
46 //#define MOZZI_FAST_ANALOG_IMPLEMENTED
47 
48 // Insert here code to read the result of the latest asynchronous conversion, when it is finished.
49 // You can also provide this as a function returning unsigned int, should it be more complex on your platform
50 #define getADCReading() 0
51 
52 /** NOTE: On "pins" vs. "channels" vs. "indices"
53  * "Pin" is the pin number as would usually be specified by the user in mozziAnalogRead().
54  * "Channel" is an internal ADC channel number corresponding to that pin. On many platforms this is simply the same as the pin number, on others it differs.
55  * In other words, this is an internal representation of "pin".
56  * "Index" is the index of the reading for a certain pin/channel in the array of analog_readings, ranging from 0 to NUM_ANALOG_PINS. This, again may be the
57  * same as "channel" (e.g. on AVR), however, on platforms where ADC-capable "channels" are not numbered sequentially starting from 0, the channel needs
58  * to be converted to a suitable index.
59  *
60  * In summary, the semantics are roughly
61  * mozziAnalogRead(pin) -> _ADCimplementation_(channel) -> analog_readings[index]
62  * Implement adcPinToChannelNum() and channelNumToIndex() to perform the appropriate mapping.
63  */
64 // NOTE: Theoretically, adcPinToChannelNum is public API for historical reasons, thus cannot be replaced by a define
65 #define channelNumToIndex(channel) channel
66 uint8_t adcPinToChannelNum(uint8_t pin) {
67  return pin;
68 }
69 
70 /** NOTE: Code needed to trigger a conversion on a new channel */
71 void adcStartConversion(uint8_t channel) {
72 #warning Fast analog read not implemented on this platform
73 }
74 
75 /** NOTE: Code needed to trigger a subsequent conversion on the latest channel. If your platform has no special code for it, you should store the channel from
76  * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */
77 void startSecondADCReadOnCurrentChannel() {
78 #warning Fast analog read not implemented on this platform
79 }
80 
81 /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize.
82  * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */
83 void setupFastAnalogRead(int8_t speed) {
84 #warning Fast analog read not implemented on this platform
85 }
86 
87 /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and
88  * possibly calibration. */
89 void setupMozziADC(int8_t speed) {
90 #warning Fast analog read not implemented on this platform
91 }
92 
93 /* NOTE: Most platforms call a specific function/ISR when conversion is complete. Provide this function, here.
94  * From inside its body, simply call advanceADCStep(). E.g.:
95 void stm32_adc_eoc_handler() {
96  advanceADCStep();
97 }
98 */
99 ////// END analog input code ////////
100 
101 ////// BEGIN audio output code //////
102 /* NOTE: Some platforms rely on control returning from loop() every so often. However, updateAudio() may take too long (it tries to completely fill the output buffer,
103  * which of course is being drained at the same time, theoretically it may not return at all). If you set this define, it will be called once per audio frame to keep things
104  * running smoothly. */
105 //#define LOOP_YIELD yield();
106 
107 #if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user
108 /** NOTE: This is the function that actually write a sample to the output. In case of EXTERNAL_AUDIO_OUTPUT == true, it is provided by the library user, instead. */
109 inline void audioOutput(const AudioOutput f) {
110  // e.g. analogWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS);
111 #if (AUDIO_CHANNELS > 1)
112  // e.g. analogWrite(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS);
113 #endif
114 }
115 #endif
116 
117 static void startAudio() {
118  // Add here code to get audio output going. This usually involves:
119  // 1) setting up some DAC mechanism (e.g. setting up a PWM pin with appropriate resolution
120  // 2a) setting up a timer to call defaultAudioOutput() at AUDIO_RATE
121  // OR 2b) setting up a buffered output queue such as I2S (see ESP32 / ESP8266 for examples for this setup)
122 #if (EXTERNAL_AUDIO_OUTPUT != true)
123  // remember that the user may configure EXTERNAL_AUDIO_OUTPUT, in which case, you'll want to provide step 2a), and only that.
124 #endif
125 }
126 
127 void stopMozzi() {
128  // Add here code to pause whatever mechanism moves audio samples to the output
129 }
130 ////// END audio output code //////
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
+
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 /** README!
14  * This file is meant to be used as a template when adding support for a new platform. Please read these instructions, first.
15  *
16  * Files involved:
17  * 1. Modify hardware_defines.h, adding a macro to detect your target platform
18  * 2. Modify MozziGuts.cpp to include MozziGuts_impl_YOURPLATFORM.hpp
19  * 3. Modify internal/config_checks_generic.h to include internal/config_checks_YOURPLATFORM.h
20  * 4. Copy this file to MozziGuts_impl_YOURPLATFORM.hpp and adjust as necessary, same for internal/config_checks_template.h
21  * (If your platform is very similar to an existing port, it may instead be better to modify the existing MozziGuts_impl_XYZ.hpp/config_checks_XYZ.h,
22  * instead of steps 2-3.).
23  * Some platforms may need small modifications to other files as well, e.g. mozzi_pgmspace.h
24  *
25  * How to implement MozziGuts_impl_YOURPLATFORM.hpp:
26  * - Follow the NOTEs provided in this file
27  * - Read the doc at the top of AudioOutput.h for a better understanding of the basic audio output framework
28  * - Take a peek at existing implementations for other hardware (e.g. TEENSY3/4 is rather complete while also simple at the time of this writing)
29  * - Wait for more documentation to arrive
30  * - Ask when in doubt
31  * - Don't forget to provide a PR when done (it does not have to be perfect; e.g. many ports skip analog input, initially)
32  */
33 
34 // The main point of this check is to document, what platform & variants this implementation file is for.
35 #if !(IS_MYPLATFORM())
36 # error "Wrong implementation included for this platform"
37 #endif
38 // Add platform specific includes and declarations, here
39 
40 //#include <my_hardware_header.h>
41 
42 // In order to allow simple yet efficient user configuration, the entire contents of this file are compiled in the same translation unit
43 // as (the main file of) the user sketch. To avoid name clashes, we encapsulate everyghing in a namespace.
44 // For the most part, this namescape can just extend from the start of the file to the end (as shown, here), and you will not have to
45 // worry about it. However, there may be a few situations, where you have to "leave" the MozziPrivate namespace. This includes:
46 // - When you include a further (hardware-dependent library). Consider gathering all includes at the top of this file, instead.
47 // - When you provide definitions for special names, importantly for ISR-functions. If these would be placed in the namespace, the linker would not
48 // recognize them as the definition of the intended ISR-vector. See MozziGuts_impl_AVR.hpp for examples.
49 
50 namespace MozziPrivate {
51 
52 ////// BEGIN analog input code ////////
53 
54 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
55 /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of MOZZI_AUDIO_INPUT (if enabled).
56  *
57  * It is possible, and even recommended, to skip over this section, initially, when starting a new port. Once you have an implementation, be sure to include something like this
58  * in your platform configuration checks:
59  *
60  * // analog reads shall be enabled by default on platforms that support it
61  * #if not defined(MOZZI_ANALOG_READ)
62  * #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
63  * #endif
64  *
65  * Also, of course, remove the #error line, below
66  */
67 #error not yet implemented
68 
69 // Insert here code to read the result of the latest asynchronous conversion, when it is finished.
70 // You can also provide this as a function returning unsigned int, should it be more complex on your platform
71 #define getADCReading() GET_MY_PLATFORM_ADC_REGISTER
72 
73 /** NOTE: On "pins" vs. "channels" vs. "indices"
74  * "Pin" is the pin number as would usually be specified by the user in mozziAnalogRead().
75  * "Channel" is an internal ADC channel number corresponding to that pin. On many platforms this is simply the same as the pin number, on others it differs.
76  * In other words, this is an internal representation of "pin".
77  * "Index" is the index of the reading for a certain pin/channel in the array of analog_readings, ranging from 0 to NUM_ANALOG_PINS. This, again may be the
78  * same as "channel" (e.g. on AVR), however, on platforms where ADC-capable "channels" are not numbered sequentially starting from 0, the channel needs
79  * to be converted to a suitable index.
80  *
81  * In summary, the semantics are roughly
82  * mozziAnalogRead(pin) -> _ADCimplementation_(channel) -> analog_readings[index]
83  * Implement adcPinToChannelNum() and channelNumToIndex() to perform the appropriate mapping.
84  */
85 // NOTE: Theoretically, adcPinToChannelNum is public API for historical reasons, thus cannot be replaced by a define
86 #define channelNumToIndex(channel) channel
87 uint8_t adcPinToChannelNum(uint8_t pin) {
88  return pin;
89 }
90 
91 /** NOTE: Code needed to trigger a conversion on a new channel */
92 void adcStartConversion(uint8_t channel) {
93 }
94 
95 /** NOTE: Code needed to trigger a subsequent conversion on the latest channel. If your platform has no special code for it, you should store the channel from
96  * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */
97 void startSecondADCReadOnCurrentChannel() {
98 }
99 
100 /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and
101  * possibly calibration. */
102 void setupMozziADC(int8_t speed) {
103  setupFastAnalogRead(speed);
104  // insert further custom code
105 }
106 
107 /* NOTE: Most platforms call a specific function/ISR when conversion is complete. Provide this function, here.
108  * From inside its body, simply call advanceADCStep(). E.g.:
109 void stm32_adc_eoc_handler() {
110  advanceADCStep();
111 }
112 */
113 
114 /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize.
115  * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */
116 void setupFastAnalogRead(int8_t speed) {
117 }
118 
119 #endif
120 
121 ////// END analog input code ////////
122 
123 ////// BEGIN audio output code //////
124 /* NOTE: Some platforms rely on control returning from loop() every so often. However, updateAudio() may take too long (it tries to completely fill the output buffer,
125  * which of course is being drained at the same time, theoretically it may not return at all). If you set this define, it will be called once per audio frame to keep things
126  * running smoothly. */
127 //#define LOOP_YIELD yield();
128 
129 /* NOTE: On some platforms, what can be called in the ISR used to output the sound is limited.
130  * This define can be used, for instance, to output the sound in audioHook() instead to overcome
131  * this limitation (see MozziGuts_impl_MBED.hpp). It can also be used if something needs to be called in audioHook() regarding
132  * analog reads for instance. */
133 //#define AUDIO_HOOK_HOOK
134 
135 /* NOTE: Code sections that are needed for a certain audio mode, only, should be guarded as follows (in this example, code will compile for the
136  * two modes MOZZI_OUTPUT_PWM, and MOZZI_OUTPUT_INTERNAL_DAC (should your port happen to support these two).
137  *
138  * Keep in mind that you probably want to support MOZZI_OUTPUT_EXTERNAL_TIMED, and MOZZI_OUTPUT_EXTERNAL_CUSTOM, too, which is usually very
139  * easy: For both, do *not* provide an audioOutput() function, as this will be provided by the user. For MOZZI_OUTPUT_EXTERNAL_TIMED make sure some
140  * timer is set up to call defaultAudioOutput() at MOZZI_AUDIO_RATE. For MOZZI_OUTPUT_EXTERNAL_CUSTOM, nothing else will be needed. */
141 
142 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC) // just an example!
143 /** NOTE: This is the function that actually write a sample to the output. In case of the two EXTERNAL modes, it is provided by the library user, instead. */
144 inline void audioOutput(const AudioOutput f) {
145  // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_1_PIN, f.l()+MOZZI_AUDIO_BIAS);
146 # if (MOZZI_AUDIO_CHANNELS > 1)
147  // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_2_PIN, f.r()+MOZZI_AUDIO_BIAS);
148 # endif
149 }
150 #endif
151 
152 static void startAudio() {
153  // Add here code to get audio output going. This usually involves:
154  // 1) setting up some DAC mechanism (e.g. setting up a PWM pin with appropriate resolution
155  // 2a) setting up a timer to call defaultAudioOutput() at MOZZI_AUDIO_RATE
156  // OR 2b) setting up a buffered output queue such as I2S (see ESP32 / ESP8266 for examples for this setup)
157 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
158  // [...]
159 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
160  // [...]
161 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
162  // remember that the user may configure MOZZI_OUTPUT_EXTERNAL_TIMED, in which case, you'll want to provide step 2a), and only that.
163 #endif
164 }
165 
166 void stopMozzi() {
167  // Add here code to pause whatever mechanism moves audio samples to the output
168 }
169 ////// END audio output code //////
170 
171 //// BEGIN Random seeding ////////
172 void MozziRandPrivate::autoSeed() {
173  // Add here code to initialize the values of MozziRandPrivate::x, MozziRandPrivate::y, and MozziRandPrivate::z to some random values
174  // This doesn't need to be crypographically safe. If nothing better is available, e.g. try reading an internal temperature sensor
175  // in order to get some noise. It also doesn't have to be fast.
176  // It *should* however ensure that rand() sequences will differ across reboots, after randSeed() has been called.
177  // x, y, and z are already initialized to non-zero, when this function is called.
178  // It's ok to leave this unimplemented, initially.
179 #warning Automatic random seeding is not implemented on this platform
180 }
181 //// END Random seeding ////////
182 
183 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
1 /*
2  * Oscil.h
3  *
4  * Oscil.h owes much to AF_precision_synthesis.pde, 2009, Adrian Freed.
5  *
6  * Copyright 2012 Tim Barrass, 2009 Adrian Freed.
7  *
8  * This file is part of Mozzi.
9  *
10  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
11  *
12  */
13 
14 #ifndef OSCIL_H_
15 #define OSCIL_H_
16 
17 #if ARDUINO >= 100
18  #include "Arduino.h"
19 #else
20  #include "WProgram.h"
21 #endif
22 #include "MozziGuts.h"
23 #include "mozzi_fixmath.h"
24 #include "mozzi_pgmspace.h"
25 
26 #ifdef OSCIL_DITHER_PHASE
27 #include "mozzi_rand.h"
28 #endif
29 
30 // fractional bits for oscillator index precision
31 #define OSCIL_F_BITS 16
32 #define OSCIL_F_BITS_AS_MULTIPLIER 65536
33 
34 // phmod_proportion is an 15n16 fixed-point number
35 #define OSCIL_PHMOD_BITS 16
36 
37 /**
38 Oscil plays a wavetable, cycling through the table to generate an audio or
39 control signal. The frequency of the signal can be set or changed with
40 setFreq(), and the output of an Oscil can be produced with next() for a simple
41 cycling oscillator, or atIndex() for a particular sample in the table.
42 @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Oscil will be
43 using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a
44 defined macro, rather than a const or int, for the Oscil to run fast enough.
45 @tparam UPDATE_RATE This will be AUDIO_RATE if the Oscil is updated in
46 updateAudio(), or CONTROL_RATE if it's updated each time updateControl() is
47 called. It could also be a fraction of CONTROL_RATE if you are doing some kind
48 of cyclic updating in updateControl(), for example, to spread out the processor load.
49 @todo Use conditional compilation to optimise setFreq() variations for different table
50 sizes.
51 @note If you #define OSCIL_DITHER_PHASE before you #include <Oscil.h>,
52 the phase increments will be dithered, which reduces spurious frequency spurs
53 in the audio output, at the cost of some extra processing and memory.
54 @section int8_t2mozzi
55 Converting soundfiles for Mozzi
56 There is a python script called char2mozzi.py in the Mozzi/python folder.
57 The usage is:
58 char2mozzi.py infilename outfilename tablename samplerate
59 */
60 //template <unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, bool DITHER_PHASE=false>
61 template <uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
62 class Oscil
63 {
64 
65 
66 public:
67  /** Constructor.
68  @param TABLE_NAME the name of the array the Oscil will be using. This
69  can be found in the table ".h" file if you are using a table made for
70  Mozzi by the int8_t2mozzi.py python script in Mozzi's python
71  folder.*/
72  Oscil(const int8_t * TABLE_NAME):table(TABLE_NAME)
73  {}
74 
75 
76  /** Constructor.
77  Declare an Oscil with template TABLE_NUM_CELLS and UPDATE_RATE
78  parameters, without specifying a particular wave table for it to play.
79  The table can be set or changed on the fly with setTable(). Any tables
80  used by the Oscil must be the same size.
81  */
83  {}
84 
85 
86  /** Updates the phase according to the current frequency and returns the sample at the new phase position.
87  @return the next sample.
88  */
89  inline
91  {
92  incrementPhase();
93  return readTable();
94  }
95 
96 
97  /** Change the sound table which will be played by the Oscil.
98  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
99  */
100  void setTable(const int8_t * TABLE_NAME)
101  {
102  table = TABLE_NAME;
103  }
104 
105 
106  /** Set the phase of the Oscil. This does the same thing as Sample::start(offset). Just different ways of thinking about oscillators and samples.
107  @param phase a position in the wavetable.
108  */
109  // This could be called in the control interrupt, so phase_fractional should really be volatile,
110  // but that could limit optimisation. Since phase_fractional gets changed often in updateAudio()
111  // (in loop()), it's probably worth keeping it nonvolatile until it causes problems
112  void setPhase(unsigned int phase)
113  {
114  phase_fractional = (unsigned long)phase << OSCIL_F_BITS;
115  }
116 
117  /** Set the phase of the Oscil. Might be useful with getPhaseFractional().
118  @param phase a position in the wavetable.
119  */
120  // This could be called in the control interrupt, so phase_fractional should really be volatile,
121  // but that could limit optimisation. Since phase_fractional gets changed often in updateAudio()
122  // (in loop()), it's probably worth keeping it nonvolatile until it causes problems
123  void setPhaseFractional(unsigned long phase)
124  {
125  phase_fractional = phase;
126  }
127 
128 
129  /** Get the phase of the Oscil in fractional format.
130  @return position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
131  */
132  unsigned long getPhaseFractional()
133  {
134  return phase_fractional;
135  }
136 
137 
138 
139  /** Returns the next sample given a phase modulation value.
140  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
141  phmod_proportion parameter is a Q15n16 fixed-point number where the fractional
142  n16 part represents almost -1 to almost 1, modulating the phase by one whole table length in
143  each direction.
144  @return a sample from the table.
145  */
146  // PM: cos((angle += incr) + change)
147  // FM: cos(angle += (incr + change))
148  // The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm )
149  inline
151  {
152  incrementPhase();
153  return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
154  }
155 
156 
157  /** Set the oscillator frequency with an unsigned int. This is faster than using a
158  float, so it's useful when processor time is tight, but it can be tricky with
159  low and high frequencies, depending on the size of the wavetable being used. If
160  you're not getting the results you expect, try explicitly using a float, or try
161  setFreq_Q24n8() or or setFreq_Q16n16().
162  @param frequency to play the wave table.
163  */
164  inline
165  void setFreq (int frequency) {
166  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
167  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
168  //phase_increment_fractional = ((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
169  // to this:
170  phase_increment_fractional = ((unsigned long)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
171  }
172 
173 
174  /** Set the oscillator frequency with a float. Using a float is the most reliable
175  way to set frequencies, -Might- be slower than using an int but you need either
176  this, setFreq_Q24n8() or setFreq_Q16n16() for fractional frequencies.
177  @param frequency to play the wave table.
178  */
179  inline
180  void setFreq(float frequency)
181  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
182  phase_increment_fractional = (unsigned long)((((float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * OSCIL_F_BITS_AS_MULTIPLIER);
183  }
184 
185 
186  /** Set the frequency using Q24n8 fixed-point number format.
187  This might be faster than the float version for setting low frequencies such as
188  1.5 Hz, or other values which may not work well with your table size. A Q24n8
189  representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE
190  less than 64 Hz.
191  @param frequency in Q24n8 fixed-point number format.
192  */
193  inline
194  void setFreq_Q24n8(Q24n8 frequency)
195  {
196  //phase_increment_fractional = (frequency* (NUM_TABLE_CELLS>>3)/(UPDATE_RATE>>6)) << (F_BITS-(8-3+6));
197 // TB2016-10-2 line below might have been left in accidentally while making the 2014 change below, remove for now
198 // phase_increment_fractional = (((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
199 // << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
200 
201  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
202  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
203  if ((256UL*NUM_TABLE_CELLS) >= UPDATE_RATE) {
204  phase_increment_fractional = ((unsigned long)frequency) * ((256UL*NUM_TABLE_CELLS)/UPDATE_RATE);
205  } else {
206  phase_increment_fractional = ((unsigned long)frequency) / (UPDATE_RATE/(256UL*NUM_TABLE_CELLS));
207  }
208  }
209 
210 
211  /** Set the frequency using Q16n16 fixed-point number format. This is useful in
212  combination with Q16n16_mtof(), a fast alternative to mtof(), using Q16n16
213  fixed-point format instead of floats.
214  @note This should work OK with tables 2048 cells or smaller and
215  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
216  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
217  @param frequency in Q16n16 fixed-point number format.
218  */
219  inline
220  void setFreq_Q16n16(Q16n16 frequency)
221  {
222  //phase_increment_fractional = ((frequency * (NUM_TABLE_CELLS>>7))/(UPDATE_RATE>>6)) << (F_BITS-16+1);
223  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
224  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
225  //phase_increment_fractional = (((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>7)*frequency)/(UPDATE_RATE>>6))
226  // << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - 16 + 1);
227  if (NUM_TABLE_CELLS >= UPDATE_RATE) {
228  phase_increment_fractional = ((unsigned long)frequency) * (NUM_TABLE_CELLS/UPDATE_RATE);
229  } else {
230  phase_increment_fractional = ((unsigned long)frequency) / (UPDATE_RATE/NUM_TABLE_CELLS);
231  }
232  }
233 /*
234  inline
235  void setFreqMidi(int8_t note_num) {
236  setFreq_Q16n16(mtof(note_num));
237  }
238 */
239  /** Returns the sample at the given table index.
240  @param index between 0 and the table size.The
241  index rolls back around to 0 if it's larger than the table size.
242  @return the sample at the given table index.
243  */
244  inline
245  int8_t atIndex(unsigned int index)
246  {
247  return FLASH_OR_RAM_READ<const int8_t>(table + (index & (NUM_TABLE_CELLS - 1)));
248  }
249 
250 
251  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
252  Instead of recalculating the phase increment for each
253  frequency in between, you can just calculate the phase increment for each end
254  frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and
255  use setPhaseInc() to set the phase increment at each step. (Note: I should
256  really profile this with the oscilloscope to see if it's worth the extra
257  confusion!)
258  @param frequency for which you want to calculate a phase increment value.
259  @return the phase increment value which will produce a given frequency.
260  */
261  inline
262  unsigned long phaseIncFromFreq(int frequency)
263  {
264  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
265  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
266  //return (((unsigned long)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << OSCIL_F_BITS;
267  return ((unsigned long)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
268  }
269 
270 
271  /** Set a specific phase increment. See phaseIncFromFreq().
272  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
273  */
274  inline
275  void setPhaseInc(unsigned long phaseinc_fractional)
276  {
277  phase_increment_fractional = phaseinc_fractional;
278  }
279 
280 
281 
282 private:
283 
284 
285  /** Used for shift arithmetic in setFreq() and its variations.
286  */
287 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
288 
289 
290  /** Increments the phase of the oscillator without returning a sample.
291  */
292  inline
293  void incrementPhase()
294  {
295  //phase_fractional += (phase_increment_fractional | 1); // odd phase incr, attempt to reduce frequency spurs in output
296  phase_fractional += phase_increment_fractional;
297  }
298 
299 
300  /** Returns the current sample.
301  */
302  inline
303  int8_t readTable()
304  {
305 #ifdef OSCIL_DITHER_PHASE
306  return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional + ((int)(xorshift96()>>16))) >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
307 #else
308  return FLASH_OR_RAM_READ<const int8_t>(table + ((phase_fractional >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
309  //return FLASH_OR_RAM_READ<int8_t>(table + (((phase_fractional >> OSCIL_F_BITS) | 1 ) & (NUM_TABLE_CELLS - 1))); odd phase, attempt to reduce frequency spurs in output
310 #endif
311  }
312 
313 
314  unsigned long phase_fractional;
315  unsigned long phase_increment_fractional;
316  const int8_t * table;
317 
318 };
319 
320 
321 /**
322 @example 01.Basics/Vibrato/Vibrato.ino
323 This is an example using Oscil::phMod to produce vibrato using phase modulation.
324 */
325 
326 #endif /* OSCIL_H_ */
int8_t next()
Updates the phase according to the current frequency and returns the sample at the new phase position...
Definition: Oscil.h:90
-
unsigned long getPhaseFractional()
Get the phase of the Oscil in fractional format.
Definition: Oscil.h:132
-
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:62
-
void setFreq(int frequency)
Set the oscillator frequency with an unsigned int.
Definition: Oscil.h:165
-
void setPhaseFractional(unsigned long phase)
Set the phase of the Oscil.
Definition: Oscil.h:123
-
unsigned long phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: Oscil.h:262
-
void setPhase(unsigned int phase)
Set the phase of the Oscil.
Definition: Oscil.h:112
-
#define OSCIL_F_BITS
Definition: Oscil.h:31
-
int8_t phMod(Q15n16 phmod_proportion)
Returns the next sample given a phase modulation value.
Definition: Oscil.h:150
-
Oscil(const int8_t *TABLE_NAME)
Constructor.
Definition: Oscil.h:72
-
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Oscil.
Definition: Oscil.h:100
-
void setFreq(float frequency)
Set the oscillator frequency with a float.
Definition: Oscil.h:180
-
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
Definition: Oscil.h:245
-
#define OSCIL_F_BITS_AS_MULTIPLIER
Definition: Oscil.h:32
-
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:45
-
void setFreq_Q16n16(Q16n16 frequency)
Set the frequency using Q16n16 fixed-point number format.
Definition: Oscil.h:220
-
void setPhaseInc(unsigned long phaseinc_fractional)
Set a specific phase increment.
Definition: Oscil.h:275
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46
-
Oscil()
Constructor.
Definition: Oscil.h:82
-
void setFreq_Q24n8(Q24n8 frequency)
Set the frequency using Q24n8 fixed-point number format.
Definition: Oscil.h:194
+
1 /*
2  * Oscil.h
3  *
4  * Oscil.h owes much to AF_precision_synthesis.pde, 2009, Adrian Freed.
5  *
6  * Copyright 2012 Tim Barrass, 2009 Adrian Freed.
7  *
8  * This file is part of Mozzi.
9  *
10  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
11  *
12  */
13 
14 #ifndef OSCIL_H_
15 #define OSCIL_H_
16 
17 #include "Arduino.h"
18 #include "MozziHeadersOnly.h"
19 #include "mozzi_fixmath.h"
20 #include "FixMath.h"
21 #include "mozzi_pgmspace.h"
22 
23 #ifdef OSCIL_DITHER_PHASE
24 #include "mozzi_rand.h"
25 #endif
26 
27 // fractional bits for oscillator index precision
28 #define OSCIL_F_BITS 16
29 #define OSCIL_F_BITS_AS_MULTIPLIER 65536
30 
31 // phmod_proportion is an 15n16 fixed-point number
32 #define OSCIL_PHMOD_BITS 16
33 
34 /**
35 Oscil plays a wavetable, cycling through the table to generate an audio or
36 control signal. The frequency of the signal can be set or changed with
37 setFreq(), and the output of an Oscil can be produced with next() for a simple
38 cycling oscillator, or atIndex() for a particular sample in the table.
39 @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Oscil will be
40 using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a
41 defined macro, rather than a const or int, for the Oscil to run fast enough.
42 @tparam UPDATE_RATE This will be MOZZI_AUDIO_RATE if the Oscil is updated in
43 updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is
44 called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind
45 of cyclic updating in updateControl(), for example, to spread out the processor load.
46 @todo Use conditional compilation to optimise setFreq() variations for different table
47 sizes.
48 @note If you #define OSCIL_DITHER_PHASE before you #include <Oscil.h>,
49 the phase increments will be dithered, which reduces spurious frequency spurs
50 in the audio output, at the cost of some extra processing and memory.
51 @section int8_t2mozzi
52 Converting soundfiles for Mozzi
53 There is a python script called char2mozzi.py in the Mozzi/python folder.
54 The usage is:
55 char2mozzi.py infilename outfilename tablename samplerate
56 */
57 //template <unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, bool DITHER_PHASE=false>
58 template <uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
59 class Oscil
60 {
61 
62 
63 public:
64  /** Constructor.
65  @param TABLE_NAME the name of the array the Oscil will be using. This
66  can be found in the table ".h" file if you are using a table made for
67  Mozzi by the int8_t2mozzi.py python script in Mozzi's python
68  folder.*/
69  Oscil(const int8_t * TABLE_NAME):table(TABLE_NAME)
70  {}
71 
72 
73  /** Constructor.
74  Declare an Oscil with template TABLE_NUM_CELLS and UPDATE_RATE
75  parameters, without specifying a particular wave table for it to play.
76  The table can be set or changed on the fly with setTable(). Any tables
77  used by the Oscil must be the same size.
78  */
80  {}
81 
82 
83  /** Updates the phase according to the current frequency and returns the sample at the new phase position.
84  @return the next sample.
85  */
86  inline
88  {
89  incrementPhase();
90  return readTable();
91  }
92 
93 
94  /** Change the sound table which will be played by the Oscil.
95  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
96  */
97  void setTable(const int8_t * TABLE_NAME)
98  {
99  table = TABLE_NAME;
100  }
101 
102 
103  /** Set the phase of the Oscil. This does the same thing as Sample::start(offset). Just different ways of thinking about oscillators and samples.
104  @param phase a position in the wavetable.
105  */
106  // This could be called in the control interrupt, so phase_fractional should really be volatile,
107  // but that could limit optimisation. Since phase_fractional gets changed often in updateAudio()
108  // (in loop()), it's probably worth keeping it nonvolatile until it causes problems
109  void setPhase(unsigned int phase)
110  {
111  phase_fractional = (uint32_t)phase << OSCIL_F_BITS;
112  }
113 
114  /** Set the phase of the Oscil. Might be useful with getPhaseFractional().
115  @param phase a position in the wavetable.
116  */
117  // This could be called in the control interrupt, so phase_fractional should really be volatile,
118  // but that could limit optimisation. Since phase_fractional gets changed often in updateAudio()
119  // (in loop()), it's probably worth keeping it nonvolatile until it causes problems
120  void setPhaseFractional(uint32_t phase)
121  {
122  phase_fractional = phase;
123  }
124 
125 
126  /** Get the phase of the Oscil in fractional format.
127  @return position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
128  */
130  {
131  return phase_fractional;
132  }
133 
134 
135 
136  /** Returns the next sample given a phase modulation value.
137  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
138  phmod_proportion parameter is a Q15n16 fixed-point number where the fractional
139  n16 part represents almost -1 to almost 1, modulating the phase by one whole table length in
140  each direction.
141  @return a sample from the table.
142  */
143  // PM: cos((angle += incr) + change)
144  // FM: cos(angle += (incr + change))
145  // The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm )
146  inline
148  {
149  incrementPhase();
150  return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
151  }
152 
153 
154  /** Returns the next sample given a phase modulation value.
155  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
156  phmod_proportion parameter is a SFix<NI,NF> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in
157  each direction. This fixed point math number is interpreted as a SFix<15,16> internally.
158  @return a sample from the table.
159  */
160  template <byte NI, byte NF>
161  inline
163  {
164  return phMod(SFix<15,16>(phmod_proportion).asRaw());
165  }
166 
167 
168 
169  /** Returns the next sample given a phase modulation value.
170  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
171  phmod_proportion parameter is a SFix<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in
172  each direction.
173  @return a sample from the table.
174  */
175  inline
177  {
178  return phMod(phmod_proportion.asRaw());
179  }
180 
181 
182  /** Set the oscillator frequency with an unsigned int. This is faster than using a
183  float, so it's useful when processor time is tight, but it can be tricky with
184  low and high frequencies, depending on the size of the wavetable being used. If
185  you're not getting the results you expect, try explicitly using a float, or try
186  setFreq_Q24n8() or or setFreq_Q16n16().
187  @param frequency to play the wave table.
188  */
189  inline
190  void setFreq (int frequency) {
191  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
192  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
193  //phase_increment_fractional = ((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
194  // to this:
195  phase_increment_fractional = ((uint32_t)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
196  }
197 
198 
199  /** Set the oscillator frequency with a float. Using a float is the most reliable
200  way to set frequencies, -Might- be slower than using an int but you need either
201  this, setFreq_Q24n8() or setFreq_Q16n16() for fractional frequencies.
202  @param frequency to play the wave table.
203  */
204  inline
205  void setFreq(float frequency)
206  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
207  phase_increment_fractional = (uint32_t)((((float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * OSCIL_F_BITS_AS_MULTIPLIER);
208  }
209 
210 
211  /** Set the frequency using UFix<NI,NF> fixed-point number format. This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors.
212  @note This should work OK with tables 2048 cells or smaller and
213  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
214  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
215  @param frequency in UFix<NI,NF> fixed-point number format.
216  */
217  template <int8_t NI, int8_t NF>
218  inline
219  void setFreq(UFix<NI,NF> frequency)
220  {
221  setFreq_Q16n16(UFix<16,16>(frequency).asRaw());
222  }
223 
224 
225 
226  /** Set the frequency using Q24n8 fixed-point number format.
227  This might be faster than the float version for setting low frequencies such as
228  1.5 Hz, or other values which may not work well with your table size. A Q24n8
229  representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE
230  less than 64 Hz.
231  @param frequency in Q24n8 fixed-point number format.
232  */
233  inline
234  void setFreq_Q24n8(Q24n8 frequency)
235  {
236  //phase_increment_fractional = (frequency* (NUM_TABLE_CELLS>>3)/(UPDATE_RATE>>6)) << (F_BITS-(8-3+6));
237 // TB2016-10-2 line below might have been left in accidentally while making the 2014 change below, remove for now
238 // phase_increment_fractional = (((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
239 // << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
240 
241  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
242  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
243  if ((256UL*NUM_TABLE_CELLS) >= UPDATE_RATE) {
244  phase_increment_fractional = ((uint32_t)frequency) * ((256UL*NUM_TABLE_CELLS)/UPDATE_RATE);
245  } else {
246  phase_increment_fractional = ((uint32_t)frequency) / (UPDATE_RATE/(256UL*NUM_TABLE_CELLS));
247  }
248  }
249 
250  /** Set the frequency using UFix<24,8> fixed-point number format.
251  This might be faster than the float version for setting low frequencies such as
252  1.5 Hz, or other values which may not work well with your table size. A UFix<24,8>
253  representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE
254  less than 64 Hz.
255  @param frequency in UFix<24,8> fixed-point number format.
256  */
257  inline
258  void setFreq(UFix<24,8> frequency)
259  {
260  setFreq_Q24n8(frequency.asRaw());
261  }
262 
263 
264  /** Set the frequency using Q16n16 fixed-point number format. This is useful in
265  combination with Q16n16_mtof(), a fast alternative to mtof(), using Q16n16
266  fixed-point format instead of floats.
267  @note This should work OK with tables 2048 cells or smaller and
268  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
269  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
270  @param frequency in Q16n16 fixed-point number format.
271  */
272  inline
273  void setFreq_Q16n16(Q16n16 frequency)
274  {
275  //phase_increment_fractional = ((frequency * (NUM_TABLE_CELLS>>7))/(UPDATE_RATE>>6)) << (F_BITS-16+1);
276  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
277  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
278  //phase_increment_fractional = (((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>7)*frequency)/(UPDATE_RATE>>6))
279  // << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - 16 + 1);
280  if (NUM_TABLE_CELLS >= UPDATE_RATE) {
281  phase_increment_fractional = ((uint32_t)frequency) * (NUM_TABLE_CELLS/UPDATE_RATE);
282  } else {
283  phase_increment_fractional = ((uint32_t)frequency) / (UPDATE_RATE/NUM_TABLE_CELLS);
284  }
285  }
286 
287 
288  /** Set the frequency using UFix<16,16> fixed-point number format. This is useful in
289  combination with Q16n16_mtof(), a fast alternative to mtof(), using UFix<16,16>
290  fixed-point format instead of fractional numbers.
291  @note This should work OK with tables 2048 cells or smaller and
292  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
293  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
294  @param frequency in UFix<16,16> fixed-point number format.
295  */
296  inline
297  void setFreq(UFix<16,16> frequency)
298  {
299  setFreq_Q16n16(frequency.asRaw());
300  }
301 
302 
303 
304  /** Set the frequency using SFix<NI,NF> fixed-point number format. This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors.
305  @note This should work OK with tables 2048 cells or smaller and
306  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
307  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
308  @param frequency in SFix<16,16> fixed-point number format.
309  */
310  template <byte NI, byte NF>
311  inline
312  void setFreq(SFix<NI,NF> frequency)
313  {
314  setFreq_Q16n16(UFix<16,16>(frequency).asRaw());
315  }
316 
317 /*
318  inline
319  void setFreqMidi(int8_t note_num) {
320  setFreq_Q16n16(mtof(note_num));
321  }
322 */
323  /** Returns the sample at the given table index.
324  @param index between 0 and the table size.The
325  index rolls back around to 0 if it's larger than the table size.
326  @return the sample at the given table index.
327  */
328  inline
329  int8_t atIndex(unsigned int index)
330  {
331  return FLASH_OR_RAM_READ<const int8_t>(table + (index & (NUM_TABLE_CELLS - 1)));
332  }
333 
334 
335  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
336  Instead of recalculating the phase increment for each
337  frequency in between, you can just calculate the phase increment for each end
338  frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and
339  use setPhaseInc() to set the phase increment at each step. (Note: I should
340  really profile this with the oscilloscope to see if it's worth the extra
341  confusion!)
342  @param frequency for which you want to calculate a phase increment value.
343  @return the phase increment value which will produce a given frequency.
344  */
345  inline
347  {
348  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
349  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
350  //return (((uint32_t)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << OSCIL_F_BITS;
351  return ((uint32_t)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
352  }
353 
354 
355  /** Set a specific phase increment. See phaseIncFromFreq().
356  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
357  */
358  inline
359  void setPhaseInc(uint32_t phaseinc_fractional)
360  {
361  phase_increment_fractional = phaseinc_fractional;
362  }
363 
364 
365 
366 private:
367 
368 
369  /** Used for shift arithmetic in setFreq() and its variations.
370  */
371 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
372 
373 
374  /** Increments the phase of the oscillator without returning a sample.
375  */
376  inline
377  void incrementPhase()
378  {
379  //phase_fractional += (phase_increment_fractional | 1); // odd phase incr, attempt to reduce frequency spurs in output
380  phase_fractional += phase_increment_fractional;
381  }
382 
383 
384  /** Returns the current sample.
385  */
386  inline
387  int8_t readTable()
388  {
389 #ifdef OSCIL_DITHER_PHASE
390  return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional + ((int)(xorshift96()>>16))) >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
391 #else
392  return FLASH_OR_RAM_READ<const int8_t>(table + ((phase_fractional >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
393  //return FLASH_OR_RAM_READ<int8_t>(table + (((phase_fractional >> OSCIL_F_BITS) | 1 ) & (NUM_TABLE_CELLS - 1))); odd phase, attempt to reduce frequency spurs in output
394 #endif
395  }
396 
397 
398  uint32_t phase_fractional;
399  uint32_t phase_increment_fractional;
400  const int8_t * table;
401 
402 };
403 
404 
405 /**
406 @example 01.Basics/Vibrato/Vibrato.ino
407 This is an example using Oscil::phMod to produce vibrato using phase modulation.
408 */
409 
410 #endif /* OSCIL_H_ */
int8_t next()
Updates the phase according to the current frequency and returns the sample at the new phase position...
Definition: Oscil.h:87
+
void setFreq(UFix< 16, 16 > frequency)
Set the frequency using UFix<16,16> fixed-point number format.
Definition: Oscil.h:297
+
int8_t phMod(SFix< NI, NF > phmod_proportion)
Returns the next sample given a phase modulation value.
Definition: Oscil.h:162
+
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:59
+
void setPhaseFractional(uint32_t phase)
Set the phase of the Oscil.
Definition: Oscil.h:120
+
void setPhase(unsigned int phase)
Set the phase of the Oscil.
Definition: Oscil.h:109
+
#define OSCIL_F_BITS
Definition: Oscil.h:28
+
uint32_t phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: Oscil.h:346
+
uint32_t getPhaseFractional()
Get the phase of the Oscil in fractional format.
Definition: Oscil.h:129
+
Oscil(const int8_t *TABLE_NAME)
Constructor.
Definition: Oscil.h:69
+
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Oscil.
Definition: Oscil.h:97
+
void setFreq(float frequency)
Set the oscillator frequency with a float.
Definition: Oscil.h:205
+
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
Definition: Oscil.h:329
+
#define OSCIL_F_BITS_AS_MULTIPLIER
Definition: Oscil.h:29
+
void setFreq(SFix< NI, NF > frequency)
Set the frequency using SFix<NI,NF> fixed-point number format.
Definition: Oscil.h:312
+
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:43
+
void setFreq_Q16n16(Q16n16 frequency)
Set the frequency using Q16n16 fixed-point number format.
Definition: Oscil.h:273
+
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:44
+
Oscil()
Constructor.
Definition: Oscil.h:79
+
int8_t phMod(SFix< 15, 16 > phmod_proportion)
Returns the next sample given a phase modulation value.
Definition: Oscil.h:176
+
void setFreq_Q24n8(Q24n8 frequency)
Set the frequency using Q24n8 fixed-point number format.
Definition: Oscil.h:234
+
void setPhaseInc(uint32_t phaseinc_fractional)
Set a specific phase increment.
Definition: Oscil.h:359
-
1 #ifndef OVERSAMPLE_H
2 #define OVERSAMPLE_H
3 
4 /*
5  * OverSample.h
6  *
7  * Copyright 2013 Tim Barrass.
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 
15  #include "RollingAverage.h"
16 
17 
18 /** @ingroup sensortools
19  Enables the resolution of analog inputs to be increased by oversampling and decimation.
20  Noise should be added to the input before it's digitised, then a succession of input readings are summed and
21  finally divided to give a number with greater resolution than the ADC.
22  Often, noise in the Arduino system will be enough, but there are other practical methods described in
23  [Enhancing ADC Resolution by Oversampling](http://www.atmel.com/images/doc8003.pdf‎),
24  as well as an explanation of the overall approach.
25  @tparam RESOLUTION_INCREASE_BITS how many extra bits of resolution to produce.
26  The window length and the memory it needs increases quickly as the oversampling resolution increases.
27  1 bit = 4 unsigned ints (analog input between 0-1023) = 8 uint8_ts,
28  2 bits = 16 unsigned ints = 32 uint8_ts,
29  3 bits = 64 unsigned ints = 128 uint8_ts,
30  More than 3 bits increase in resolution would require either using longs to store the readings,
31  which would need 1024 uint8_ts for a 4 bit increase and 4096 uint8_ts for 5 bits (do any avr's have that much room?),
32  or the average reading would have to be no more than 128 (for 4 bits increase), because 256 readings would be needed,
33  and the sum of all 256 readings would have to fit into an int. (32767 / 256 = 128).
34  Changing OverSample to use unsigned ints could enable an average reading of 256, but isn't tested properly yet.
35  @note The higher the resolution, the more lag there will be.
36  It's almost a RollingAverage filter, with the difference that
37  OverSample doesn't divide by as much as you would for an average.
38 */
39 
40 
41 template <class T, const uint8_t RESOLUTION_INCREASE_BITS>
42 class OverSample: public RollingAverage<T, (1<<(RESOLUTION_INCREASE_BITS*2))>
43 {
44 
45 public:
46  using RollingAverage<T, (1<<(RESOLUTION_INCREASE_BITS*2))>::add;
47 
48  /** Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;
49  @param input an analog input to oversample.
50  @return the higher resolution result.
51  @note timing 5.7us
52  */
53  T next(T input)
54  {
55  return add(input)>>RESOLUTION_INCREASE_BITS;
56  }
57 
58 };
59 
60 
61 /**
62 @example 05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino
63 This is an example demonstrating the OverSample class.
64 */
65 
66 #endif // #ifndef OVERSAMPLE_H
Calculates a running average over a specified number of the most recent readings. ...
-
T next(T input)
Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;.
Definition: OverSample.h:53
-
Enables the resolution of analog inputs to be increased by oversampling and decimation.
Definition: OverSample.h:42
+
1 #ifndef OVERSAMPLE_H
2 #define OVERSAMPLE_H
3 
4 /*
5  * OverSample.h
6  *
7  * Copyright 2013 Tim Barrass.
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 
15  #include "RollingAverage.h"
16 
17 
18 /** @ingroup sensortools
19  Enables the resolution of analog inputs to be increased by oversampling and decimation.
20  Noise should be added to the input before it's digitised, then a succession of input readings are summed and
21  finally divided to give a number with greater resolution than the ADC.
22  Often, noise in the Arduino system will be enough, but there are other practical methods described in
23  [Enhancing ADC Resolution by Oversampling](http://www.atmel.com/images/doc8003.pdf‎),
24  as well as an explanation of the overall approach.
25  @tparam RESOLUTION_INCREASE_BITS how many extra bits of resolution to produce.
26  The window length and the memory it needs increases quickly as the oversampling resolution increases.
27  1 bit = 4 unsigned ints (analog input between 0-1023) = 8 uint8_ts,
28  2 bits = 16 unsigned ints = 32 uint8_ts,
29  3 bits = 64 unsigned ints = 128 uint8_ts,
30  More than 3 bits increase in resolution would require either using longs to store the readings,
31  which would need 1024 uint8_ts for a 4 bit increase and 4096 uint8_ts for 5 bits (do any avr's have that much room?),
32  or the average reading would have to be no more than 128 (for 4 bits increase), because 256 readings would be needed,
33  and the sum of all 256 readings would have to fit into an int. (32767 / 256 = 128).
34  Changing OverSample to use unsigned ints could enable an average reading of 256, but isn't tested properly yet.
35  @note The higher the resolution, the more lag there will be.
36  It's almost a RollingAverage filter, with the difference that
37  OverSample doesn't divide by as much as you would for an average.
38 */
39 
40 
41 template <class T, const uint8_t RESOLUTION_INCREASE_BITS>
43 {
44 
45 public:
46  using RollingAverage<T, (1<<(RESOLUTION_INCREASE_BITS*2))>::add;
47 
48  /** Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;
49  @param input an analog input to oversample.
50  @return the higher resolution result.
51  @note timing 5.7us
52  */
53  T next(T input)
54  {
55  return add(input)>>RESOLUTION_INCREASE_BITS;
56  }
57 
58 };
59 
60 
61 /**
62 @example 05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino
63 This is an example demonstrating the OverSample class.
64 */
65 
66 #endif // #ifndef OVERSAMPLE_H
T next(T input)
Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;.
Definition: OverSample.h:53
+
Enables the resolution of analog inputs to be increased by oversampling and decimation.
Definition: OverSample.h:42
-
1 /*
2  * PDResonant.h
3  *
4  * This implementation copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 
13 
14 #include <mozzi_midi.h>
15 #include <ADSR.h>
16 #include <Oscil.h>
17 #include <Phasor.h>
18 // wavetable for oscillator:
19 #include <tables/sin2048_int8.h>
20 
21 /**
22  PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on
23  https://en.wikipedia.org/wiki/Phase_distortion_synthesis.
24 
25  The class shows how the Mozzi Phasor class
26  can be used to generate an index into a wavetable, and an ADSR
27  is used to modulate the effect by modifying the Phasor frequency and sync.
28  More complex phase distortion effects could be developed by using
29  precalculated tables, or calcuating tables on the fly using a double buffer,
30  or a line-breakpoint model, a sort of hybridPhasor-Line object.
31 */
32 
34 {
35 
36 public:
37 
38  /** Constructor.
39  */
41  PDM_SCALE(0.05)
42  {
43  aOsc.setTable(SIN2048_DATA);
44  aAmpEnv.setADLevels(255, 255);
45  aAmpEnv.setTimes(50, 300, 60000, 1000);
46  kResonantFreqEnv.setADLevels(255,100);
47  }
48 
49  /** Play a note in response to midi input. Params copied from MIDI library HandleNoteOn().
50  @param channel is the midi channel
51  @param pitch is the midi note
52  @param velocity you know what it is
53  */
54  void noteOn(byte channel, byte pitch, byte velocity)
55  {
56  kResonantFreqEnv.noteOn();
57  aAmpEnv.noteOn();
58  freq = mtof(pitch);
59  aBaseCounter.setFreq(freq); // gets modulated in updateControl()
60  aResonanceFreqCounter.setFreq(freq);
61  }
62 
63 
64  /** Stop a note in response to midi input. Params copied from MIDI library HandleNoteOff()
65  @param channel is the midi channel
66  @param pitch is the midi note
67  @param velocity you know what it is
68  */
69  void noteOff(byte channel, byte pitch, byte velocity)
70  {
71  aAmpEnv.noteOff();
72  kResonantFreqEnv.noteOff();
73  }
74 
75 
76  /** Set the resonant filter sweep parameters.
77  @param attack ADSR attack
78  @param decay ADSR decay
79  */
80  void setPDEnv(int attack, int decay)
81  {
82  // sustain and release timesare hardcoded here but don't need to be
83  kResonantFreqEnv.setTimes(attack, decay, 60000, 1000);
84  kResonantFreqEnv.update();
85 
86  float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
87  aResonanceFreqCounter.setFreq(resonance_freq);
88  }
89 
90 
91  /** Update the filter sweep. Use this in updateControl().
92  */
93  void update()
94  {
95  aAmpEnv.update();
96  kResonantFreqEnv.update();
97  // change freq of resonant freq counter, following the envelope
98  float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
99  aResonanceFreqCounter.setFreq(resonance_freq);
100  }
101 
102  /** Produce the audio output. This goes in updateAudio().
103  */
104  int next()
105  {
106  static byte previous_base_counter;
107  byte base_counter = aBaseCounter.next()>>24;
108 
109  // reset resonance counter (wiki b.)
110  if (base_counter<previous_base_counter) aResonanceFreqCounter.set(0);
111  previous_base_counter= base_counter;
112 
113  // index (phase) needs to end up as 11bit to match 2048 wavetable size
114  unsigned int index = aResonanceFreqCounter.next()>>21; // 11 bits fits 2048 cell sin table
115 
116  // amp ramp smooths the jump when aResonanceFreqCounter is reset (wiki d.)
117  byte amp_ramp = 255-base_counter;
118 
119  // wiki e., with amp envelope added
120  return ((long)aAmpEnv.next() * amp_ramp * aOsc.atIndex(index))>>16;
121 
122  // return ((index>>3)*amp_ramp)>>8; // this also sounds good - squelchy sawtooth
123  }
124 
125 
126 private:
127  const float PDM_SCALE;
128  byte amp;
129  int freq;
130 
131  Phasor <AUDIO_RATE> aBaseCounter;
132  Phasor <AUDIO_RATE> aResonanceFreqCounter;
133 
134  Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aOsc;
135  ADSR <CONTROL_RATE, AUDIO_RATE> aAmpEnv;
136  ADSR <CONTROL_RATE, CONTROL_RATE> kResonantFreqEnv;
137 
138 };
int next()
Produce the audio output.
Definition: PDResonant.h:104
-
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:62
+
1 /*
2  * PDResonant.h
3  *
4  * This implementation copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 
13 
14 #include <mozzi_midi.h>
15 #include <ADSR.h>
16 #include <Oscil.h>
17 #include <Phasor.h>
18 // wavetable for oscillator:
19 #include <tables/sin2048_int8.h>
20 
21 /**
22  PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on
23  https://en.wikipedia.org/wiki/Phase_distortion_synthesis.
24 
25  The class shows how the Mozzi Phasor class
26  can be used to generate an index into a wavetable, and an ADSR
27  is used to modulate the effect by modifying the Phasor frequency and sync.
28  More complex phase distortion effects could be developed by using
29  precalculated tables, or calcuating tables on the fly using a double buffer,
30  or a line-breakpoint model, a sort of hybridPhasor-Line object.
31 */
32 
34 {
35 
36 public:
37 
38  /** Constructor.
39  */
41  PDM_SCALE(0.05)
42  {
43  aOsc.setTable(SIN2048_DATA);
44  aAmpEnv.setADLevels(255, 255);
45  aAmpEnv.setTimes(50, 300, 60000, 1000);
46  kResonantFreqEnv.setADLevels(255,100);
47  }
48 
49  /** Play a note in response to midi input. Params copied from MIDI library HandleNoteOn().
50  @param channel is the midi channel
51  @param pitch is the midi note
52  @param velocity you know what it is
53  */
54  void noteOn(byte channel, byte pitch, byte velocity)
55  {
56  kResonantFreqEnv.noteOn();
57  aAmpEnv.noteOn();
58  freq = mtof(pitch);
59  aBaseCounter.setFreq(freq); // gets modulated in updateControl()
60  aResonanceFreqCounter.setFreq(freq);
61  }
62 
63 
64  /** Stop a note in response to midi input. Params copied from MIDI library HandleNoteOff()
65  @param channel is the midi channel
66  @param pitch is the midi note
67  @param velocity you know what it is
68  */
69  void noteOff(byte channel, byte pitch, byte velocity)
70  {
71  aAmpEnv.noteOff();
72  kResonantFreqEnv.noteOff();
73  }
74 
75 
76  /** Set the resonant filter sweep parameters.
77  @param attack ADSR attack
78  @param decay ADSR decay
79  */
80  void setPDEnv(int attack, int decay)
81  {
82  // sustain and release timesare hardcoded here but don't need to be
83  kResonantFreqEnv.setTimes(attack, decay, 60000, 1000);
84  kResonantFreqEnv.update();
85 
86  float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
87  aResonanceFreqCounter.setFreq(resonance_freq);
88  }
89 
90 
91  /** Update the filter sweep. Use this in updateControl().
92  */
93  void update()
94  {
95  aAmpEnv.update();
96  kResonantFreqEnv.update();
97  // change freq of resonant freq counter, following the envelope
98  float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
99  aResonanceFreqCounter.setFreq(resonance_freq);
100  }
101 
102  /** Produce the audio output. This goes in updateAudio().
103  */
104  int next()
105  {
106  static byte previous_base_counter;
107  byte base_counter = aBaseCounter.next()>>24;
108 
109  // reset resonance counter (wiki b.)
110  if (base_counter<previous_base_counter) aResonanceFreqCounter.set(0);
111  previous_base_counter= base_counter;
112 
113  // index (phase) needs to end up as 11bit to match 2048 wavetable size
114  unsigned int index = aResonanceFreqCounter.next()>>21; // 11 bits fits 2048 cell sin table
115 
116  // amp ramp smooths the jump when aResonanceFreqCounter is reset (wiki d.)
117  byte amp_ramp = 255-base_counter;
118 
119  // wiki e., with amp envelope added
120  return ((long)aAmpEnv.next() * amp_ramp * aOsc.atIndex(index))>>16;
121 
122  // return ((index>>3)*amp_ramp)>>8; // this also sounds good - squelchy sawtooth
123  }
124 
125 
126 private:
127  const float PDM_SCALE;
128  byte amp;
129  int freq;
130 
131  Phasor <MOZZI_AUDIO_RATE> aBaseCounter;
132  Phasor <MOZZI_AUDIO_RATE> aResonanceFreqCounter;
133 
134  Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aOsc;
136  ADSR <MOZZI_CONTROL_RATE, MOZZI_CONTROL_RATE> kResonantFreqEnv;
137 
138 };
#define MOZZI_CONTROL_RATE
Control rate setting.
+
int next()
Produce the audio output.
Definition: PDResonant.h:104
PDResonant()
Constructor.
Definition: PDResonant.h:40
-
#define AUDIO_RATE
Holds the audio rate setting.
Definition: mozzi_config.h:62
void update()
Update the filter sweep.
Definition: PDResonant.h:93
PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter...
Definition: PDResonant.h:33
void noteOn(byte channel, byte pitch, byte velocity)
Play a note in response to midi input.
Definition: PDResonant.h:54
-
Phasor repeatedly generates a high resolution ramp at a variable frequency.
Definition: Phasor.h:32
void setPDEnv(int attack, int decay)
Set the resonant filter sweep parameters.
Definition: PDResonant.h:80
void noteOff(byte channel, byte pitch, byte velocity)
Stop a note in response to midi input.
Definition: PDResonant.h:69
@@ -119,7 +117,7 @@
-
1 /*
2  * Phasor.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef PHASOR_H_
13 #define PHASOR_H_
14 
15 #if ARDUINO >= 100
16  #include "Arduino.h"
17 #else
18  #include "WProgram.h"
19 #endif
20 #include "mozzi_fixmath.h"
21 
22 #define PHASOR_MAX_VALUE_UL 4294967295UL
23 
24 /** Phasor repeatedly generates a high resolution ramp at a variable frequency.
25 The output of Phasor.next() is an unsigned number between 0 and 4294967295, the
26 maximum that can be expressed by an unsigned 32 bit integer.
27 @tparam UPDATE_RATE the rate at which the Phasor will be updated,
28 usually CONTROL_RATE or AUDIO_RATE.
29 */
30 
31 template <unsigned int UPDATE_RATE>
32 class Phasor
33 {
34 private:
35  uint32_t current_value;
36  volatile uint32_t step_size;
37 
38 public:
39  /** Constructor. "Phasor <AUDIO_RATE> myphasor;"
40  makes a Phasor which updates at AUDIO_RATE.
41  */
42  Phasor (){
43  ;
44  }
45 
46  /** Increments one step along the phase.
47  @return the next value.
48  */
49  inline
51  {
52  current_value += step_size; // will wrap
53  return current_value;
54  }
55 
56  /** Set the current value of the phasor. The Phasor will continue incrementing from this
57  value using any previously calculated step size.
58  */
59  inline
60  void set(uint32_t value)
61  {
62  current_value=value;
63  }
64 
65 
66  /** Set the Phasor frequency with an unsigned int.
67  @param frequency is how many times per second to count from
68  0 to the maximum uint32_t value 4294967295.
69  @note Timing 8us
70  */
71  inline
72  void setFreq( int frequency)
73  {
74  step_size = ((((uint32_t)((PHASOR_MAX_VALUE_UL>>8)+1))/(UPDATE_RATE))*frequency)<<8;
75  }
76 
77 
78  /** Set the Phasor frequency with a float.
79  @param frequency is how many times per second to count from
80  0 to the maximum uint32_t value 4294967295.
81  */
82  inline
83  void setFreq(float frequency)
84  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
85  step_size = (uint32_t)(((float)PHASOR_MAX_VALUE_UL/UPDATE_RATE)*frequency);
86  }
87 
88  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
89  Instead of recalculating the phase increment for each frequency in between, you
90  can just calculate the phase increment for each end frequency with
91  phaseIncFromFreq(), then use a Line to interpolate on the fly and use
92  setPhaseInc() to set the phase increment at each step. (Note: I should really
93  profile this with the oscilloscope to see if it's worth the extra confusion!)
94  @param frequency for which you want to calculate a phase increment value.
95  @return the phase increment value which will produce a given frequency.
96  */
97  inline
99  {
100  return ((((uint32_t)((PHASOR_MAX_VALUE_UL>>8)+1))/(UPDATE_RATE))*frequency)<<8;
101  }
102 
103 
104  /** Set a specific phase increment. See phaseIncFromFreq().
105  @param stepsize a phase increment value as calculated by phaseIncFromFreq().
106  */
107  inline
108  void setPhaseInc(uint32_t stepsize)
109  {
110  step_size = stepsize;
111  }
112 
113 };
114 
115 /**
116 @example 06.Synthesis/PWM_Phasing/PWM_Phasing.ino
117 This example demonstrates the Phasor class.
118 */
119 
120 #endif /* PHASOR_H_ */
void set(uint32_t value)
Set the current value of the phasor.
Definition: Phasor.h:60
-
void setFreq(int frequency)
Set the Phasor frequency with an unsigned int.
Definition: Phasor.h:72
-
Phasor()
Constructor.
Definition: Phasor.h:42
-
void setFreq(float frequency)
Set the Phasor frequency with a float.
Definition: Phasor.h:83
-
#define PHASOR_MAX_VALUE_UL
Definition: Phasor.h:22
-
uint32_t phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: Phasor.h:98
-
uint32_t next()
Increments one step along the phase.
Definition: Phasor.h:50
-
Phasor repeatedly generates a high resolution ramp at a variable frequency.
Definition: Phasor.h:32
-
void setPhaseInc(uint32_t stepsize)
Set a specific phase increment.
Definition: Phasor.h:108
+
1 /*
2  * Phasor.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef PHASOR_H_
13 #define PHASOR_H_
14 
15 #include "Arduino.h"
16 #include "mozzi_fixmath.h"
17 
18 #define PHASOR_MAX_VALUE_UL 4294967295UL
19 
20 /** Phasor repeatedly generates a high resolution ramp at a variable frequency.
21 The output of Phasor.next() is an unsigned number between 0 and 4294967295, the
22 maximum that can be expressed by an unsigned 32 bit integer.
23 @tparam UPDATE_RATE the rate at which the Phasor will be updated,
24 usually MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE.
25 */
26 
27 template <unsigned int UPDATE_RATE>
28 class Phasor
29 {
30 private:
31  uint32_t current_value;
32  volatile uint32_t step_size;
33 
34 public:
35  /** Constructor. "Phasor <MOZZI_AUDIO_RATE> myphasor;"
36  makes a Phasor which updates at MOZZI_AUDIO_RATE.
37  */
38  Phasor (){
39  ;
40  }
41 
42  /** Increments one step along the phase.
43  @return the next value.
44  */
45  inline
47  {
48  current_value += step_size; // will wrap
49  return current_value;
50  }
51 
52  /** Set the current value of the phasor. The Phasor will continue incrementing from this
53  value using any previously calculated step size.
54  */
55  inline
56  void set(uint32_t value)
57  {
58  current_value=value;
59  }
60 
61 
62  /** Set the Phasor frequency with an unsigned int.
63  @param frequency is how many times per second to count from
64  0 to the maximum uint32_t value 4294967295.
65  @note Timing 8us
66  */
67  inline
68  void setFreq( int frequency)
69  {
70  step_size = ((((uint32_t)((PHASOR_MAX_VALUE_UL>>8)+1))/(UPDATE_RATE))*frequency)<<8;
71  }
72 
73 
74  /** Set the Phasor frequency with a float.
75  @param frequency is how many times per second to count from
76  0 to the maximum uint32_t value 4294967295.
77  */
78  inline
79  void setFreq(float frequency)
80  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
81  step_size = (uint32_t)(((float)PHASOR_MAX_VALUE_UL/UPDATE_RATE)*frequency);
82  }
83 
84  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
85  Instead of recalculating the phase increment for each frequency in between, you
86  can just calculate the phase increment for each end frequency with
87  phaseIncFromFreq(), then use a Line to interpolate on the fly and use
88  setPhaseInc() to set the phase increment at each step. (Note: I should really
89  profile this with the oscilloscope to see if it's worth the extra confusion!)
90  @param frequency for which you want to calculate a phase increment value.
91  @return the phase increment value which will produce a given frequency.
92  */
93  inline
95  {
96  return ((((uint32_t)((PHASOR_MAX_VALUE_UL>>8)+1))/(UPDATE_RATE))*frequency)<<8;
97  }
98 
99 
100  /** Set a specific phase increment. See phaseIncFromFreq().
101  @param stepsize a phase increment value as calculated by phaseIncFromFreq().
102  */
103  inline
104  void setPhaseInc(uint32_t stepsize)
105  {
106  step_size = stepsize;
107  }
108 
109 };
110 
111 /**
112 @example 06.Synthesis/PWM_Phasing/PWM_Phasing.ino
113 This example demonstrates the Phasor class.
114 */
115 
116 #endif /* PHASOR_H_ */
void set(uint32_t value)
Set the current value of the phasor.
Definition: Phasor.h:56
+
void setFreq(int frequency)
Set the Phasor frequency with an unsigned int.
Definition: Phasor.h:68
+
Phasor()
Constructor.
Definition: Phasor.h:38
+
void setFreq(float frequency)
Set the Phasor frequency with a float.
Definition: Phasor.h:79
+
#define PHASOR_MAX_VALUE_UL
Definition: Phasor.h:18
+
uint32_t phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: Phasor.h:94
+
uint32_t next()
Increments one step along the phase.
Definition: Phasor.h:46
+
Phasor repeatedly generates a high resolution ramp at a variable frequency.
Definition: Phasor.h:28
+
void setPhaseInc(uint32_t stepsize)
Set a specific phase increment.
Definition: Phasor.h:104
-
1 /*
2  * Portamento.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef PORTAMENTO_H_
13 #define PORTAMENTO_H_
14 
15 #include "mozzi_midi.h"
16 #include "mozzi_fixmath.h"
17 #include "Line.h"
18 
19 /** A simple portamento (pitch slide from one note to the next) effect, useful for note-based applications.
20 */
21 template <unsigned int CONTROL_UPDATE_RATE>
22 class
23  Portamento {
24 
25 public:
26 
27  /** Constructor.
28  */
30  MICROS_PER_CONTROL_STEP(1000000/CONTROL_UPDATE_RATE)
31  {
32  }
33 
34  /** Set how long it will take to slide from note to note, in milliseconds.
35  @param milliseconds
36  */
37  inline
38  void setTime(unsigned int milliseconds){
39  //control_steps_per_portamento = ((long)milliseconds*1000)/MICROS_PER_CONTROL_STEP; // more accurate but slower
40  control_steps_per_portamento = convertMsecToControlSteps(milliseconds);
41  }
42 
43  /** Call this at note-on, it initialises the portamento.
44  @param note a midi note number, a whole number.
45  */
46  inline
47  void start(uint8_t note) {
48  target_freq = Q16n16_mtof(Q8n0_to_Q16n16(note));
49  aPortamentoLine.set(target_freq, control_steps_per_portamento);
50  countdown = control_steps_per_portamento;
51  portamento_on=true;
52  }
53 
54  /** Call this at note-on, it initialises the portamento.
55  @param note a midi note number in Q16n16 fractional format. This is useful for non-whole note or detuned values.
56  */
57  inline
58  void start(Q16n16 note) {
59  target_freq = Q16n16_mtof(note);
60  aPortamentoLine.set(target_freq, control_steps_per_portamento);
61  countdown = control_steps_per_portamento;
62  portamento_on=true;
63  }
64 
65 
66  /** Use this in updateControl() to provide a frequency to the oscillator it's controlling.
67  For example:
68  myOscil.setFreq_Q16n16(myPortamento.next());
69  @return a Q16n16 fractional frequency value, progressing smoothly between successive notes.
70  */
71  inline
73  if (portamento_on==true){
74  if(--countdown < 0) {
75  // stay level when portamento has finished
76  aPortamentoLine.set(target_freq, target_freq, control_steps_per_portamento);
77  portamento_on=false;
78  }
79  }
80  return aPortamentoLine.next();
81  }
82 
83  private:
84 
85  int countdown;
86  int control_steps_per_portamento;
87  Q16n16 target_freq;
88  bool portamento_on;
89  const unsigned int MICROS_PER_CONTROL_STEP;
90  Line <Q16n16> aPortamentoLine;
91 
92 
93  // copied from ADSR.h
94  inline
95  static const unsigned int convertMsecToControlSteps(unsigned int msec){
96  return (uint16_t) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
97  }
98 
99 };
100 
101 /**
102 @example 05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino
103 This example demonstrates the Portamento class.
104 */
105 
106 #endif /* PORTAMENTO_H_ */
Q16n16 Q16n16_mtof(Q16n16 midival)
Converts midi note number to frequency with speed and accuracy.
Definition: mozzi_midi.cpp:132
-
A simple portamento (pitch slide from one note to the next) effect, useful for note-based application...
Definition: Portamento.h:22
+
1 /*
2  * Portamento.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef PORTAMENTO_H_
13 #define PORTAMENTO_H_
14 
15 #include "mozzi_midi.h"
16 #include "mozzi_fixmath.h"
17 #include "Line.h"
18 
19 /** A simple portamento (pitch slide from one note to the next) effect, useful for note-based applications.
20 */
21 template <unsigned int CONTROL_UPDATE_RATE>
22 class
23  Portamento {
24 
25 public:
26 
27  /** Constructor.
28  */
30  MICROS_PER_CONTROL_STEP(1000000/CONTROL_UPDATE_RATE)
31  {
32  }
33 
34  /** Set how long it will take to slide from note to note, in milliseconds.
35  @param milliseconds
36  */
37  inline
38  void setTime(unsigned int milliseconds){
39  //control_steps_per_portamento = ((long)milliseconds*1000)/MICROS_PER_CONTROL_STEP; // more accurate but slower
40  control_steps_per_portamento = convertMsecToControlSteps(milliseconds);
41  }
42 
43  /** Call this at note-on, it initialises the portamento.
44  @param note a midi note number, a whole number.
45  */
46  inline
47  void start(uint8_t note) {
48  target_freq = Q16n16_mtof(Q8n0_to_Q16n16(note));
49  aPortamentoLine.set(target_freq, control_steps_per_portamento);
50  countdown = control_steps_per_portamento;
51  portamento_on=true;
52  }
53 
54  /** Call this at note-on, it initialises the portamento.
55  @param note a midi note number in Q16n16 fractional format. This is useful for non-whole note or detuned values.
56  */
57  inline
58  void start(Q16n16 note) {
59  target_freq = Q16n16_mtof(note);
60  aPortamentoLine.set(target_freq, control_steps_per_portamento);
61  countdown = control_steps_per_portamento;
62  portamento_on=true;
63  }
64 
65 
66  /** Use this in updateControl() to provide a frequency to the oscillator it's controlling.
67  For example:
68  myOscil.setFreq_Q16n16(myPortamento.next());
69  @return a Q16n16 fractional frequency value, progressing smoothly between successive notes.
70  */
71  inline
73  if (portamento_on==true){
74  if(--countdown < 0) {
75  // stay level when portamento has finished
76  aPortamentoLine.set(target_freq, target_freq, control_steps_per_portamento);
77  portamento_on=false;
78  }
79  }
80  return aPortamentoLine.next();
81  }
82 
83  private:
84 
85  int countdown;
86  int control_steps_per_portamento;
87  Q16n16 target_freq;
88  bool portamento_on;
89  const unsigned int MICROS_PER_CONTROL_STEP;
90  Line <Q16n16> aPortamentoLine;
91 
92 
93  // copied from ADSR.h
94  inline
95  static const unsigned int convertMsecToControlSteps(unsigned int msec){
96  return (uint16_t) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
97  }
98 
99 };
100 
101 /**
102 @example 05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino
103 This example demonstrates the Portamento class.
104 */
105 
106 #endif /* PORTAMENTO_H_ */
Q16n16 Q16n16_mtof(Q16n16 midival_fractional)
Converts midi note number to frequency with speed and accuracy.
Definition: mozzi_midi.h:97
void setTime(unsigned int milliseconds)
Set how long it will take to slide from note to note, in milliseconds.
Definition: Portamento.h:38
void start(Q16n16 note)
Call this at note-on, it initialises the portamento.
Definition: Portamento.h:58
-
For linear changes with a minimum of calculation at each step.
Definition: Line.h:37
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46
+
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:44
Q16n16 next()
Use this in updateControl() to provide a frequency to the oscillator it&#39;s controlling.
Definition: Portamento.h:72
Portamento()
Constructor.
Definition: Portamento.h:29
@@ -117,7 +115,7 @@
-
1 /*
2  * ResonantFilter.h
3  *
4  * Copyright 2012 Tim Barrass
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #ifndef RESONANTFILTER_H_
14 #define RESONANTFILTER_H_
15 
16 #include "IntegerType.h"
17 #include "AudioOutput.h"
18 #include "meta.h"
19 
20 
21 
22 /*
23 simple resonant filter posted to musicdsp.org by Paul Kellett
24 http://www.musicdsp.org/archive.php?classid=3#259, applying the
25 modification from Peter Schoffhauzer to make it able to output
26 all filter types (LowPass, HighPass, Notch and BandPass).
27 
28 The generic filter is ResonantFilter<unsigned_t type, FILTER_TYPE>.
29  - type specifies the type expected for the cutoff and resonance. Only uint8_t and uint16_t have been tested. These are denoted 8bits and 16bits versions of the filter in the following.
30  - FILTER_TYPE specifies the filter type. LOWPASS, BANDPASS, HIGHPASS and NOTCH are available types.
31 
32 Two versions are available: the 8bits and 16bits versions (see above).
33 The 8bits version is an optimized version that uses 8bits values to set
34 the resonance and the cutoff_freq. It can works on 8bits samples only
35 on 8bits platforms.
36 The 16bits version consumes more CPU ressources but uses 16bits values
37 for resonance and cutoff_freq and can work on samples up to 16bits on
38 8bits platforms and up to 32 on 32bits platforms.
39 
40 The filter can be instanciated using the template version ResonantFilter<unsigned_t type, FILTER_TYPE>. For ease of use, the following types are also accepted:
41 
42 8bits versions: LowPassFilter, HighPassFilter, BandPassFilter, NotchFilter
43 16bits versions: LowPassFilter16, HighPassFilter16, BandPassFilter16, NotchFilter16
44 
45 
46 
47 //// ALGORITHM ////
48 // set feedback amount given f and q between 0 and 1
49 fb = q + q/(1.0 - f);
50 In order to avoid a slow division we use the use a Taylor expansion to approximate 1/(1.0 - f):
51 Close to f=0: 1/(1.0-f) approx 1.0+f.
52 Hence: fb = q + q * (1.0 + f)
53 This approximation is less and less valid with an increasing cutoff, leading to a reduction of the resonance of the filter at high cutoff frequencies.
54 
55 // for each sample...
56 buf0 = buf0 + f * (in - buf0 + fb * (buf0 - buf1));
57 buf1 = buf1 + f * (buf0 - buf1);
58 out = buf1; // LowPass
59 out = in - buf0; // HighPass
60 out = buf0 - buf1; // BandPass
61 out = in - buf0 + buf1; // Notch
62 
63 fixed point version of the filter
64 "dave's blog of art and programming" http://www.pawfal.org/dave/blog/2011/09/
65 */
66 
67 
68 
69 
70 
71 enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
72 
73 /** A generic resonant filter for audio signals.
74  */
75 template<int8_t FILTER_TYPE, typename su=uint8_t>
77 {
78 
79 public:
80  /** Constructor.
81  */
83 
84 
85  /** deprecated. Use setCutoffFreqAndResonance(su cutoff, su
86  resonance).
87 
88  Set the cut off frequency,
89  @param cutoff use the range 0-255 to represent 0-8191 Hz (AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-AUDIO_RATE/2.
90  Be careful of distortion at the lower end, especially with high resonance.
91  */
92  void setCutoffFreq(su cutoff)
93  {
94  f = cutoff;
95  fb = q + ucfxmul(q, (typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type) SHIFTED_1 + cutoff);
96  }
97 
98  /** deprecated. Use setCutoffFreqAndResonance(su cutoff, su
99  resonance).
100 
101  Set the resonance. If you hear unwanted distortion, back off the resonance.
102  After setting resonance, you need to call setCuttoffFreq() to hear the change!
103  @param resonance in the range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, with 255/65535 being most resonant
104  @note Remember to call setCuttoffFreq() after resonance is changed!
105  */
106  void setResonance(su resonance) { q = resonance; }
107 
108  /**
109  Set the cut off frequency and resonance. Replaces setCutoffFreq() and
110  setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)
111  @param cutoff range 0-255 represents 0-8191 Hz (AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16
112  Be careful of distortion at the lower end, especially with high resonance.
113  @param resonance range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
114  */
115  void setCutoffFreqAndResonance(su cutoff, su resonance)
116  {
117  f = cutoff;
118  q = resonance; // hopefully optimised away when compiled, just here for
119  // backwards compatibility
120  fb = q + ucfxmul(q,(typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type) SHIFTED_1 + cutoff);
121  }
122 
123  /** Calculate the next sample, given an input signal.
124  @param in the signal input. Should not be more than 8bits on 8bits platforms (Arduino) if using the 8bits version and not 16bits version.
125  @return the signal output.
126  @note Timing: about 11us.
127  */
128  // 10.5 to 12.5 us, mostly 10.5 us (was 14us)
130  {
131  advanceBuffers(in);
132  return current(in, Int2Type<FILTER_TYPE>());
133  }
134 
135 protected:
136  su q;
137  su f;
138  typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type fb;
139  AudioOutputStorage_t buf0, buf1;
140  const uint8_t FX_SHIFT = sizeof(su) << 3;
141  const uint8_t FX_SHIFT_M_1 = FX_SHIFT-1;
142  const su SHIFTED_1 = (1<<FX_SHIFT)-1;
143 
144  // // multiply two fixed point numbers (returns fixed point)
145  // inline
146  // long fxmul(long a, long b)
147  // {
148  // return (a*b)>>FX_SHIFT;
149  // }
150 
151  inline void advanceBuffers(AudioOutputStorage_t in)
152  {
153  buf0 += fxmul(((in - buf0) + fxmul(fb, buf0 - buf1)), f);
154  buf1 += ifxmul(buf0 - buf1, f); // could overflow if input changes fast
155  }
156 
157  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<LOWPASS>) {return buf1;}
158 
159  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<HIGHPASS>) {return in - buf0;}
160 
161  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<BANDPASS>) {return buf0-buf1;}
162 
163  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<NOTCH>) {return in - buf0 + buf1;}
164 
165  // multiply two fixed point numbers (returns fixed point)
166  inline typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type ucfxmul(su a, typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type b)
167  {
168  return (((typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type)a * (b >> 1)) >> (FX_SHIFT_M_1));
169  }
170 
171  // multiply two fixed point numbers (returns fixed point)
172  inline typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(su)-1>::signed_type ifxmul(typename IntegerType<sizeof(AudioOutputStorage_t )+sizeof(su)-1>::signed_type a, su b) { return ((a * b) >> FX_SHIFT); }
173 
174  // multiply two fixed point numbers (returns fixed point)
175  inline typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type fxmul(typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(su)-1>::signed_type b) { return ((a * b) >> FX_SHIFT); }
176 };
177 
178 /** A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime.
179 Behaves like ResonantFilter for setting the resonance and cutoff frequency.
180 Like ResonantFilter, it can be used on different sample sizes: MultiResonantFilter<uint8_t> and MultiResonantFilter<uint16_t> have been tested.
181 For the former, both cutoff and resonance are uint8_t, hence between 0-255.
182 For the later, both cutoff and resonance are uint16_t, hence between 0-65535.
183  */
184 template<typename su=uint8_t>
185 class MultiResonantFilter: public ResonantFilter<LOWPASS,su>
186 {
187 public:
188  /** Compute the filters, given an input signal.
189  @param in the signal input. Should not be more than 8bits on 8bits platforms (Arduino) if using the 8bits version and not 16bits version.
190  */
191 inline void next (AudioOutputStorage_t in)
192  {
193  last_in = in;
194  ResonantFilter<LOWPASS,su>::advanceBuffers(in);
195  }
196  /** Return the input filtered with a lowpass filter
197  @return the filtered signal output.
198  */
199  inline AudioOutputStorage_t low() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<LOWPASS>());}
200  /** Return the input filtered with a highpass filter
201  @return the filtered signal output.
202  */
203  inline AudioOutputStorage_t high() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<HIGHPASS>());}
204  /** Return the input filtered with a bandpass filter
205  @return the filtered signal output.
206  */
207  inline AudioOutputStorage_t band() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<BANDPASS>());}
208  /** Return the input filtered with a notch filter
209  @return the filtered signal output.
210  */
211  inline AudioOutputStorage_t notch() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<NOTCH>());}
212 
213 private:
214  AudioOutputStorage_t last_in;
215 };
216 
217 
218 typedef ResonantFilter<LOWPASS> LowPassFilter;
219 typedef ResonantFilter<LOWPASS, uint16_t> LowPassFilter16;
220 /*
221 typedef ResonantFilter<uint8_t, HIGHPASS> HighPassFilter;
222 typedef ResonantFilter<uint16_t, HIGHPASS> HighPassFilter16;
223 typedef ResonantFilter<uint8_t, BANDPASS> BandPassFilter;
224 typedef ResonantFilter<uint16_t, BANDPASS> BandPassFilter16;
225 typedef ResonantFilter<uint8_t, NOTCH> NotchFilter;
226 typedef ResonantFilter<uint16_t, NOTCH> NotchFilter16;
227 */
228 
229 
230 /**
231 @example 10.Audio_Filters/ResonantFilter/ResonantFilter.ino
232 This example demonstrates the ResonantFilter specification of this class.
233 
234 @example 10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino
235 This example demonstrates the ResonantFilter16 specification of this class.
236 
237 @example 10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino
238 This example demonstrates the MultiResonantFilter specification of this class.
239 */
240 
241 #endif /* RESONANTFILTER_H_ */
void setCutoffFreqAndResonance(su cutoff, su resonance)
Set the cut off frequency and resonance.
+
1 /*
2  * ResonantFilter.h
3  *
4  * Copyright 2012 Tim Barrass
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #ifndef RESONANTFILTER_H_
14 #define RESONANTFILTER_H_
15 
16 #include "IntegerType.h"
17 #include "AudioOutput.h"
18 #include "meta.h"
19 
20 
21 
22 /*
23 simple resonant filter posted to musicdsp.org by Paul Kellett
24 http://www.musicdsp.org/archive.php?classid=3#259, applying the
25 modification from Peter Schoffhauzer to make it able to output
26 all filter types (LowPass, HighPass, Notch and BandPass).
27 
28 The generic filter is ResonantFilter<unsigned_t type, FILTER_TYPE>.
29  - type specifies the type expected for the cutoff and resonance. Only uint8_t and uint16_t have been tested. These are denoted 8bits and 16bits versions of the filter in the following.
30  - FILTER_TYPE specifies the filter type. LOWPASS, BANDPASS, HIGHPASS and NOTCH are available types.
31 
32 Two versions are available: the 8bits and 16bits versions (see above).
33 The 8bits version is an optimized version that uses 8bits values to set
34 the resonance and the cutoff_freq. It can works on 8bits samples only
35 on 8bits platforms.
36 The 16bits version consumes more CPU ressources but uses 16bits values
37 for resonance and cutoff_freq and can work on samples up to 16bits on
38 8bits platforms and up to 32 on 32bits platforms.
39 
40 The filter can be instanciated using the template version ResonantFilter<unsigned_t type, FILTER_TYPE>. For ease of use, the following types are also accepted:
41 
42 8bits versions: LowPassFilter, HighPassFilter, BandPassFilter, NotchFilter
43 16bits versions: LowPassFilter16, HighPassFilter16, BandPassFilter16, NotchFilter16
44 
45 
46 
47 //// ALGORITHM ////
48 // set feedback amount given f and q between 0 and 1
49 fb = q + q/(1.0 - f);
50 In order to avoid a slow division we use the use a Taylor expansion to approximate 1/(1.0 - f):
51 Close to f=0: 1/(1.0-f) approx 1.0+f.
52 Hence: fb = q + q * (1.0 + f)
53 This approximation is less and less valid with an increasing cutoff, leading to a reduction of the resonance of the filter at high cutoff frequencies.
54 
55 // for each sample...
56 buf0 = buf0 + f * (in - buf0 + fb * (buf0 - buf1));
57 buf1 = buf1 + f * (buf0 - buf1);
58 out = buf1; // LowPass
59 out = in - buf0; // HighPass
60 out = buf0 - buf1; // BandPass
61 out = in - buf0 + buf1; // Notch
62 
63 fixed point version of the filter
64 "dave's blog of art and programming" http://www.pawfal.org/dave/blog/2011/09/
65 */
66 
67 
68 
69 
70 
71 enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
72 
73 /** A generic resonant filter for audio signals.
74  */
75 template<int8_t FILTER_TYPE, typename su=uint8_t>
77 {
78 
79 public:
80  /** Constructor.
81  */
83 
84 
85  /** deprecated. Use setCutoffFreqAndResonance(su cutoff, su
86  resonance).
87 
88  Set the cut off frequency,
89  @param cutoff use the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2.
90  Be careful of distortion at the lower end, especially with high resonance.
91  */
92  void setCutoffFreq(su cutoff)
93  {
94  f = cutoff;
95  fb = q + ucfxmul(q, (typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type) SHIFTED_1 + cutoff);
96  }
97 
98  /** deprecated. Use setCutoffFreqAndResonance(su cutoff, su
99  resonance).
100 
101  Set the resonance. If you hear unwanted distortion, back off the resonance.
102  After setting resonance, you need to call setCuttoffFreq() to hear the change!
103  @param resonance in the range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, with 255/65535 being most resonant
104  @note Remember to call setCuttoffFreq() after resonance is changed!
105  */
106  void setResonance(su resonance) { q = resonance; }
107 
108  /**
109  Set the cut off frequency and resonance. Replaces setCutoffFreq() and
110  setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)
111  @param cutoff range 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16
112  Be careful of distortion at the lower end, especially with high resonance.
113  @param resonance range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
114  */
115  void setCutoffFreqAndResonance(su cutoff, su resonance)
116  {
117  f = cutoff;
118  q = resonance; // hopefully optimised away when compiled, just here for
119  // backwards compatibility
120  fb = q + ucfxmul(q,(typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type) SHIFTED_1 + cutoff);
121  }
122 
123  /** Calculate the next sample, given an input signal.
124  @param in the signal input. Should not be more than 8bits on 8bits platforms (Arduino) if using the 8bits version and not 16bits version.
125  @return the signal output.
126  @note Timing: about 11us.
127  */
128  // 10.5 to 12.5 us, mostly 10.5 us (was 14us)
130  {
131  advanceBuffers(in);
132  return current(in, Int2Type<FILTER_TYPE>());
133  }
134 
135 protected:
136  su q;
137  su f;
138  typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type fb;
139  AudioOutputStorage_t buf0, buf1;
140  const uint8_t FX_SHIFT = sizeof(su) << 3;
141  const uint8_t FX_SHIFT_M_1 = FX_SHIFT-1;
142  const su SHIFTED_1 = (1<<FX_SHIFT)-1;
143 
144  // // multiply two fixed point numbers (returns fixed point)
145  // inline
146  // long fxmul(long a, long b)
147  // {
148  // return (a*b)>>FX_SHIFT;
149  // }
150 
151  inline void advanceBuffers(AudioOutputStorage_t in)
152  {
153  buf0 += fxmul(((in - buf0) + fxmul(fb, buf0 - buf1)), f);
154  buf1 += ifxmul(buf0 - buf1, f); // could overflow if input changes fast
155  }
156 
157  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<LOWPASS>) {return buf1;}
158 
159  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<HIGHPASS>) {return in - buf0;}
160 
161  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<BANDPASS>) {return buf0-buf1;}
162 
163  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<NOTCH>) {return in - buf0 + buf1;}
164 
165  // multiply two fixed point numbers (returns fixed point)
166  inline typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type ucfxmul(su a, typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type b)
167  {
168  return (((typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type)a * (b >> 1)) >> (FX_SHIFT_M_1));
169  }
170 
171  // multiply two fixed point numbers (returns fixed point)
172  inline typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(su)-1>::signed_type ifxmul(typename IntegerType<sizeof(AudioOutputStorage_t )+sizeof(su)-1>::signed_type a, su b) { return ((a * b) >> FX_SHIFT); }
173 
174  // multiply two fixed point numbers (returns fixed point)
175  inline typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type fxmul(typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(su)-1>::signed_type b) { return ((a * b) >> FX_SHIFT); }
176 };
177 
178 /** A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime.
179 Behaves like ResonantFilter for setting the resonance and cutoff frequency.
180 Like ResonantFilter, it can be used on different sample sizes: MultiResonantFilter<uint8_t> and MultiResonantFilter<uint16_t> have been tested.
181 For the former, both cutoff and resonance are uint8_t, hence between 0-255.
182 For the later, both cutoff and resonance are uint16_t, hence between 0-65535.
183  */
184 template<typename su=uint8_t>
185 class MultiResonantFilter: public ResonantFilter<LOWPASS,su>
186 {
187 public:
188  /** Compute the filters, given an input signal.
189  @param in the signal input. Should not be more than 8bits on 8bits platforms (Arduino) if using the 8bits version and not 16bits version.
190  */
191 inline void next (AudioOutputStorage_t in)
192  {
193  last_in = in;
194  ResonantFilter<LOWPASS,su>::advanceBuffers(in);
195  }
196  /** Return the input filtered with a lowpass filter
197  @return the filtered signal output.
198  */
199  inline AudioOutputStorage_t low() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<LOWPASS>());}
200  /** Return the input filtered with a highpass filter
201  @return the filtered signal output.
202  */
203  inline AudioOutputStorage_t high() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<HIGHPASS>());}
204  /** Return the input filtered with a bandpass filter
205  @return the filtered signal output.
206  */
207  inline AudioOutputStorage_t band() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<BANDPASS>());}
208  /** Return the input filtered with a notch filter
209  @return the filtered signal output.
210  */
211  inline AudioOutputStorage_t notch() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<NOTCH>());}
212 
213 private:
214  AudioOutputStorage_t last_in;
215 };
216 
217 
218 typedef ResonantFilter<LOWPASS> LowPassFilter;
219 typedef ResonantFilter<LOWPASS, uint16_t> LowPassFilter16;
220 /*
221 typedef ResonantFilter<uint8_t, HIGHPASS> HighPassFilter;
222 typedef ResonantFilter<uint16_t, HIGHPASS> HighPassFilter16;
223 typedef ResonantFilter<uint8_t, BANDPASS> BandPassFilter;
224 typedef ResonantFilter<uint16_t, BANDPASS> BandPassFilter16;
225 typedef ResonantFilter<uint8_t, NOTCH> NotchFilter;
226 typedef ResonantFilter<uint16_t, NOTCH> NotchFilter16;
227 */
228 
229 
230 /**
231 @example 10.Audio_Filters/ResonantFilter/ResonantFilter.ino
232 This example demonstrates the ResonantFilter specification of this class.
233 
234 @example 10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino
235 This example demonstrates the ResonantFilter16 specification of this class.
236 
237 @example 10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino
238 This example demonstrates the MultiResonantFilter specification of this class.
239 */
240 
241 #endif /* RESONANTFILTER_H_ */
void setCutoffFreqAndResonance(su cutoff, su resonance)
Set the cut off frequency and resonance.
AudioOutputStorage_t next(AudioOutputStorage_t in)
Calculate the next sample, given an input signal.
AudioOutputStorage_t notch()
Return the input filtered with a notch filter.
-
Enables you to instantiate a template based on an integer value.
Definition: meta.h:20
+
Provides appropriate integer types that can bit the given number of bytes on this platform (at most 6...
Definition: IntegerType.h:9
+
Enables you to instantiate a template based on an integer value.
Definition: meta.h:22
void next(AudioOutputStorage_t in)
Compute the filters, given an input signal.
A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at ...
AudioOutputStorage_t low()
Return the input filtered with a lowpass filter.
AudioOutputStorage_t high()
Return the input filtered with a highpass filter.
-
AudioOutputStorage_t band()
Return the input filtered with a bandpass filter.
void setResonance(su resonance)
deprecated.
A generic resonant filter for audio signals.
void setCutoffFreq(su cutoff)
deprecated.
ResonantFilter()
Constructor.
-
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:46
+
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:53
-
1 #ifndef ROLLINGAVERAGE_H
2 #define ROLLINGAVERAGE_H
3 
4 /*
5  * RollingAverage.h
6  *
7  * Copyright 2013 Tim Barrass.
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 /*
15  Draws on Arduino Smoothing example,
16  Created 22 April 2007
17  By David A. Mellis <dam@mellis.org>
18  modified 9 Apr 2012
19  by Tom Igoe
20  http://www.arduino.cc/en/Tutorial/Smoothing
21 */
22 
23 #include "mozzi_utils.h" // for trailingZeros()
24 
25 
26 /** @ingroup sensortools
27  Calculates a running average over a
28  specified number of the most recent readings.
29  Like Smooth(), this is good for smoothing analog inputs in updateControl().
30  @tparam WINDOW_LENGTH the number of readings to include in the rolling average.
31  It must be a power of two (unless you're averaging floats). The higher the
32  number, the more the readings will be smoothed, but the slower the output
33  will respond to the input.
34 */
35 
36 template <class T, int WINDOW_LENGTH>
37 class
39 
40 public:
41 
42  /** Constructor.
43  @tparam T the type of numbers to average, eg. int, unsigned int, float etc. It will be relatively slow with
44  floating point numbers, as it will use a divide operation for the averaging.
45  Nevertheless, there might be a time when it's useful.
46  @tparam WINDOW_LENGTH the number of readings to keep track of. It must be a power of two (unless
47  you're averaging floats). The higher the number, the more the readings will be
48  smoothed, but the slower the output will respond to the input.
49  @note Watch out for overflows!
50  */
52  {
53  // initialize all the readings to 0:
54  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
55  readings[thisReading] = 0;
56  }
57 
58 
59  /** Give the average of the last WINDOW_LENGTH.
60  @param input a control signal such as an analog input which needs smoothing.
61  @return the smoothed result.
62  @note unsigned int timing 5.7us
63  */
64  T next(T input)
65  {
66  return add(input)>>WINDOW_LENGTH_AS_RSHIFT;
67  }
68 
69 
70 protected:
71 
72  inline
73  T add(T input){
74  // out with the old
75  total -= readings[index];
76  // in with the new
77  total += input;
78  readings[index] = input;
79 
80  // advance and wrap index
81  ++index &= WINDOW_LENGTH -1;
82  return total;
83  }
84 
85 
86 private:
87  T readings[WINDOW_LENGTH]; // the readings from the analog input
88  unsigned int index; // the index of the current reading
89  long total; // the running total
90  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
91 
92 };
93 
94 // no need to show the specialisations
95 /** @cond */
96 
97 /** unsigned int partial specialisation of RollingAverage template.
98 This is needed because unsigned types need to remind (unsigned) for rshift.
99 */
100 template <int WINDOW_LENGTH>
101 class RollingAverage <unsigned int, WINDOW_LENGTH>
102 {
103 public:
104  /** Constructor.
105  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
106  The higher the number, the more the readings will be smoothed, but the slower the output will
107  respond to the input.
108  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
109  However, watch out for overflows if you are averaging a long number types!
110  */
111  RollingAverage():index(0),total(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
112  {
113  // initialize all the readings to 0:
114  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
115  readings[thisReading] = 0;
116  }
117 
118  /** Give the average of the last WINDOW_LENGTH.
119  @param a control signal such as an analog input which needs smoothing.
120  @return the smoothed result.
121  @note timing for int 6us
122  */
123  unsigned int next(unsigned int input)
124  {
125  // calculate the average:
126  // this unsigned cast is the only difference between the int and unsigned int specialisations
127  // it tells the shift not to sign extend in from the left
128  return (unsigned)add(input)>>WINDOW_LENGTH_AS_RSHIFT;
129  }
130 
131 protected:
132 
133 
134  inline
135  unsigned int add(unsigned int input){
136  // out with the old
137  total -= readings[index];
138  // in with the new
139  total += input;
140  readings[index] = input;
141 
142  // advance and wrap index
143  ++index &= WINDOW_LENGTH -1;
144  return total;
145  }
146 
147 
148 private:
149  unsigned int readings[WINDOW_LENGTH]; // the readings from the analog input
150  unsigned int index; // the index of the current reading
151  long total; // the running total
152  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
153 
154 };
155 
156 
157 
158 /** float partial specialisation of RollingAverage template*/
159 template <int WINDOW_LENGTH>
160 class RollingAverage <float, WINDOW_LENGTH>
161 {
162 public:
163  /** Constructor.
164  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
165  The higher the number, the more the readings will be smoothed, but the slower the output will
166  respond to the input.
167  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
168  However, watch out for overflows if you are averaging a long number types!
169  */
170  RollingAverage():index(0),total(0.0)
171  {
172  // initialize all the readings to 0:
173  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
174  readings[thisReading] = 0.0;
175  }
176 
177  /** Give the average of the last WINDOW_LENGTH.
178  @param a control signal such as an analog input which needs smoothing.
179  @return the smoothed result.
180  @note timing for float 37us
181  */
182  float next(float input)
183  {
184  // out with the old
185  total -= readings[index];
186  // in with the new
187  total += input;
188  readings[index] = input;
189 
190  // advance and wrap index
191  ++index &= WINDOW_LENGTH -1;
192 
193  // calculate the average:
194  return total/WINDOW_LENGTH;
195  }
196 
197 private:
198  float readings[WINDOW_LENGTH]; // the readings from the analog input
199  unsigned int index; // the index of the current reading
200  float total; // the running total
201 
202 };
203 
204 
205 // no need to show the specialisations
206 /** @endcond
207 */
208 
209 /**
210 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
211 This example demonstrates the RollingAverage class.
212 */
213 
214 #endif // #ifndef ROLLINGAVERAGE_H
Calculates a running average over a specified number of the most recent readings. ...
-
T next(T input)
Give the average of the last WINDOW_LENGTH.
-
RollingAverage()
Constructor.
-
+
1 #ifndef ROLLINGAVERAGE_H
2 #define ROLLINGAVERAGE_H
3 
4 /*
5  * RollingAverage.h
6  *
7  * Copyright 2013 Tim Barrass.
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 /*
15  Draws on Arduino Smoothing example,
16  Created 22 April 2007
17  By David A. Mellis <dam@mellis.org>
18  modified 9 Apr 2012
19  by Tom Igoe
20  http://www.arduino.cc/en/Tutorial/Smoothing
21 */
22 
23 #include "mozzi_utils.h" // for trailingZeros()
24 
25 
26 /** @ingroup sensortools
27  Calculates a running average over a
28  specified number of the most recent readings.
29  Like Smooth(), this is good for smoothing analog inputs in updateControl().
30  @tparam WINDOW_LENGTH the number of readings to include in the rolling average.
31  It must be a power of two (unless you're averaging floats). The higher the
32  number, the more the readings will be smoothed, but the slower the output
33  will respond to the input.
34 */
35 
36 template <class T, int WINDOW_LENGTH>
37 class
38  RollingAverage {
39 
40 public:
41 
42  /** Constructor.
43  @tparam T the type of numbers to average, eg. int, unsigned int, float etc. It will be relatively slow with
44  floating point numbers, as it will use a divide operation for the averaging.
45  Nevertheless, there might be a time when it's useful.
46  @tparam WINDOW_LENGTH the number of readings to keep track of. It must be a power of two (unless
47  you're averaging floats). The higher the number, the more the readings will be
48  smoothed, but the slower the output will respond to the input.
49  @note Watch out for overflows!
50  */
51  RollingAverage():index(0),total(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
52  {
53  // initialize all the readings to 0:
54  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
55  readings[thisReading] = 0;
56  }
57 
58 
59  /** Give the average of the last WINDOW_LENGTH.
60  @param input a control signal such as an analog input which needs smoothing.
61  @return the smoothed result.
62  @note unsigned int timing 5.7us
63  */
64  T next(T input)
65  {
66  return add(input)>>WINDOW_LENGTH_AS_RSHIFT;
67  }
68 
69 
70 protected:
71 
72  inline
73  T add(T input){
74  // out with the old
75  total -= readings[index];
76  // in with the new
77  total += input;
78  readings[index] = input;
79 
80  // advance and wrap index
81  ++index &= WINDOW_LENGTH -1;
82  return total;
83  }
84 
85 
86 private:
87  T readings[WINDOW_LENGTH]; // the readings from the analog input
88  unsigned int index; // the index of the current reading
89  long total; // the running total
90  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
91 
92 };
93 
94 // no need to show the specialisations
95 /** @cond */
96 
97 /** unsigned int partial specialisation of RollingAverage template.
98 This is needed because unsigned types need to remind (unsigned) for rshift.
99 */
100 template <int WINDOW_LENGTH>
101 class RollingAverage <unsigned int, WINDOW_LENGTH>
102 {
103 public:
104  /** Constructor.
105  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
106  The higher the number, the more the readings will be smoothed, but the slower the output will
107  respond to the input.
108  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
109  However, watch out for overflows if you are averaging a long number types!
110  */
111  RollingAverage():index(0),total(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
112  {
113  // initialize all the readings to 0:
114  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
115  readings[thisReading] = 0;
116  }
117 
118  /** Give the average of the last WINDOW_LENGTH.
119  @param a control signal such as an analog input which needs smoothing.
120  @return the smoothed result.
121  @note timing for int 6us
122  */
123  unsigned int next(unsigned int input)
124  {
125  // calculate the average:
126  // this unsigned cast is the only difference between the int and unsigned int specialisations
127  // it tells the shift not to sign extend in from the left
128  return (unsigned)add(input)>>WINDOW_LENGTH_AS_RSHIFT;
129  }
130 
131 protected:
132 
133 
134  inline
135  unsigned int add(unsigned int input){
136  // out with the old
137  total -= readings[index];
138  // in with the new
139  total += input;
140  readings[index] = input;
141 
142  // advance and wrap index
143  ++index &= WINDOW_LENGTH -1;
144  return total;
145  }
146 
147 
148 private:
149  unsigned int readings[WINDOW_LENGTH]; // the readings from the analog input
150  unsigned int index; // the index of the current reading
151  long total; // the running total
152  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
153 
154 };
155 
156 
157 
158 /** float partial specialisation of RollingAverage template*/
159 template <int WINDOW_LENGTH>
160 class RollingAverage <float, WINDOW_LENGTH>
161 {
162 public:
163  /** Constructor.
164  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
165  The higher the number, the more the readings will be smoothed, but the slower the output will
166  respond to the input.
167  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
168  However, watch out for overflows if you are averaging a long number types!
169  */
170  RollingAverage():index(0),total(0.0)
171  {
172  // initialize all the readings to 0:
173  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
174  readings[thisReading] = 0.0;
175  }
176 
177  /** Give the average of the last WINDOW_LENGTH.
178  @param a control signal such as an analog input which needs smoothing.
179  @return the smoothed result.
180  @note timing for float 37us
181  */
182  float next(float input)
183  {
184  // out with the old
185  total -= readings[index];
186  // in with the new
187  total += input;
188  readings[index] = input;
189 
190  // advance and wrap index
191  ++index &= WINDOW_LENGTH -1;
192 
193  // calculate the average:
194  return total/WINDOW_LENGTH;
195  }
196 
197 private:
198  float readings[WINDOW_LENGTH]; // the readings from the analog input
199  unsigned int index; // the index of the current reading
200  float total; // the running total
201 
202 };
203 
204 
205 // no need to show the specialisations
206 /** @endcond
207 */
208 
209 /**
210 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
211 This example demonstrates the RollingAverage class.
212 */
213 
214 #endif // #ifndef ROLLINGAVERAGE_H
-
1 #ifndef ROLLINGSTAT_H
2 #define ROLLINGSTAT_H
3 
4 /*
5  * RollingStat.h
6  *
7  * WARNING: this code is incomplete, it doesn't work yet
8  *
9  * Copyright 2013 Tim Barrass.
10  *
11  * This file is part of Mozzi.
12  *
13  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
14  *
15  */
16 
17 #include "RollingAverage.h"
18 #include "mozzi_fixmath.h"
19 
20 // adapted from RunningStat, http://www.johndcook.com/standard_deviation.html
21 /** @ingroup sensortools
22 WARNING: this class is work in progress, don't use it yet.
23 Calculates an approximation of the variance and standard deviation for a window of recent inputs.
24 @tparam T the type of numbers to use. Choose unsigned int, int , uint8_t, int8_t, or float
25 @tparam WINDOW_LENGTH how many recent input values to include in the calculations.
26 */
27 template <class T, int WINDOW_LENGTH>
29 {
30 public:
31 
32  /** Constructor */
33  RollingStat() : _previous_mean(0), _mean(0), _variance(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
34  {}
35 
36 
37  /** Update the mean and variance given a new input value.
38  @param x the next input value
39  @note timing for unsigned int 10us, int 22us
40  */
41  void update(T x) {
42  _mean = rollingMean.next(x);
43  _variance = (((long)x - _previous_mean)*((long)x - _mean))>>WINDOW_LENGTH_AS_RSHIFT; // should really be div by (WINDOW_LENGTH-1), but exact values are not important for this application
44  _previous_mean = _mean;
45  }
46 
47 
48  /** Update the mean and variance given a new input value.
49  @param x the next input value
50  */
51  void update(int8_t x) {
52  _mean = rollingMean.next(x);
53  _variance = (((int)x - _previous_mean)*((int)x - _mean))>>WINDOW_LENGTH_AS_RSHIFT; // should really be div by (WINDOW_LENGTH-1), but exact values are not important for this application
54  _previous_mean = _mean;
55  }
56 
57 
58  /** Return the mean of the last WINDOW_LENGTH number of inputs.
59  @return mean
60  */
61  T getMean() const {
62  return _mean;
63  }
64 
65 
66  /** Return the approximate variance of the last WINDOW_LENGTH number of inputs.
67  @return variance
68  @note This should really be calculated using WINDOW_LENGTH-1, but sacrificing accuracy for speed
69  we use the power of two value of WINDOW_LENGTH.
70  */
71  T getVariance() const {
72  return _variance;
73  }
74 
75  /** Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
76  @return standard deviation.
77  */
79  return isqrt16(_variance);
80  }
81 
82 
83 
84 private:
85  T _previous_mean, _mean, _variance;
86  RollingAverage <T, WINDOW_LENGTH> rollingMean;
87  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
88 };
89 
90 // no need to show the specialisations
91 /** @cond */
92 
93 /** float specialisation of RollingStat template */
94 template <int WINDOW_LENGTH>
95 class RollingStat <float, WINDOW_LENGTH>
96 {
97 public:
98 
99  /** Constructor */
100  RollingStat() : _previous_mean(0), _mean(0), _variance(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
101  {}
102 
103 
104  /** Update the mean and variance given a new input value.
105  @param x the next input value
106  @note timing for float: 60 to 90us
107  */
108  void update(float x) {
109  _mean = rollingMean.next(x);
110  _variance = ((x - _previous_mean)*(x - _mean))/(WINDOW_LENGTH-1);
111  _previous_mean = _mean;
112  }
113 
114 
115  /** Return the mean of the last WINDOW_LENGTH number of inputs.
116  @return mean
117  */
118  float getMean() const {
119  return _mean;
120  }
121 
122 
123  /** Return the approximate variance of the last WINDOW_LENGTH number of inputs.
124  @return variance
125  */
126  float getVariance() const {
127  return _variance;
128  }
129 
130  /** Calculate and return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
131  @return standard deviation.
132  @note this is probably too slow to use!
133  */
134  float getStandardDeviation() const {
135  return sqrt(_variance);
136  }
137 
138 
139 
140 private:
141  float _previous_mean, _mean, _variance;
142  RollingAverage <float, WINDOW_LENGTH> rollingMean;
143  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
144 };
145 
146 // no need to show the specialisations
147 /** @endcond */
148 
149 #endif // #ifndef ROLLINGSTAT_H
T getVariance() const
Return the approximate variance of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:71
-
void update(int8_t x)
Update the mean and variance given a new input value.
Definition: RollingStat.h:51
-
Calculates a running average over a specified number of the most recent readings. ...
-
T getMean() const
Return the mean of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:61
-
RollingStat()
Constructor.
Definition: RollingStat.h:33
-
void update(T x)
Update the mean and variance given a new input value.
Definition: RollingStat.h:41
-
WARNING: this class is work in progress, don&#39;t use it yet.
Definition: RollingStat.h:28
-
T getStandardDeviation() const
Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:78
+
1 #ifndef ROLLINGSTAT_H
2 #define ROLLINGSTAT_H
3 
4 /*
5  * RollingStat.h
6  *
7  * WARNING: this code is incomplete, it doesn't work yet
8  *
9  * Copyright 2013 Tim Barrass.
10  *
11  * This file is part of Mozzi.
12  *
13  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
14  *
15  */
16 
17 #include "RollingAverage.h"
18 #include "mozzi_fixmath.h"
19 
20 // adapted from RunningStat, http://www.johndcook.com/standard_deviation.html
21 /** @ingroup sensortools
22 WARNING: this class is work in progress, don't use it yet.
23 Calculates an approximation of the variance and standard deviation for a window of recent inputs.
24 @tparam T the type of numbers to use. Choose unsigned int, int , uint8_t, int8_t, or float
25 @tparam WINDOW_LENGTH how many recent input values to include in the calculations.
26 */
27 template <class T, int WINDOW_LENGTH>
29 {
30 public:
31 
32  /** Constructor */
33  RollingStat() : _previous_mean(0), _mean(0), _variance(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
34  {}
35 
36 
37  /** Update the mean and variance given a new input value.
38  @param x the next input value
39  @note timing for unsigned int 10us, int 22us
40  */
41  void update(T x) {
42  _mean = rollingMean.next(x);
43  _variance = (((long)x - _previous_mean)*((long)x - _mean))>>WINDOW_LENGTH_AS_RSHIFT; // should really be div by (WINDOW_LENGTH-1), but exact values are not important for this application
44  _previous_mean = _mean;
45  }
46 
47 
48  /** Update the mean and variance given a new input value.
49  @param x the next input value
50  */
51  void update(int8_t x) {
52  _mean = rollingMean.next(x);
53  _variance = (((int)x - _previous_mean)*((int)x - _mean))>>WINDOW_LENGTH_AS_RSHIFT; // should really be div by (WINDOW_LENGTH-1), but exact values are not important for this application
54  _previous_mean = _mean;
55  }
56 
57 
58  /** Return the mean of the last WINDOW_LENGTH number of inputs.
59  @return mean
60  */
61  T getMean() const {
62  return _mean;
63  }
64 
65 
66  /** Return the approximate variance of the last WINDOW_LENGTH number of inputs.
67  @return variance
68  @note This should really be calculated using WINDOW_LENGTH-1, but sacrificing accuracy for speed
69  we use the power of two value of WINDOW_LENGTH.
70  */
71  T getVariance() const {
72  return _variance;
73  }
74 
75  /** Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
76  @return standard deviation.
77  */
79  return isqrt16(_variance);
80  }
81 
82 
83 
84 private:
85  T _previous_mean, _mean, _variance;
86  RollingAverage <T, WINDOW_LENGTH> rollingMean;
87  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
88 };
89 
90 // no need to show the specialisations
91 /** @cond */
92 
93 /** float specialisation of RollingStat template */
94 template <int WINDOW_LENGTH>
95 class RollingStat <float, WINDOW_LENGTH>
96 {
97 public:
98 
99  /** Constructor */
100  RollingStat() : _previous_mean(0), _mean(0), _variance(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
101  {}
102 
103 
104  /** Update the mean and variance given a new input value.
105  @param x the next input value
106  @note timing for float: 60 to 90us
107  */
108  void update(float x) {
109  _mean = rollingMean.next(x);
110  _variance = ((x - _previous_mean)*(x - _mean))/(WINDOW_LENGTH-1);
111  _previous_mean = _mean;
112  }
113 
114 
115  /** Return the mean of the last WINDOW_LENGTH number of inputs.
116  @return mean
117  */
118  float getMean() const {
119  return _mean;
120  }
121 
122 
123  /** Return the approximate variance of the last WINDOW_LENGTH number of inputs.
124  @return variance
125  */
126  float getVariance() const {
127  return _variance;
128  }
129 
130  /** Calculate and return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
131  @return standard deviation.
132  @note this is probably too slow to use!
133  */
134  float getStandardDeviation() const {
135  return sqrt(_variance);
136  }
137 
138 
139 
140 private:
141  float _previous_mean, _mean, _variance;
142  RollingAverage <float, WINDOW_LENGTH> rollingMean;
143  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
144 };
145 
146 // no need to show the specialisations
147 /** @endcond */
148 
149 #endif // #ifndef ROLLINGSTAT_H
WARNING: this class is work in progress, don&#39;t use it yet.
Definition: RollingStat.h:28
+
T getMean() const
Return the mean of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:61
+
RollingStat()
Constructor.
Definition: RollingStat.h:33
+
T getStandardDeviation() const
Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:78
+
T getVariance() const
Return the approximate variance of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:71
+
void update(int8_t x)
Update the mean and variance given a new input value.
Definition: RollingStat.h:51
+
void update(T x)
Update the mean and variance given a new input value.
Definition: RollingStat.h:41
-
1 /*
2  * Sample.h
3  *
4  * Copyright 2012 Tim Barrass
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef SAMPLE_H_
13 #define SAMPLE_H_
14 
15 #include "MozziGuts.h"
16 #include "mozzi_fixmath.h"
17 #include "mozzi_pgmspace.h"
18 
19 // fractional bits for sample index precision
20 #define SAMPLE_F_BITS 16
21 #define SAMPLE_F_BITS_AS_MULTIPLIER 65536
22 
23 // phmod_proportion is an 1n15 fixed-point number only using
24 // the fractional part and the sign bit
25 #define SAMPLE_PHMOD_BITS 16
26 
27 enum interpolation {INTERP_NONE, INTERP_LINEAR};
28 
29 /** Sample is like Oscil, it plays a wavetable. However, Sample can be
30 set to play once through only, with variable start and end points,
31 or can loop, also with variable start and end points.
32 It defaults to playing once through the whole sound table, from start to finish.
33 @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Sample will be
34 using. The sound table can be arbitrary length for Sample.
35 It's important that NUM_TABLE_CELLS is either a literal number (eg. "8192") or a
36 defined macro, rather than a const or int, for the Sample to run fast enough.
37 @tparam UPDATE_RATE This will be AUDIO_RATE if the Sample is updated in
38 updateAudio(), or CONTROL_RATE if it's updated each time updateControl() is
39 called. It could also be a fraction of CONTROL_RATE if you are doing some kind
40 of cyclic updating in updateControl(), for example, to spread out the processor load.
41 @section int8_t2mozzi
42 Converting soundfiles for Mozzi.
43 There is a python script called int8_t2mozzi.py in the Mozzi/python folder.
44 The script converts raw sound data saved from a program like Audacity.
45 Instructions are in the int8_t2mozzi.py file.
46 */
47 template <unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, uint8_t INTERP=INTERP_NONE>
48 class Sample
49 {
50 
51 public:
52 
53  /** Constructor.
54  @param TABLE_NAME the name of the array the Sample will be using. This
55  can be found in the table ".h" file if you are using a table made for
56  Mozzi by the int8_t2mozzi.py python script in Mozzi's python
57  folder. Sound tables can be of arbitrary lengths for Sample().
58  */
59  Sample(const int8_t * TABLE_NAME):table(TABLE_NAME),endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS) // so isPlaying() will work
60  {
62  //rangeWholeSample();
63  }
64 
65 
66 
67  /** Constructor.
68  Declare a Sample with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play.
69  The table can be set or changed on the fly with setTable().
70  */
71  Sample():endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS)
72  {
74  //rangeWholeSample();
75  }
76 
77 
78  /** Change the sound table which will be played by the Sample.
79  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
80  */
81  inline
82  void setTable(const int8_t * TABLE_NAME)
83  {
84  table = TABLE_NAME;
85  }
86 
87 
88  /** Sets the starting position in samples.
89  @param startpos offset position in samples.
90  */
91  inline
92  void setStart(unsigned int startpos)
93  {
94  startpos_fractional = (unsigned long) startpos << SAMPLE_F_BITS;
95  }
96 
97 
98  /** Resets the phase (the playhead) to the start position, which will be 0 unless set to another value with setStart();
99  */
100  inline
101  void start()
102  {
103  phase_fractional = startpos_fractional;
104  }
105 
106 
107  /** Sets a new start position plays the sample from that position.
108  @param startpos position in samples from the beginning of the sound.
109  */
110  inline
111  void start(unsigned int startpos)
112  {
113  setStart(startpos);
114  start();
115  }
116 
117 
118  /** Sets the end position in samples from the beginning of the sound.
119  @param end position in samples.
120  */
121  inline
122  void setEnd(unsigned int end)
123  {
124  endpos_fractional = (unsigned long) end << SAMPLE_F_BITS;
125  }
126 
127 
128  /** Sets the start and end points to include the range of the whole sound table.
129  */
130  inline
132  {
133  startpos_fractional = 0;
134  endpos_fractional = (unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS;
135  }
136 
137 
138  /** Turns looping on.
139  */
140  inline
142  {
143  looping=true;
144  }
145 
146 
147  /** Turns looping off.
148  */
149  inline
151  {
152  looping=false;
153  }
154 
155 
156 
157  /**
158  Returns the sample at the current phase position, or 0 if looping is off
159  and the phase overshoots the end of the sample. Updates the phase
160  according to the current frequency.
161  @return the next sample value from the table, or 0 if it's finished playing.
162  @todo in next(), incrementPhase() happens in a different position than for Oscil - check if it can be standardised
163  */
164  inline
165  int8_t next() { // 4us
166 
167  if (phase_fractional>endpos_fractional){
168  if (looping) {
169  phase_fractional = startpos_fractional + (phase_fractional - endpos_fractional);
170  }else{
171  return 0;
172  }
173  }
174  int8_t out;
175  if(INTERP==INTERP_LINEAR){
176  // WARNNG this is hard coded for when SAMPLE_F_BITS is 16
177  unsigned int index = phase_fractional >> SAMPLE_F_BITS;
178  out = FLASH_OR_RAM_READ<const int8_t>(table + index);
179  int8_t difference = FLASH_OR_RAM_READ<const int8_t>((table + 1) + index) - out;
180  int8_t diff_fraction = (int8_t)(((((unsigned int) phase_fractional)>>8)*difference)>>8); // (unsigned int) phase_fractional keeps low word, then>> for only 8 bit precision
181  out += diff_fraction;
182  }else{
183  out = FLASH_OR_RAM_READ<const int8_t>(table + (phase_fractional >> SAMPLE_F_BITS));
184  }
185  incrementPhase();
186  return out;
187  }
188 
189 
190  /** Checks if the sample is playing by seeing if the phase is within the limits of its end position.
191  @return true if the sample is playing
192  */
193  inline
195  return phase_fractional<endpos_fractional;
196  }
197 
198 
199  // Not readjusted for arbitrary table length yet
200  //
201  // Returns the next sample given a phase modulation value.
202  // @param phmod_proportion phase modulation value given as a proportion of the wave. The
203  // phmod_proportion parameter is a Q15n16 fixed-point number where to fractional
204  // n16 part represents -1 to 1, modulating the phase by one whole table length in
205  // each direction.
206  // @return a sample from the table.
207  //
208  // inline
209  // int8_t phMod(long phmod_proportion)
210  // {
211  // incrementPhase();
212  // return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>SAMPLE_SAMPLE_F_BITS) & (NUM_TABLE_CELLS - 1)));
213  // }
214 
215 
216 
217  /** Set the oscillator frequency with an unsigned int.
218  This is faster than using a float, so it's useful when processor time is tight,
219  but it can be tricky with low and high frequencies, depending on the size of the
220  wavetable being used. If you're not getting the results you expect, try
221  explicitly using a float, or try setFreq_Q24n8.
222  @param frequency to play the wave table.
223  */
224  inline
225  void setFreq (int frequency) {
226  phase_increment_fractional = ((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
227  }
228 
229 
230  /** Set the sample frequency with a float. Using a float is the most reliable
231  way to set frequencies, -Might- be slower than using an int but you need either
232  this or setFreq_Q24n8 for fractional frequencies.
233  @param frequency to play the wave table.
234  */
235  inline
236  void setFreq(float frequency)
237  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
238  phase_increment_fractional = (unsigned long)((((float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * SAMPLE_F_BITS_AS_MULTIPLIER);
239  }
240 
241 
242  /** Set the frequency using Q24n8 fixed-point number format.
243  This might be faster than the float version for setting low frequencies
244  such as 1.5 Hz, or other values which may not work well with your table
245  size. Note: use with caution because it's prone to overflow with higher
246  frequencies and larger table sizes. An Q24n8 representation of 1.5 is 384
247  (ie. 1.5 * 256).
248  @param frequency in Q24n8 fixed-point number format.
249  */
250  inline
251  void setFreq_Q24n8(Q24n8 frequency)
252  {
253  //phase_increment_fractional = (frequency* (NUM_TABLE_CELLS>>3)/(UPDATE_RATE>>6)) << (F_BITS-(8-3+6));
254  phase_increment_fractional = (((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
255  << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
256  }
257 
258 
259  /** Returns the sample at the given table index.
260  @param index between 0 and the table size.
261  @return the sample at the given table index.
262  */
263  inline
264  int8_t atIndex(unsigned int index)
265  {
266  return FLASH_OR_RAM_READ<const int8_t>(table + index);
267  }
268 
269 
270  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
271  Instead of recalculating the phase increment for each
272  frequency in between, you can just calculate the phase increment for each end
273  frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and
274  use setPhaseInc() to set the phase increment at each step. (Note: I should
275  really profile this with the oscilloscope to see if it's worth the extra
276  confusion!)
277  @param frequency for which you want to calculate a phase increment value.
278  @return the phase increment value which will produce a given frequency.
279  */
280  inline
281  unsigned long phaseIncFromFreq(unsigned int frequency)
282  {
283  return (((unsigned long)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << SAMPLE_F_BITS;
284  }
285 
286 
287  /** Set a specific phase increment. See phaseIncFromFreq().
288  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
289  */
290  inline
291  void setPhaseInc(unsigned long phaseinc_fractional)
292  {
293  phase_increment_fractional = phaseinc_fractional;
294  }
295 
296 
297 private:
298 
299 
300  /** Used for shift arithmetic in setFreq() and its variations.
301  */
302 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
303 
304 
305  /** Increments the phase of the oscillator without returning a sample.
306  */
307  inline
308  void incrementPhase()
309  {
310  phase_fractional += phase_increment_fractional;
311  }
312 
313 
314  volatile unsigned long phase_fractional;
315  volatile unsigned long phase_increment_fractional;
316  const int8_t * table;
317  bool looping;
318  unsigned long startpos_fractional, endpos_fractional;
319 };
320 
321 
322 /**
323 @example 08.Samples/Sample/Sample.ino
324 This example demonstrates the Sample class.
325 */
326 
327 #endif /* SAMPLE_H_ */
void setFreq_Q24n8(Q24n8 frequency)
Set the frequency using Q24n8 fixed-point number format.
Definition: Sample.h:251
+
1 /*
2  * Sample.h
3  *
4  * Copyright 2012 Tim Barrass
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef SAMPLE_H_
13 #define SAMPLE_H_
14 
15 #include "MozziHeadersOnly.h"
16 #include "mozzi_fixmath.h"
17 #include "mozzi_pgmspace.h"
18 
19 // fractional bits for sample index precision
20 #define SAMPLE_F_BITS 16
21 #define SAMPLE_F_BITS_AS_MULTIPLIER 65536
22 
23 // phmod_proportion is an 1n15 fixed-point number only using
24 // the fractional part and the sign bit
25 #define SAMPLE_PHMOD_BITS 16
26 
27 enum interpolation {INTERP_NONE, INTERP_LINEAR};
28 
29 /** Sample is like Oscil, it plays a wavetable. However, Sample can be
30 set to play once through only, with variable start and end points,
31 or can loop, also with variable start and end points.
32 It defaults to playing once through the whole sound table, from start to finish.
33 @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Sample will be
34 using. The sound table can be arbitrary length for Sample.
35 It's important that NUM_TABLE_CELLS is either a literal number (eg. "8192") or a
36 defined macro, rather than a const or int, for the Sample to run fast enough.
37 @tparam UPDATE_RATE This will be MOZZI_AUDIO_RATE if the Sample is updated in
38 updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is
39 called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind
40 of cyclic updating in updateControl(), for example, to spread out the processor load.
41 @section int8_t2mozzi
42 Converting soundfiles for Mozzi.
43 There is a python script called int8_t2mozzi.py in the Mozzi/python folder.
44 The script converts raw sound data saved from a program like Audacity.
45 Instructions are in the int8_t2mozzi.py file.
46 */
47 template <unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, uint8_t INTERP=INTERP_NONE>
48 class Sample
49 {
50 
51 public:
52 
53  /** Constructor.
54  @param TABLE_NAME the name of the array the Sample will be using. This
55  can be found in the table ".h" file if you are using a table made for
56  Mozzi by the int8_t2mozzi.py python script in Mozzi's python
57  folder. Sound tables can be of arbitrary lengths for Sample().
58  */
59  Sample(const int8_t * TABLE_NAME):table(TABLE_NAME),endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS) // so isPlaying() will work
60  {
62  //rangeWholeSample();
63  }
64 
65 
66 
67  /** Constructor.
68  Declare a Sample with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play.
69  The table can be set or changed on the fly with setTable().
70  */
71  Sample():endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS)
72  {
74  //rangeWholeSample();
75  }
76 
77 
78  /** Change the sound table which will be played by the Sample.
79  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
80  */
81  inline
82  void setTable(const int8_t * TABLE_NAME)
83  {
84  table = TABLE_NAME;
85  }
86 
87 
88  /** Sets the starting position in samples.
89  @param startpos offset position in samples.
90  */
91  inline
92  void setStart(unsigned int startpos)
93  {
94  startpos_fractional = (unsigned long) startpos << SAMPLE_F_BITS;
95  }
96 
97 
98  /** Resets the phase (the playhead) to the start position, which will be 0 unless set to another value with setStart();
99  */
100  inline
101  void start()
102  {
103  phase_fractional = startpos_fractional;
104  }
105 
106 
107  /** Sets a new start position plays the sample from that position.
108  @param startpos position in samples from the beginning of the sound.
109  */
110  inline
111  void start(unsigned int startpos)
112  {
113  setStart(startpos);
114  start();
115  }
116 
117 
118  /** Sets the end position in samples from the beginning of the sound.
119  @param end position in samples.
120  */
121  inline
122  void setEnd(unsigned int end)
123  {
124  endpos_fractional = (unsigned long) end << SAMPLE_F_BITS;
125  }
126 
127 
128  /** Sets the start and end points to include the range of the whole sound table.
129  */
130  inline
132  {
133  startpos_fractional = 0;
134  endpos_fractional = (unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS;
135  }
136 
137 
138  /** Turns looping on.
139  */
140  inline
142  {
143  looping=true;
144  }
145 
146 
147  /** Turns looping off.
148  */
149  inline
151  {
152  looping=false;
153  }
154 
155 
156 
157  /**
158  Returns the sample at the current phase position, or 0 if looping is off
159  and the phase overshoots the end of the sample. Updates the phase
160  according to the current frequency.
161  @return the next sample value from the table, or 0 if it's finished playing.
162  @todo in next(), incrementPhase() happens in a different position than for Oscil - check if it can be standardised
163  */
164  inline
165  int8_t next() { // 4us
166 
167  if (phase_fractional>endpos_fractional){
168  if (looping) {
169  phase_fractional = startpos_fractional + (phase_fractional - endpos_fractional);
170  }else{
171  return 0;
172  }
173  }
174  int8_t out;
175  if(INTERP==INTERP_LINEAR){
176  // WARNNG this is hard coded for when SAMPLE_F_BITS is 16
177  unsigned int index = phase_fractional >> SAMPLE_F_BITS;
178  out = FLASH_OR_RAM_READ<const int8_t>(table + index);
179  int8_t difference = FLASH_OR_RAM_READ<const int8_t>((table + 1) + index) - out;
180  int8_t diff_fraction = (int8_t)(((((unsigned int) phase_fractional)>>8)*difference)>>8); // (unsigned int) phase_fractional keeps low word, then>> for only 8 bit precision
181  out += diff_fraction;
182  }else{
183  out = FLASH_OR_RAM_READ<const int8_t>(table + (phase_fractional >> SAMPLE_F_BITS));
184  }
185  incrementPhase();
186  return out;
187  }
188 
189 
190  /** Checks if the sample is playing by seeing if the phase is within the limits of its end position.
191  @return true if the sample is playing
192  */
193  inline
195  return phase_fractional<endpos_fractional;
196  }
197 
198 
199  // Not readjusted for arbitrary table length yet
200  //
201  // Returns the next sample given a phase modulation value.
202  // @param phmod_proportion phase modulation value given as a proportion of the wave. The
203  // phmod_proportion parameter is a Q15n16 fixed-point number where to fractional
204  // n16 part represents -1 to 1, modulating the phase by one whole table length in
205  // each direction.
206  // @return a sample from the table.
207  //
208  // inline
209  // int8_t phMod(long phmod_proportion)
210  // {
211  // incrementPhase();
212  // return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>SAMPLE_SAMPLE_F_BITS) & (NUM_TABLE_CELLS - 1)));
213  // }
214 
215 
216 
217  /** Set the oscillator frequency with an unsigned int.
218  This is faster than using a float, so it's useful when processor time is tight,
219  but it can be tricky with low and high frequencies, depending on the size of the
220  wavetable being used. If you're not getting the results you expect, try
221  explicitly using a float, or try setFreq_Q24n8.
222  @param frequency to play the wave table.
223  */
224  inline
225  void setFreq (int frequency) {
226  phase_increment_fractional = ((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
227  }
228 
229 
230  /** Set the sample frequency with a float. Using a float is the most reliable
231  way to set frequencies, -Might- be slower than using an int but you need either
232  this or setFreq_Q24n8 for fractional frequencies.
233  @param frequency to play the wave table.
234  */
235  inline
236  void setFreq(float frequency)
237  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
238  phase_increment_fractional = (unsigned long)((((float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * SAMPLE_F_BITS_AS_MULTIPLIER);
239  }
240 
241 
242  /** Set the frequency using Q24n8 fixed-point number format.
243  This might be faster than the float version for setting low frequencies
244  such as 1.5 Hz, or other values which may not work well with your table
245  size. Note: use with caution because it's prone to overflow with higher
246  frequencies and larger table sizes. An Q24n8 representation of 1.5 is 384
247  (ie. 1.5 * 256).
248  @param frequency in Q24n8 fixed-point number format.
249  */
250  inline
251  void setFreq_Q24n8(Q24n8 frequency)
252  {
253  //phase_increment_fractional = (frequency* (NUM_TABLE_CELLS>>3)/(UPDATE_RATE>>6)) << (F_BITS-(8-3+6));
254  phase_increment_fractional = (((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
255  << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
256  }
257 
258 
259  /** Returns the sample at the given table index.
260  @param index between 0 and the table size.
261  @return the sample at the given table index.
262  */
263  inline
264  int8_t atIndex(unsigned int index)
265  {
266  return FLASH_OR_RAM_READ<const int8_t>(table + index);
267  }
268 
269 
270  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
271  Instead of recalculating the phase increment for each
272  frequency in between, you can just calculate the phase increment for each end
273  frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and
274  use setPhaseInc() to set the phase increment at each step. (Note: I should
275  really profile this with the oscilloscope to see if it's worth the extra
276  confusion!)
277  @param frequency for which you want to calculate a phase increment value.
278  @return the phase increment value which will produce a given frequency.
279  */
280  inline
281  unsigned long phaseIncFromFreq(unsigned int frequency)
282  {
283  return (((unsigned long)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << SAMPLE_F_BITS;
284  }
285 
286 
287  /** Set a specific phase increment. See phaseIncFromFreq().
288  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
289  */
290  inline
291  void setPhaseInc(unsigned long phaseinc_fractional)
292  {
293  phase_increment_fractional = phaseinc_fractional;
294  }
295 
296 
297 private:
298 
299 
300  /** Used for shift arithmetic in setFreq() and its variations.
301  */
302 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
303 
304 
305  /** Increments the phase of the oscillator without returning a sample.
306  */
307  inline
308  void incrementPhase()
309  {
310  phase_fractional += phase_increment_fractional;
311  }
312 
313 
314  volatile unsigned long phase_fractional;
315  volatile unsigned long phase_increment_fractional;
316  const int8_t * table;
317  bool looping;
318  unsigned long startpos_fractional, endpos_fractional;
319 };
320 
321 
322 /**
323 @example 08.Samples/Sample/Sample.ino
324 This example demonstrates the Sample class.
325 */
326 
327 #endif /* SAMPLE_H_ */
void setFreq_Q24n8(Q24n8 frequency)
Set the frequency using Q24n8 fixed-point number format.
Definition: Sample.h:251
void setLoopingOn()
Turns looping on.
Definition: Sample.h:141
void setFreq(int frequency)
Set the oscillator frequency with an unsigned int.
Definition: Sample.h:225
void setEnd(unsigned int end)
Sets the end position in samples from the beginning of the sound.
Definition: Sample.h:122
@@ -117,7 +117,7 @@
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Sample.
Definition: Sample.h:82
#define SAMPLE_F_BITS
Definition: Sample.h:20
int8_t next()
Returns the sample at the current phase position, or 0 if looping is off and the phase overshoots th...
Definition: Sample.h:165
-
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:45
+
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:43
boolean isPlaying()
Checks if the sample is playing by seeing if the phase is within the limits of its end position...
Definition: Sample.h:194
void start()
Resets the phase (the playhead) to the start position, which will be 0 unless set to another value wi...
Definition: Sample.h:101
void setFreq(float frequency)
Set the sample frequency with a float.
Definition: Sample.h:236
@@ -131,7 +131,7 @@
-
1 /*
2  * Smooth.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef SMOOTH_H_
13 #define SMOOTH_H_
14 
15 #include "Arduino.h"
16 #include "mozzi_fixmath.h"
17 
18 /** A simple infinite impulse response low pass filter for smoothing control or audio signals.
19 This algorithm comes from http://en.wikipedia.org/wiki/Low-pass_filter:
20 y[i] := y[i-1] + α * (x[i] - y[i-1]),
21 translated as
22 out = last_out + a * (in - last_out).
23 It's not calibrated to any real-world update rate, so if you use it at
24 CONTROL_RATE and you change CONTROL_RATE, you'll need to adjust the smoothness
25 value to suit.
26 @tparam T the type of numbers being smoothed. Watch out for numbers overflowing the
27 internal calculations. Some experimentation is recommended.
28 @note Timing: ~5us for 16 bit types, ~1us for 8 bit types.
29 @todo Check if 8 bit templates can work efficiently with a higher res smoothness -
30  as is they don't have enough resolution to work well at audio rate. See if Line might be
31  more useful in most cases.
32 */
33 
34 template <class T>
35 class Smooth
36 {
37 private:
38  long last_out;
39  Q0n16 a;
40 
41 public:
42  /** Constructor.
43  @param smoothness sets how much smoothing the filter will apply to
44  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
45  very smooth.
46  */
47  Smooth(float smoothness)
48  {
49  setSmoothness(smoothness);
50  }
51 
52  /** Constructor.
53  This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition.
54  You need to call setSmoothness(float) for your object before using Smooth.
55  @note there's probably a better way to do this...
56  */
58  {}
59 
60 
61  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
62  @param in the signal to be smoothed.
63  @return the filtered signal.
64  */
65  inline
66  T next(T in)
67  {
68  long out = ((((((long)in - (last_out>>8)) * a))>>8) + last_out);
69  last_out = out;
70  return (T)(out>>8);
71  }
72 
73 
74  /** Filters the input and returns the filtered value. Same as next(input-value).
75  @param in the signal to be smoothed.
76  @return the filtered signal.
77  */
78  inline
79  T operator()(T n) {
80  return next(n);
81  }
82 
83 
84  /** Sets how much smoothing the filter will apply to its input.
85  @param smoothness sets how much smoothing the filter will apply to
86  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
87  very smooth.
88  */
89  inline
90  void setSmoothness(float smoothness)
91  {
92  a=float_to_Q0n16(1.f-smoothness);
93  }
94 
95 };
96 
97 
98 /** @cond */ // doxygen can ignore the specialisations
99 
100 /** uint8_t specialisation of Smooth template*/
101 template <>
102 class Smooth <uint8_t>
103 {
104 private:
105  unsigned int last_out;
106  Q0n8 a;
107 
108 public:
109  /** Constructor.
110  @param smoothness sets how much smoothing the filter will apply to
111  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
112  very smooth.
113  */
114  Smooth(float smoothness)
115  {
116  setSmoothness(smoothness);
117  }
118 
119  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
120  @param in the signal to be smoothed.
121  @return the filtered signal.
122  */
123  inline
124  uint8_t next(uint8_t in)
125  {
126  unsigned int out = (((((int)in - (last_out>>8)) * a)) + last_out);
127  last_out = out;
128  return (uint8_t)(out>>8);
129  }
130 
131 
132  /** Filters the input and returns the filtered value. Same as next(input-value).
133  @param in the signal to be smoothed.
134  @return the filtered signal.
135  */
136  inline
137  uint8_t operator()(uint8_t n) {
138  return next(n);
139  }
140 
141 
142  /** Sets how much smoothing the filter will apply to its input.
143  @param smoothness sets how much smoothing the filter will apply to
144  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
145  very smooth.
146  */
147  inline
148  void setSmoothness(float smoothness)
149  {
150  a=float_to_Q0n8(1.f-smoothness);
151  }
152 
153 };
154 
155 
156 /** int8_t specialisation of Smooth template*/
157 template <>
158 class Smooth <int8_t>
159 {
160 private:
161  int last_out;
162  Q0n8 a;
163 
164 public:
165  /** Constructor.
166  @param smoothness sets how much smoothing the filter will apply to
167  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
168  very smooth.
169  */
170  Smooth(float smoothness)
171  {
172  setSmoothness(smoothness);
173  }
174 
175 
176  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
177  @param in the signal to be smoothed.
178  @return the filtered signal.
179  */
180  inline
181  int8_t next(int8_t in)
182  {
183  int out = (((((int)in - (last_out>>8)) * a)) + last_out);
184  last_out = out;
185  return (int8_t)(out>>8);
186  }
187 
188 
189  /** Filters the input and returns the filtered value. Same as next(input-value).
190  @param in the signal to be smoothed.
191  @return the filtered signal.
192  */
193  inline
194  int8_t operator()(int8_t n) {
195  return next(n);
196  }
197 
198 
199  /** Sets how much smoothing the filter will apply to its input.
200  @param smoothness sets how much smoothing the filter will apply to
201  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
202  very smooth.
203  */
204  inline
205  void setSmoothness(float smoothness)
206  {
207  a=float_to_Q0n8(1.f-smoothness);
208  }
209 
210 };
211 
212 /** float specialisation of Smooth template*/
213 template <>
214 class Smooth <float>
215 {
216 private:
217  float last_out;
218  float a;
219 
220 public:
221  /** Constructor.
222  @param smoothness sets how much smoothing the filter will apply to
223  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
224  very smooth.
225  */
226  Smooth(float smoothness)
227  {
228  setSmoothness(smoothness);
229  }
230 
231  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
232  @param in the signal to be smoothed.
233  @return the filtered signal.
234  */
235  inline
236  float next(float in)
237  {
238  float out = last_out + a * (in - last_out);
239  //float out = (in - last_out * a) + last_out;
240  last_out = out;
241  return out;
242  }
243 
244 
245  /** Filters the input and returns the filtered value. Same as next(input-value).
246  @param in the signal to be smoothed.
247  @return the filtered signal.
248  */
249  inline
250  float operator()(float n) {
251  return next(n);
252  }
253 
254 
255  /** Sets how much smoothing the filter will apply to its input.
256  @param smoothness sets how much smoothing the filter will apply to
257  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
258  very smooth.
259  */
260  inline
261  void setSmoothness(float smoothness)
262  {
263  a=1.f-smoothness;
264  }
265 
266 };
267 
268 
269 /** @endcond */
270 
271 /**
272 @example 05.Control_Filters/Smooth/Smooth.ino
273 This example demonstrates the Smooth class.
274 */
275 
276 #endif /* SMOOTH_H_ */
void setSmoothness(float smoothness)
Sets how much smoothing the filter will apply to its input.
Definition: Smooth.h:90
+
1 /*
2  * Smooth.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef SMOOTH_H_
13 #define SMOOTH_H_
14 
15 #include "Arduino.h"
16 #include "mozzi_fixmath.h"
17 
18 /** A simple infinite impulse response low pass filter for smoothing control or audio signals.
19 This algorithm comes from http://en.wikipedia.org/wiki/Low-pass_filter:
20 y[i] := y[i-1] + α * (x[i] - y[i-1]),
21 translated as
22 out = last_out + a * (in - last_out).
23 It's not calibrated to any real-world update rate, so if you use it at
24 MOZZI_CONTROL_RATE and you change MOZZI_CONTROL_RATE, you'll need to adjust the smoothness
25 value to suit.
26 @tparam T the type of numbers being smoothed. Watch out for numbers overflowing the
27 internal calculations. Some experimentation is recommended.
28 @note Timing: ~5us for 16 bit types, ~1us for 8 bit types.
29 @todo Check if 8 bit templates can work efficiently with a higher res smoothness -
30  as is they don't have enough resolution to work well at audio rate. See if Line might be
31  more useful in most cases.
32 */
33 
34 template <class T>
35 class Smooth
36 {
37 private:
38  long last_out;
39  Q0n16 a;
40 
41 public:
42  /** Constructor.
43  @param smoothness sets how much smoothing the filter will apply to
44  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
45  very smooth.
46  */
47  Smooth(float smoothness)
48  {
49  setSmoothness(smoothness);
50  }
51 
52  /** Constructor.
53  This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition.
54  You need to call setSmoothness(float) for your object before using Smooth.
55  @note there's probably a better way to do this...
56  */
58  {}
59 
60 
61  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
62  @param in the signal to be smoothed.
63  @return the filtered signal.
64  */
65  inline
66  T next(T in)
67  {
68  long out = ((((((long)in - (last_out>>8)) * a))>>8) + last_out);
69  last_out = out;
70  return (T)(out>>8);
71  }
72 
73 
74  /** Filters the input and returns the filtered value. Same as next(input-value).
75  @param in the signal to be smoothed.
76  @return the filtered signal.
77  */
78  inline
79  T operator()(T n) {
80  return next(n);
81  }
82 
83 
84  /** Sets how much smoothing the filter will apply to its input.
85  @param smoothness sets how much smoothing the filter will apply to
86  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
87  very smooth.
88  */
89  inline
90  void setSmoothness(float smoothness)
91  {
92  a=float_to_Q0n16(1.f-smoothness);
93  }
94 
95 };
96 
97 
98 /** @cond */ // doxygen can ignore the specialisations
99 
100 /** uint8_t specialisation of Smooth template*/
101 template <>
102 class Smooth <uint8_t>
103 {
104 private:
105  unsigned int last_out;
106  Q0n8 a;
107 
108 public:
109  /** Constructor.
110  @param smoothness sets how much smoothing the filter will apply to
111  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
112  very smooth.
113  */
114  Smooth(float smoothness)
115  {
116  setSmoothness(smoothness);
117  }
118 
119  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
120  @param in the signal to be smoothed.
121  @return the filtered signal.
122  */
123  inline
124  uint8_t next(uint8_t in)
125  {
126  unsigned int out = (((((int)in - (last_out>>8)) * a)) + last_out);
127  last_out = out;
128  return (uint8_t)(out>>8);
129  }
130 
131 
132  /** Filters the input and returns the filtered value. Same as next(input-value).
133  @param in the signal to be smoothed.
134  @return the filtered signal.
135  */
136  inline
137  uint8_t operator()(uint8_t n) {
138  return next(n);
139  }
140 
141 
142  /** Sets how much smoothing the filter will apply to its input.
143  @param smoothness sets how much smoothing the filter will apply to
144  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
145  very smooth.
146  */
147  inline
148  void setSmoothness(float smoothness)
149  {
150  a=float_to_Q0n8(1.f-smoothness);
151  }
152 
153 };
154 
155 
156 /** int8_t specialisation of Smooth template*/
157 template <>
158 class Smooth <int8_t>
159 {
160 private:
161  int last_out;
162  Q0n8 a;
163 
164 public:
165  /** Constructor.
166  @param smoothness sets how much smoothing the filter will apply to
167  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
168  very smooth.
169  */
170  Smooth(float smoothness)
171  {
172  setSmoothness(smoothness);
173  }
174 
175 
176  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
177  @param in the signal to be smoothed.
178  @return the filtered signal.
179  */
180  inline
181  int8_t next(int8_t in)
182  {
183  int out = (((((int)in - (last_out>>8)) * a)) + last_out);
184  last_out = out;
185  return (int8_t)(out>>8);
186  }
187 
188 
189  /** Filters the input and returns the filtered value. Same as next(input-value).
190  @param in the signal to be smoothed.
191  @return the filtered signal.
192  */
193  inline
194  int8_t operator()(int8_t n) {
195  return next(n);
196  }
197 
198 
199  /** Sets how much smoothing the filter will apply to its input.
200  @param smoothness sets how much smoothing the filter will apply to
201  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
202  very smooth.
203  */
204  inline
205  void setSmoothness(float smoothness)
206  {
207  a=float_to_Q0n8(1.f-smoothness);
208  }
209 
210 };
211 
212 /** float specialisation of Smooth template*/
213 template <>
214 class Smooth <float>
215 {
216 private:
217  float last_out;
218  float a;
219 
220 public:
221  /** Constructor.
222  @param smoothness sets how much smoothing the filter will apply to
223  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
224  very smooth.
225  */
226  Smooth(float smoothness)
227  {
228  setSmoothness(smoothness);
229  }
230 
231  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
232  @param in the signal to be smoothed.
233  @return the filtered signal.
234  */
235  inline
236  float next(float in)
237  {
238  float out = last_out + a * (in - last_out);
239  //float out = (in - last_out * a) + last_out;
240  last_out = out;
241  return out;
242  }
243 
244 
245  /** Filters the input and returns the filtered value. Same as next(input-value).
246  @param in the signal to be smoothed.
247  @return the filtered signal.
248  */
249  inline
250  float operator()(float n) {
251  return next(n);
252  }
253 
254 
255  /** Sets how much smoothing the filter will apply to its input.
256  @param smoothness sets how much smoothing the filter will apply to
257  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
258  very smooth.
259  */
260  inline
261  void setSmoothness(float smoothness)
262  {
263  a=1.f-smoothness;
264  }
265 
266 };
267 
268 
269 /** @endcond */
270 
271 /**
272 @example 05.Control_Filters/Smooth/Smooth.ino
273 This example demonstrates the Smooth class.
274 */
275 
276 #endif /* SMOOTH_H_ */
void setSmoothness(float smoothness)
Sets how much smoothing the filter will apply to its input.
Definition: Smooth.h:90
Smooth(float smoothness)
Constructor.
Definition: Smooth.h:47
-
uint16_t Q0n16
unsigned fractional number using 16 fractional bits, represents 0.0 to 0.999
Definition: mozzi_fixmath.h:29
+
uint16_t Q0n16
unsigned fractional number using 16 fractional bits, represents 0.0 to 0.999
Definition: mozzi_fixmath.h:27
A simple infinite impulse response low pass filter for smoothing control or audio signals...
Definition: Smooth.h:35
T operator()(T n)
Filters the input and returns the filtered value.
Definition: Smooth.h:79
-
Q0n16 float_to_Q0n16(float a)
Convert float to Q0n16 fix.
+
Q0n16 float_to_Q0n16(float a)
Convert float to Q0n16 fix.
T next(T in)
Filters the input and returns the filtered value.
Definition: Smooth.h:66
Smooth()
Constructor.
Definition: Smooth.h:57
@@ -117,7 +117,7 @@
-
1 /*
2  * StateVariable.h
3  *
4  * This implementation copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 /**
14 State Variable Filter (approximation of Chamberlin version)
15 Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and
16 http://www.musicdsp.org/showone.php?id=142. Here's the original:
17 ---------------------
18 cutoff = cutoff freq in Hz
19 fs = sampling frequency //(e.g. 44100Hz)
20 f = 2 sin (pi * cutoff / fs) //[approximately]
21 q = resonance/bandwidth [0 < q <= 1] most res: q=1, less: q=0
22 low = lowpass output
23 high = highpass output
24 band = bandpass output
25 notch = notch output
26 
27 scale = q
28 
29 low=high=band=0;
30 
31 //--beginloop
32 low = low + f * band;
33 high = scale * input - low - q*band;
34 band = f * high + band;
35 notch = high + low;
36 //--endloop
37 ----------------------
38 References :
39 Hal Chamberlin, Musical Applications of Microprocessors, 2nd Ed, Hayden Book
40 Company 1985. pp 490-492. Jon Dattorro, Effect Design Part 1, J. Audio Eng.
41 Soc., Vol 45, No. 9, 1997 September
42 */
43 
44 #ifndef STATEVARIABLE_H_
45 #define STATEVARIABLE_H_
46 
47 #include "Arduino.h"
48 #include "math.h"
49 #include "meta.h"
50 #include "mozzi_fixmath.h"
51 #include "mozzi_utils.h"
52 #include "ResonantFilter.h"
53 
54 //enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
55 
56 /** A State Variable filter which offers 12db resonant low, high, bandpass and
57 notch modes.
58 @tparam FILTER_TYPE choose between LOWPASS, BANDPASS, HIGHPASS and NOTCH.
59 @note To save processing time, this version of the filter does not saturate
60 internally, so any resonant peaks are unceremoniously truncated. It may be
61 worth adding code to constrain the internal variables to enable resonant
62 saturating effects.
63 @todo Try adding code to constrain the internal variables to enable resonant
64 saturating effects.
65 */
66 template <int8_t FILTER_TYPE> class StateVariable {
67 
68 public:
69  /** Constructor.
70  */
72 
73  /** Set how resonant the filter will be.
74  @param resonance a byte value between 1 and 255.
75  The lower this value is, the more resonant the filter.
76  At very low values, the filter can output loud peaks which can exceed
77  Mozzi's output range, so you may need to attenuate the output in your sketch.
78  @note Timing < 500 ns
79  */
80  void setResonance(Q0n8 resonance) {
81  // qvalue goes from 255 to 0, representing .999 to 0 in fixed point
82  // lower q, more resonance
83  q = resonance;
84  scale = (Q0n8)sqrt((unsigned int)resonance << 8);
85  }
86 
87  /** Set the centre or corner frequency of the filter.
88  @param centre_freq 20 - 4096 Hz (AUDIO_RATE/4).
89  This will be the cut-off frequency for LOWPASS and HIGHPASS, and the
90  centre frequency to pass or reduce for BANDPASS and NOTCH.
91  @note Timing 25-30us
92  @note The frequency calculation is VERY "approximate". This really needs to
93  be fixed.
94  */
95  void setCentreFreq(unsigned int centre_freq) {
96  // simple frequency tuning with error towards nyquist (reference? where did
97  // this come from?)
98  // f = (Q1n15)(((Q16n16_2PI*centre_freq)>>AUDIO_RATE_AS_LSHIFT)>>1);
99  f = (Q15n16)((Q16n16_2PI * centre_freq) >>
100  (AUDIO_RATE_AS_LSHIFT)); // this works best for now
101  // f = (Q15n16)(((Q16n16_2PI*centre_freq)<<(16-AUDIO_RATE_AS_LSHIFT))>>16);
102  // // a small shift left and a round 16 right is faster than big
103  // non-byte-aligned right in one go float ff =
104  // Q16n16_to_float(((Q16n16_PI*centre_freq))>>AUDIO_RATE_AS_LSHIFT); f =
105  // float_to_Q15n16(2.0f *sin(ff));
106  }
107 
108  /** Calculate the next sample, given an input signal.
109  @param input the signal input.
110  @return the signal output.
111  @note Timing: 16 - 20 us
112  */
113  inline int next(int input) {
114  // chooses a different next() function depending on whether the
115  // filter is declared as LOWPASS, BANDPASS, HIGHPASS or NOTCH.
116  // See meta.h.
117  return next(input, Int2Type<FILTER_TYPE>());
118  }
119 
120 private:
121  int low, band;
122  Q0n8 q, scale;
123  volatile Q15n16 f;
124 
125  /** Calculate the next sample, given an input signal.
126  @param in the signal input.
127  @return the signal output.
128  @note Timing: 16 - 20 us
129  */
130  inline int next(int input, Int2Type<LOWPASS>) {
131  // setPin13High();
132  low += ((f * band) >> 16);
133  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
134  band += ((f * high) >> 16);
135  // int notch = high + low;
136  // setPin13Low();
137  return low;
138  }
139 
140  /** Calculate the next sample, given an input signal.
141  @param input the signal input.
142  @return the signal output.
143  @note Timing:
144  */
145  inline int next(int input, Int2Type<BANDPASS>) {
146  // setPin13High();
147  low += ((f * band) >> 16);
148  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
149  band += ((f * high) >> 16);
150  // int notch = high + low;
151  // setPin13Low();
152  return band;
153  }
154 
155  /** Calculate the next sample, given an input signal.
156  @param input the signal input.
157  @return the signal output.
158  @note Timing:
159  */
160  inline int next(int input, Int2Type<HIGHPASS>) {
161  // setPin13High();
162  low += ((f * band) >> 16);
163  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
164  band += ((f * high) >> 16);
165  // int notch = high + low;
166  // setPin13Low();
167  return high;
168  }
169 
170  /** Calculate the next sample, given an input signal.
171  @param input the signal input.
172  @return the signal output.
173  @note Timing: 16 - 20 us
174  */
175  inline int next(int input, Int2Type<NOTCH>) {
176  // setPin13High();
177  low += ((f * band) >> 16);
178  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
179  band += ((f * high) >> 16);
180  int notch = high + low;
181  // setPin13Low();
182  return notch;
183  }
184 };
185 
186 /**
187 @example 11.Audio_Filters/StateVariableFilter/StateVariableFilter.ino
188 This example demonstrates the StateVariable class.
189 */
190 
191 #endif /* STATEVARIABLE_H_ */
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:40
+
1 /*
2  * StateVariable.h
3  *
4  * This implementation copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 /**
14 State Variable Filter (approximation of Chamberlin version)
15 Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and
16 http://www.musicdsp.org/showone.php?id=142. Here's the original:
17 ---------------------
18 cutoff = cutoff freq in Hz
19 fs = sampling frequency //(e.g. 44100Hz)
20 f = 2 sin (pi * cutoff / fs) //[approximately]
21 q = resonance/bandwidth [0 < q <= 1] most res: q=1, less: q=0
22 low = lowpass output
23 high = highpass output
24 band = bandpass output
25 notch = notch output
26 
27 scale = q
28 
29 low=high=band=0;
30 
31 //--beginloop
32 low = low + f * band;
33 high = scale * input - low - q*band;
34 band = f * high + band;
35 notch = high + low;
36 //--endloop
37 ----------------------
38 References :
39 Hal Chamberlin, Musical Applications of Microprocessors, 2nd Ed, Hayden Book
40 Company 1985. pp 490-492. Jon Dattorro, Effect Design Part 1, J. Audio Eng.
41 Soc., Vol 45, No. 9, 1997 September
42 */
43 
44 #ifndef STATEVARIABLE_H_
45 #define STATEVARIABLE_H_
46 
47 #include "Arduino.h"
48 #include "math.h"
49 #include "meta.h"
50 #include "mozzi_fixmath.h"
51 #include "mozzi_utils.h"
52 #include "ResonantFilter.h"
53 
54 //enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
55 
56 /** A State Variable filter which offers 12db resonant low, high, bandpass and
57 notch modes.
58 @tparam FILTER_TYPE choose between LOWPASS, BANDPASS, HIGHPASS and NOTCH.
59 @note To save processing time, this version of the filter does not saturate
60 internally, so any resonant peaks are unceremoniously truncated. It may be
61 worth adding code to constrain the internal variables to enable resonant
62 saturating effects.
63 @todo Try adding code to constrain the internal variables to enable resonant
64 saturating effects.
65 */
66 template <int8_t FILTER_TYPE> class StateVariable {
67 
68 public:
69  /** Constructor.
70  */
72 
73  /** Set how resonant the filter will be.
74  @param resonance a byte value between 1 and 255.
75  The lower this value is, the more resonant the filter.
76  At very low values, the filter can output loud peaks which can exceed
77  Mozzi's output range, so you may need to attenuate the output in your sketch.
78  @note Timing < 500 ns
79  */
80  void setResonance(Q0n8 resonance) {
81  // qvalue goes from 255 to 0, representing .999 to 0 in fixed point
82  // lower q, more resonance
83  q = resonance;
84  scale = (Q0n8)sqrt((unsigned int)resonance << 8);
85  }
86 
87  /** Set the centre or corner frequency of the filter.
88  @param centre_freq 20 - 4096 Hz (MOZZI_AUDIO_RATE/4).
89  This will be the cut-off frequency for LOWPASS and HIGHPASS, and the
90  centre frequency to pass or reduce for BANDPASS and NOTCH.
91  @note Timing 25-30us
92  @note The frequency calculation is VERY "approximate". This really needs to
93  be fixed.
94  */
95  void setCentreFreq(unsigned int centre_freq) {
96  // simple frequency tuning with error towards nyquist (reference? where did
97  // this come from?)
98  // f = (Q1n15)(((Q16n16_2PI*centre_freq)>>AUDIO_RATE_AS_LSHIFT)>>1);
99  f = (Q15n16)((Q16n16_2PI * centre_freq) >>
100  (AUDIO_RATE_AS_LSHIFT)); // this works best for now
101  // f = (Q15n16)(((Q16n16_2PI*centre_freq)<<(16-AUDIO_RATE_AS_LSHIFT))>>16);
102  // // a small shift left and a round 16 right is faster than big
103  // non-byte-aligned right in one go float ff =
104  // Q16n16_to_float(((Q16n16_PI*centre_freq))>>AUDIO_RATE_AS_LSHIFT); f =
105  // float_to_Q15n16(2.0f *sin(ff));
106  }
107 
108  /** Calculate the next sample, given an input signal.
109  @param input the signal input.
110  @return the signal output.
111  @note Timing: 16 - 20 us
112  */
113  inline int next(int input) {
114  // chooses a different next() function depending on whether the
115  // filter is declared as LOWPASS, BANDPASS, HIGHPASS or NOTCH.
116  // See meta.h.
117  return next(input, Int2Type<FILTER_TYPE>());
118  }
119 
120 private:
121  int low, band;
122  Q0n8 q, scale;
123  volatile Q15n16 f;
124 
125  /** Calculate the next sample, given an input signal.
126  @param in the signal input.
127  @return the signal output.
128  @note Timing: 16 - 20 us
129  */
130  inline int next(int input, Int2Type<LOWPASS>) {
131  // setPin13High();
132  low += ((f * band) >> 16);
133  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
134  band += ((f * high) >> 16);
135  // int notch = high + low;
136  // setPin13Low();
137  return low;
138  }
139 
140  /** Calculate the next sample, given an input signal.
141  @param input the signal input.
142  @return the signal output.
143  @note Timing:
144  */
145  inline int next(int input, Int2Type<BANDPASS>) {
146  // setPin13High();
147  low += ((f * band) >> 16);
148  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
149  band += ((f * high) >> 16);
150  // int notch = high + low;
151  // setPin13Low();
152  return band;
153  }
154 
155  /** Calculate the next sample, given an input signal.
156  @param input the signal input.
157  @return the signal output.
158  @note Timing:
159  */
160  inline int next(int input, Int2Type<HIGHPASS>) {
161  // setPin13High();
162  low += ((f * band) >> 16);
163  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
164  band += ((f * high) >> 16);
165  // int notch = high + low;
166  // setPin13Low();
167  return high;
168  }
169 
170  /** Calculate the next sample, given an input signal.
171  @param input the signal input.
172  @return the signal output.
173  @note Timing: 16 - 20 us
174  */
175  inline int next(int input, Int2Type<NOTCH>) {
176  // setPin13High();
177  low += ((f * band) >> 16);
178  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
179  band += ((f * high) >> 16);
180  int notch = high + low;
181  // setPin13Low();
182  return notch;
183  }
184 };
185 
186 /**
187 @example 11.Audio_Filters/StateVariableFilter/StateVariableFilter.ino
188 This example demonstrates the StateVariable class.
189 */
190 
191 #endif /* STATEVARIABLE_H_ */
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:38
void setResonance(Q0n8 resonance)
Set how resonant the filter will be.
Definition: StateVariable.h:80
-
Enables you to instantiate a template based on an integer value.
Definition: meta.h:20
+
Enables you to instantiate a template based on an integer value.
Definition: meta.h:22
StateVariable()
Constructor.
Definition: StateVariable.h:71
int next(int input)
Calculate the next sample, given an input signal.
-
#define AUDIO_RATE_AS_LSHIFT
Definition: MozziGuts.h:193
State Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www...
Definition: StateVariable.h:66
-
#define Q16n16_2PI
2*PI in Q16n16 format
Definition: mozzi_fixmath.h:69
-
uint8_t Q0n8
unsigned fractional number using 8 fractional bits, represents 0.0 to 0.996
Definition: mozzi_fixmath.h:27
+
#define Q16n16_2PI
2*PI in Q16n16 format
Definition: mozzi_fixmath.h:67
+
uint8_t Q0n8
unsigned fractional number using 8 fractional bits, represents 0.0 to 0.996
Definition: mozzi_fixmath.h:25
void setCentreFreq(unsigned int centre_freq)
Set the centre or corner frequency of the filter.
Definition: StateVariable.h:95
@@ -119,7 +118,7 @@
-
1 /*
2  * Wavefolder.h
3  *
4  * Copyright 2022 Thomas Combriat
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #ifndef WAVEFOLDER_H
14 #define WAVEFOLDER_H
15 
16 
17 #include "IntegerType.h"
18 #include "AudioOutput.h"
19 
20 
21 /*
22  A simple wavefolder which folds the waves once it reachs the up or
23  low limits. The wave can be folded several times. It constrains the wave
24  to be constrain between the LowLimit and the HighLimit.
25  By default, this class is working on data which not overflow the
26  AudioOutputStorage_t type, which is int by default.
27  Feeding samples which, before folding, are overflowing this container
28  will lead to unpredicted behavior.
29  It is possible to use a bigger type with the template formulation
30  if needed.
31 */
32 
33 
34 /** A simple wavefolder
35  */
36 
37 template<typename T=AudioOutputStorage_t>
39 {
40 public:
41  /** Constructor
42  */
44 
45 
46  /** Set the high limit where the wave will start to be folded back the other way.
47  @param highLimit the high limit used by the wavefolder.
48  */
49  void setHighLimit(T highLimit)
50  {
51  hl = highLimit;
52  R = hl-ll;
53  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
54  }
55 
56 
57  /** Set the low limit where the wave will start to be folded back the other way.
58  @param lowLimit the low limit used by the wavefolder.
59  */
60  void setLowLimit(T lowLimit)
61  {
62  ll = lowLimit;
63  R = hl-ll;
64  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
65  }
66 
67 
68  /** Set the low and the high limits at the same time.
69  @param lowLimit the low limit used by the wavefolder
70  @param highLimit the high limit used by the wavefolder
71  @note highLimit MUST be higher than lowLimit
72  */
73  void setLimits(T lowLimit, T highLimit)
74  {
75  hl = highLimit;
76  ll = lowLimit;
77  R = hl-ll;
78  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
79  }
80 
81 
82  /** Return the next folded sample
83  @param in is the signal input.
84  @return the folded output.
85  */
86  T next(T in)
87  {
88  if (in > hl)
89  {
90  typename IntegerType<sizeof(T)>::unsigned_type sub = in-hl;
91  /* Instead of using a division, we multiply by the inverse.
92  As the inverse is necessary smaller than 1, in order to fit in an integer
93  we multiply it by NUMERATOR before computing the inverse.
94  The shift is equivalent to divide by the NUMERATOR:
95  q = sub / R = (sub * (NUMERATOR/R))/NUMERATOR with NUMERATOR/R = Ri
96  */
97  typename IntegerType<sizeof(T)>::unsigned_type q = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) sub*Ri) >> SHIFT;
98  typename IntegerType<sizeof(T)>::unsigned_type r = sub - q*R; // remainer
99  if (q&0b1) return ll+r; //odd
100  else return hl-r; // even
101 
102  }
103  else if (in < ll)
104  {
105  typename IntegerType<sizeof(T)>::unsigned_type sub = ll-in;
106  typename IntegerType<sizeof(T)>::unsigned_type q = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) sub*Ri) >> SHIFT;
107  typename IntegerType<sizeof(T)>::unsigned_type r = sub - q*R; // remainer
108  if (q&0b1) return hl-r;
109  else return ll+r;
110  }
111  else return in;
112  }
113 
114 private:
115  T hl;
116  T ll;
117  typename IntegerType<sizeof(T)>::unsigned_type R;
118  typename IntegerType<sizeof(T)>::unsigned_type Ri;
119  static const uint8_t SHIFT = (sizeof(T) << 3);
120  static const typename IntegerType<sizeof(T)>::unsigned_type NUMERATOR = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) 1<<(SHIFT))-1;
121 
122  // Slower (way slower, around 2.5 times) but more precise, kept in case we want to switch one day.
123  /* typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type Ri;
124  static const uint8_t SHIFT = 1+(sizeof(T) << 3);
125  static const typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type NUMERATOR = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) 1<<(SHIFT))-1;*/
126 
127 
128 };
129 
130 
131 #endif
void setHighLimit(T highLimit)
Set the high limit where the wave will start to be folded back the other way.
Definition: WaveFolder.h:49
+
1 /*
2  * Wavefolder.h
3  *
4  * Copyright 2022 Thomas Combriat
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #ifndef WAVEFOLDER_H
14 #define WAVEFOLDER_H
15 
16 
17 #include "IntegerType.h"
18 #include "AudioOutput.h"
19 
20 
21 /*
22  A simple wavefolder which folds the waves once it reachs the up or
23  low limits. The wave can be folded several times. It constrains the wave
24  to be constrain between the LowLimit and the HighLimit.
25  By default, this class is working on data which not overflow the
26  AudioOutputStorage_t type, which is int by default.
27  Feeding samples which, before folding, are overflowing this container
28  will lead to unpredicted behavior.
29  It is possible to use a bigger type with the template formulation
30  if needed.
31 */
32 
33 
34 /** A simple wavefolder
35  */
36 
37 template<typename T=AudioOutputStorage_t>
39 {
40 public:
41  /** Constructor
42  */
44 
45 
46  /** Set the high limit where the wave will start to be folded back the other way.
47  @param highLimit the high limit used by the wavefolder.
48  */
49  void setHighLimit(T highLimit)
50  {
51  hl = highLimit;
52  R = hl-ll;
53  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
54  }
55 
56 
57  /** Set the low limit where the wave will start to be folded back the other way.
58  @param lowLimit the low limit used by the wavefolder.
59  */
60  void setLowLimit(T lowLimit)
61  {
62  ll = lowLimit;
63  R = hl-ll;
64  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
65  }
66 
67 
68  /** Set the low and the high limits at the same time.
69  @param lowLimit the low limit used by the wavefolder
70  @param highLimit the high limit used by the wavefolder
71  @note highLimit MUST be higher than lowLimit
72  */
73  void setLimits(T lowLimit, T highLimit)
74  {
75  hl = highLimit;
76  ll = lowLimit;
77  R = hl-ll;
78  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
79  }
80 
81 
82  /** Return the next folded sample
83  @param in is the signal input.
84  @return the folded output.
85  */
86  T next(T in)
87  {
88  if (in > hl)
89  {
90  typename IntegerType<sizeof(T)>::unsigned_type sub = in-hl;
91  /* Instead of using a division, we multiply by the inverse.
92  As the inverse is necessary smaller than 1, in order to fit in an integer
93  we multiply it by NUMERATOR before computing the inverse.
94  The shift is equivalent to divide by the NUMERATOR:
95  q = sub / R = (sub * (NUMERATOR/R))/NUMERATOR with NUMERATOR/R = Ri
96  */
97  typename IntegerType<sizeof(T)>::unsigned_type q = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) sub*Ri) >> SHIFT;
98  typename IntegerType<sizeof(T)>::unsigned_type r = sub - q*R; // remainer
99  if (q&0b1) return ll+r; //odd
100  else return hl-r; // even
101 
102  }
103  else if (in < ll)
104  {
105  typename IntegerType<sizeof(T)>::unsigned_type sub = ll-in;
106  typename IntegerType<sizeof(T)>::unsigned_type q = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) sub*Ri) >> SHIFT;
107  typename IntegerType<sizeof(T)>::unsigned_type r = sub - q*R; // remainer
108  if (q&0b1) return hl-r;
109  else return ll+r;
110  }
111  else return in;
112  }
113 
114 private:
115  T hl;
116  T ll;
117  typename IntegerType<sizeof(T)>::unsigned_type R;
118  typename IntegerType<sizeof(T)>::unsigned_type Ri;
119  static const uint8_t SHIFT = (sizeof(T) << 3);
120  static const typename IntegerType<sizeof(T)>::unsigned_type NUMERATOR = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) 1<<(SHIFT))-1;
121 
122  // Slower (way slower, around 2.5 times) but more precise, kept in case we want to switch one day.
123  /* typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type Ri;
124  static const uint8_t SHIFT = 1+(sizeof(T) << 3);
125  static const typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type NUMERATOR = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) 1<<(SHIFT))-1;*/
126 
127 
128 };
129 
130 
131 #endif
Provides appropriate integer types that can bit the given number of bytes on this platform (at most 6...
Definition: IntegerType.h:9
+
void setHighLimit(T highLimit)
Set the high limit where the wave will start to be folded back the other way.
Definition: WaveFolder.h:49
void setLimits(T lowLimit, T highLimit)
Set the low and the high limits at the same time.
Definition: WaveFolder.h:73
void setLowLimit(T lowLimit)
Set the low limit where the wave will start to be folded back the other way.
Definition: WaveFolder.h:60
-
WaveFolder()
Constructor.
Definition: WaveFolder.h:43
A simple wavefolder.
Definition: WaveFolder.h:38
T next(T in)
Return the next folded sample.
Definition: WaveFolder.h:86
-
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:46
+
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:53
-
1 /*
2  * WavePacket.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 
13 #ifndef WAVEPACKET_H
14 #define WAVEPACKET_H
15 
16 #include <MozziGuts.h>
17 #include <Oscil.h>
18 #include <tables/cos8192_int8.h>
19 #include <mozzi_fixmath.h>
20 #include <Phasor.h>
21 #include <Line.h>
22 #include <meta.h>
23 
24 
25 enum algorithms {SINGLE,DOUBLE};
26 
27 /**
28 Wavepacket synthesis, with two overlapping streams of wave packets. Draws on
29 Miller Puckette's Pure Data example, F14.wave.packet.pd. Each packet is an
30 enveloped grain of a sin (or cos) wave. The frequency of the wave, the width of
31 the envelopes and the rate of release of envelopes are the parameters which can
32 be changed.
33 @tparam ALGORITHM options are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
34 */
35 template <int8_t ALGORITHM>
37 {
38 public:
39 
40  /** Constructor.
41  */
42  WavePacket():AUDIO_STEPS_PER_CONTROL(AUDIO_RATE / CONTROL_RATE)
43  {
44  aCos.setTable(COS8192_DATA);
45  }
46 
47 
48  /** Set all the parameters for the synthesis.
49  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
50  @param fundamental the rate at which packets are produced.
51  @param bandwidth the width of each packet. A lower value allows more
52  of the centre frequency to be audible, a rounder sound.
53  A higher value produces narrower packets, a more buzzing sound.
54  @param centrefreq the oscillation frequency within each packet.
55  */
56  inline
57  void set(int fundamental, int bandwidth, int centrefreq)
58  {
59  setFundamental(fundamental);
60  setBandwidth(bandwidth);
61  setCentreFreq(centrefreq);
62  }
63 
64 
65  /** Set the fundamental frequency.
66  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
67  @param fundamental the rate at which packets are produced.
68  */
69  inline
70  void setFundamental(int fundamental)
71  {
72  aPhasor.setFreq(fundamental);
73  invFreq = Q8n24_FIX1 / fundamental;
74  }
75 
76 
77 
78  /** Set the bandwidth.
79  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
80  @param bandwidth the width of each packet. A lower value allows more of the
81  centre frequency to be audible, a rounder sound.
82  A higher value produces narrower packets, a more buzzing sound.
83  */
84  inline
85  void setBandwidth(int bandwidth)
86  {
87  Q15n16 bw = invFreq*bandwidth;
88  bw >>= 9;
89  bw = max(bw, Q15n16_FIX1>>3);
90  aBandwidth.set(bw, AUDIO_STEPS_PER_CONTROL);
91  }
92 
93 
94 
95  /** Set the centre frequency.
96  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
97  @param centrefreq the oscillation frequency within each packet.
98  */
99  inline
100  void setCentreFreq(int centrefreq)
101  {
102  Q15n16 cf = invFreq * centrefreq;
103  cf >>= 3;
104  aCentrefreq.set(cf, AUDIO_STEPS_PER_CONTROL);
105  }
106 
107 
108 /** Calculate the next synthesised sample.
109 @return a full-scale 16 bit value, which needs to be scaled to suit your sketch. If you're using it straight as the sketch output,
110 then that will be yourThing.next()>>2 for HIFI 14 bit output, or >>8 for STANDARD 8+ bit output.
111 */
112  inline
113  int next()
114  {
115  gcentrefreq = aCentrefreq.next();
116  gbandwidth = aBandwidth.next();
117  int phase1 = aPhasor.next()>>16; // -0.5 to 0.5, 0n15
118  if (ALGORITHM == DOUBLE) {
119  return (signalPath(params1, phase1)+signalPath(params2, phase1+32768))>>1;
120  } else {
121  return signalPath(params1, phase1);
122  }
123  }
124 
125 
126 
127 private:
128  //Q15n16 fundamental; // range 4 to 6271 in pd patch, 13 integer bits
129  Q8n24 invFreq;
130  Q15n16 gcentrefreq; // range 0 to 3068, 12 integer bits
131  Q15n16 gbandwidth; // range 1 to 3068, 12 integer bits
132 
133  // Lines to interpolate controls at audio rate
134  Line <Q15n16> aCentrefreq;
135  Line <Q16n16> aBandwidth;
136  Line <Q16n16> aFreq;
137 
138  // different sets of params for each audio phase stream
139  struct parameters
140  {
141  int previous_phase;
142  Q15n16 centrefreq;
143  Q23n8 bandwidth;
144  }
145  params1,params2;
146 
147  // the number of audio steps the line has to take to reach the next control value
148  const unsigned int AUDIO_STEPS_PER_CONTROL;
149 
150  Oscil <COS8192_NUM_CELLS, AUDIO_RATE> aCos;
151  Phasor <AUDIO_RATE> aPhasor;
152 
153 
154  inline
155  int signalPath(struct parameters &param, int phase) // 25us? * 2
156  {
157  //setPin13High();
158  int index;
159 
160  if(phase<param.previous_phase)
161  {
162  param.centrefreq = gcentrefreq>>8;
163  param.bandwidth = Q15n16_to_Q23n8(gbandwidth);
164  }
165  param.previous_phase = phase;
166 
167  // oscillation
168  index = (param.centrefreq * phase)>>16;
169  // hack to make peak in middle of packet, otherwise it centres around a zero-crossing..
170  index += COS8192_NUM_CELLS>>1;
171  index &= COS8192_NUM_CELLS-1;
172  int8_t sig1 = aCos.atIndex(index);
173 
174  // packet envelope
175  Q23n8 bwphase = (param.bandwidth * phase)>>8;
176  bwphase += COS8192_NUM_CELLS>>1;
177  index = constrain(bwphase, 0, (COS8192_NUM_CELLS-1));
178  uint8_t packet_width = 128 + aCos.atIndex(index);
179  // if (AUDIO_MODE == HIFI){
180  // return ((int) sig1 * packet_width)>>3; // scaled to fit HIFI updateAudio output
181  // }else{
182  // return ((int) sig1 * packet_width)>>8; // scaled to fit STANDARD updateAudio output
183  // }
184 
185  return ((int) sig1 * packet_width);
186  }
187 
188 };
189 
190 /** @example 06.Synthesis/WavePacket/WavePacket.ino
191 This is an example of how to use the WavePacket class.
192 */
193 
194 #endif // #ifndef WAVEPACKET_H
void setCentreFreq(int centrefreq)
Set the centre frequency.
Definition: WavePacket.h:100
+
1 /*
2  * WavePacket.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 
13 #ifndef WAVEPACKET_H
14 #define WAVEPACKET_H
15 
16 #include "MozziHeadersOnly.h"
17 #include "Oscil.h"
18 #include "tables/cos8192_int8.h"
19 #include "mozzi_fixmath.h"
20 #include "Phasor.h"
21 #include "Line.h"
22 #include "meta.h"
23 
24 
25 enum algorithms {SINGLE,DOUBLE};
26 
27 /**
28 Wavepacket synthesis, with two overlapping streams of wave packets. Draws on
29 Miller Puckette's Pure Data example, F14.wave.packet.pd. Each packet is an
30 enveloped grain of a sin (or cos) wave. The frequency of the wave, the width of
31 the envelopes and the rate of release of envelopes are the parameters which can
32 be changed.
33 @tparam ALGORITHM options are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
34 */
35 template <int8_t ALGORITHM>
37 {
38 public:
39 
40  /** Constructor.
41  */
43  {
44  aCos.setTable(COS8192_DATA);
45  }
46 
47 
48  /** Set all the parameters for the synthesis.
49  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
50  @param fundamental the rate at which packets are produced.
51  @param bandwidth the width of each packet. A lower value allows more
52  of the centre frequency to be audible, a rounder sound.
53  A higher value produces narrower packets, a more buzzing sound.
54  @param centrefreq the oscillation frequency within each packet.
55  */
56  inline
57  void set(int fundamental, int bandwidth, int centrefreq)
58  {
59  setFundamental(fundamental);
60  setBandwidth(bandwidth);
61  setCentreFreq(centrefreq);
62  }
63 
64 
65  /** Set the fundamental frequency.
66  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
67  @param fundamental the rate at which packets are produced.
68  */
69  inline
70  void setFundamental(int fundamental)
71  {
72  aPhasor.setFreq(fundamental);
73  invFreq = Q8n24_FIX1 / fundamental;
74  }
75 
76 
77 
78  /** Set the bandwidth.
79  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
80  @param bandwidth the width of each packet. A lower value allows more of the
81  centre frequency to be audible, a rounder sound.
82  A higher value produces narrower packets, a more buzzing sound.
83  */
84  inline
85  void setBandwidth(int bandwidth)
86  {
87  Q15n16 bw = invFreq*bandwidth;
88  bw >>= 9;
89  bw = max(bw, Q15n16_FIX1>>3);
90  aBandwidth.set(bw, AUDIO_STEPS_PER_CONTROL);
91  }
92 
93 
94 
95  /** Set the centre frequency.
96  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
97  @param centrefreq the oscillation frequency within each packet.
98  */
99  inline
100  void setCentreFreq(int centrefreq)
101  {
102  Q15n16 cf = invFreq * centrefreq;
103  cf >>= 3;
104  aCentrefreq.set(cf, AUDIO_STEPS_PER_CONTROL);
105  }
106 
107 
108 /** Calculate the next synthesised sample.
109 @return a full-scale 16 bit value, which needs to be scaled to suit your sketch. If you're using it straight as the sketch output,
110 then that will be yourThing.next()>>2 for HIFI 14 bit output, or >>8 for STANDARD 8+ bit output.
111 */
112  inline
113  int next()
114  {
115  gcentrefreq = aCentrefreq.next();
116  gbandwidth = aBandwidth.next();
117  int phase1 = aPhasor.next()>>16; // -0.5 to 0.5, 0n15
118  if (ALGORITHM == DOUBLE) {
119  return (signalPath(params1, phase1)+signalPath(params2, phase1+32768))>>1;
120  } else {
121  return signalPath(params1, phase1);
122  }
123  }
124 
125 
126 
127 private:
128  //Q15n16 fundamental; // range 4 to 6271 in pd patch, 13 integer bits
129  Q8n24 invFreq;
130  Q15n16 gcentrefreq; // range 0 to 3068, 12 integer bits
131  Q15n16 gbandwidth; // range 1 to 3068, 12 integer bits
132 
133  // Lines to interpolate controls at audio rate
134  Line <Q15n16> aCentrefreq;
135  Line <Q16n16> aBandwidth;
136  Line <Q16n16> aFreq;
137 
138  // different sets of params for each audio phase stream
139  struct parameters
140  {
141  int previous_phase;
142  Q15n16 centrefreq;
143  Q23n8 bandwidth;
144  }
145  params1,params2;
146 
147  // the number of audio steps the line has to take to reach the next control value
148  const unsigned int AUDIO_STEPS_PER_CONTROL;
149 
150  Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aCos;
151  Phasor <MOZZI_AUDIO_RATE> aPhasor;
152 
153 
154  inline
155  int signalPath(struct parameters &param, int phase) // 25us? * 2
156  {
157  //setPin13High();
158  int index;
159 
160  if(phase<param.previous_phase)
161  {
162  param.centrefreq = gcentrefreq>>8;
163  param.bandwidth = Q15n16_to_Q23n8(gbandwidth);
164  }
165  param.previous_phase = phase;
166 
167  // oscillation
168  index = (param.centrefreq * phase)>>16;
169  // hack to make peak in middle of packet, otherwise it centres around a zero-crossing..
170  index += COS8192_NUM_CELLS>>1;
171  index &= COS8192_NUM_CELLS-1;
172  int8_t sig1 = aCos.atIndex(index);
173 
174  // packet envelope
175  Q23n8 bwphase = (param.bandwidth * phase)>>8;
176  bwphase += COS8192_NUM_CELLS>>1;
177  index = constrain(bwphase, 0, (COS8192_NUM_CELLS-1));
178  uint8_t packet_width = 128 + aCos.atIndex(index);
179  // if (AUDIO_MODE == HIFI){
180  // return ((int) sig1 * packet_width)>>3; // scaled to fit HIFI updateAudio output
181  // }else{
182  // return ((int) sig1 * packet_width)>>8; // scaled to fit STANDARD updateAudio output
183  // }
184 
185  return ((int) sig1 * packet_width);
186  }
187 
188 };
189 
190 /** @example 06.Synthesis/WavePacket/WavePacket.ino
191 This is an example of how to use the WavePacket class.
192 */
193 
194 #endif // #ifndef WAVEPACKET_H
void setCentreFreq(int centrefreq)
Set the centre frequency.
Definition: WavePacket.h:100
+
#define MOZZI_CONTROL_RATE
Control rate setting.
int next()
Calculate the next synthesised sample.
Definition: WavePacket.h:113
-
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:40
+
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:38
WavePacket()
Constructor.
Definition: WavePacket.h:42
-
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:62
void set(int fundamental, int bandwidth, int centrefreq)
Set all the parameters for the synthesis.
Definition: WavePacket.h:57
void setFundamental(int fundamental)
Set the fundamental frequency.
Definition: WavePacket.h:70
-
#define AUDIO_RATE
Holds the audio rate setting.
Definition: mozzi_config.h:62
-
For linear changes with a minimum of calculation at each step.
Definition: Line.h:37
-
#define Q15n16_FIX1
1 in Q15n16 format
Definition: mozzi_fixmath.h:63
+
For linear changes with a minimum of calculation at each step.
Definition: Line.h:33
+
#define Q15n16_FIX1
1 in Q15n16 format
Definition: mozzi_fixmath.h:61
void setBandwidth(int bandwidth)
Set the bandwidth.
Definition: WavePacket.h:85
Wavepacket synthesis, with two overlapping streams of wave packets.
Definition: WavePacket.h:36
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46
-
uint32_t Q8n24
signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:44
-
#define Q8n24_FIX1
1 in Q8n24 format
Definition: mozzi_fixmath.h:64
-
Phasor repeatedly generates a high resolution ramp at a variable frequency.
Definition: Phasor.h:32
-
int32_t Q23n8
signed fractional number using 23 integer bits and 8 fractional bits, represents -8388607.996 to 8388607.996
Definition: mozzi_fixmath.h:39
+
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:44
+
uint32_t Q8n24
signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:42
+
#define Q8n24_FIX1
1 in Q8n24 format
Definition: mozzi_fixmath.h:62
+
int32_t Q23n8
signed fractional number using 23 integer bits and 8 fractional bits, represents -8388607.996 to 8388607.996
Definition: mozzi_fixmath.h:37
-
1 /*
2  * WavePacketSample.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef WAVEPACKETSAMPLE_H
13 #define WAVEPACKETSAMPLE_H
14 
15 
16 #include "WavePacket.h"
17 /** A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains).
18 @tparam ALGORITHM options are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
19 
20 */
21 template <int8_t ALGORITHM>
22 class WavePacketSample: public WavePacket<ALGORITHM>
23 {
24 public:
25  /** Change the sound table which will be played. Needs to be 8192 cells long for now.
26  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
27  */
28  inline
29  void setTable(const int8_t * TABLE_NAME)
30  {
31  aWav.setTable(TABLE_NAME);
32  }
33 
34 private:
35  Oscil <8192, AUDIO_RATE> aWav;
36 };
37 
38 /** @example 06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino
39 This is an example of how to use the WavePacketSample class.
40 */
41 #endif // #ifndef WAVEPACKETSAMPLE_H
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:62
-
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played.
-
#define AUDIO_RATE
Holds the audio rate setting.
Definition: mozzi_config.h:62
+
1 /*
2  * WavePacketSample.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef WAVEPACKETSAMPLE_H
13 #define WAVEPACKETSAMPLE_H
14 
15 
16 #include "WavePacket.h"
17 /** A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains).
18 @tparam ALGORITHM options are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
19 
20 */
21 template <int8_t ALGORITHM>
22 class WavePacketSample: public WavePacket<ALGORITHM>
23 {
24 public:
25  /** Change the sound table which will be played. Needs to be 8192 cells long for now.
26  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
27  */
28  inline
29  void setTable(const int8_t * TABLE_NAME)
30  {
31  aWav.setTable(TABLE_NAME);
32  }
33 
34 private:
35  Oscil <8192, MOZZI_AUDIO_RATE> aWav;
36 };
37 
38 /** @example 06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino
39 This is an example of how to use the WavePacketSample class.
40 */
41 #endif // #ifndef WAVEPACKETSAMPLE_H
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played.
A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains...
Wavepacket synthesis, with two overlapping streams of wave packets.
Definition: WavePacket.h:36
@@ -114,7 +112,7 @@
-
1 #! /usr/bin/python
2 #
3 # Generator for compressed Arduino audio data
4 # Thomas Grill, 2011
5 # http://grrrr.org
6 #
7 # Modified by TIm Barrass 2013
8 # - changed PROGMEM to CONSTTABLE_STORAGE, to stop compiler warning
9 # - moved huffman table to progmem
10 # - added --name argument to give all constants specific names
11 # - changed all constant names to upper case
12 # - added include guards, Arduino and avr includes
13 #
14 # Dependencies:
15 # Numerical Python (numpy): http://numpy.scipy.org/
16 # scikits.audiolab: http://pypi.python.org/pypi/scikits.audiolab/
17 # purehuff: https://grrrr.org/data/dev/purehuff/
18 # pylab / matplotlib (only for plotting): http://matplotlib.sourceforge.net/
19 #
20 # For help on options invoke with:
21 # audio2huff --help
22 
23 import sys,os.path
24 from itertools import imap,chain,izip
25 
26 try:
27  import numpy as N
28 except ImportError:
29  print >>sys.stderr, "Error: Numerical Python not found"
30  exit(-1)
31 
32 try:
33  from scikits.audiolab import Sndfile
34 except ImportError:
35  print >>sys.stderr, "Error: scikits.audiolab not found"
36  exit(-1)
37 
38 try:
39  import purehuff
40 except ImportError:
41  print >>sys.stderr, "Error: purehuff module not found"
42  exit(-1)
43 
44 def grouper(n,seq):
45  """group list elements"""
46  it = iter(seq)
47  while True:
48  l = [v for _,v in izip(xrange(n),it)]
49  if l:
50  yield l
51  if len(l) < n:
52  break
53 
54 def arrayformatter(seq,perline=40):
55  """format list output linewise"""
56  return ",\n".join(",".join(imap(str,s)) for s in grouper(perline,seq))
57 
58 if __name__ == "__main__":
59  from optparse import OptionParser
60  parser = OptionParser()
61  parser.add_option("--bits", type="int", default=8, dest="bits",help="bit resolution")
62  parser.add_option("--sndfile", dest="sndfile",help="input sound file")
63  parser.add_option("--hdrfile", dest="hdrfile",help="output C header file")
64  parser.add_option("--name", dest="name",help="prefix for tables and constants in file")
65  parser.add_option("--plothist", type="int", default=0, dest="plothist",help="plot histogram")
66  (options, args) = parser.parse_args()
67 
68  if not options.sndfile:
69  print >>sys.stderr,"Error: --sndfile argument required"
70  exit(-1)
71 
72  sndf = Sndfile(options.sndfile,'r')
73  sound = sndf.read_frames(sndf.nframes)
74  fs = sndf.samplerate
75  del sndf
76 
77  # mix down multi-channel audio
78  if len(sound.shape) > 1:
79  sound = N.mean(sound,axis=1)
80 
81  # convert to n bits (no dithering, except it has already been done with the same bit resolution for the soundfile)
82  sound8 = N.clip((sound*(2**(options.bits-1))).astype(int),-2**(options.bits-1),2**(options.bits-1)-1)
83  # the following mapping with int is necessary as numpy.int32 types are not digested well by the HuffmanTree class
84  dsound8 = map(int,chain((sound8[0],),imap(lambda x: x[1]-x[0],izip(sound8[:-1],sound8[1:]))))
85 
86  print >>sys.stderr,"min/max: %i/%i"%(N.min(sound8),N.max(sound8))
87  print >>sys.stderr,"data bits: %i"%(len(sound8)*options.bits)
88 
89  hist = purehuff.histogram(dsound8)
90 
91  if options.plothist:
92  try:
93  import pylab as P
94  except ImportError:
95  print >>sys.stderr, "Plotting needs pylab"
96 
97  from collections import defaultdict
98  d = defaultdict(float)
99  for n,v in hist:
100  d[v] += n
101  x = range(min(d.iterkeys()),max(d.iterkeys())+1)
102  y = [d[xi] for xi in x]
103 
104  P.title("Histogram of sample differentials, file %s"%os.path.split(options.sndfile)[-1])
105  P.plot(x,y,marker='x')
106  P.show()
107 
108  hufftree = purehuff.HuffTree(hist)
109 
110  # get decoder instance
111  decoder = hufftree.decoder()
112  # get encoder instance
113  encoder = hufftree.encoder()
114  # encode data
115  enc = encoder(dsound8)
116 
117  print >>sys.stderr,"encoded bits: %i"%len(enc)
118  print >>sys.stderr,"ratio: %.0f%%"%((len(enc)*100.)/(len(sound8)*8))
119  print >>sys.stderr,"decoder length: %.0f words"%(len(decoder.huff))
120 
121  if options.hdrfile:
122  hdrf = file(options.hdrfile,'wt')
123  print >>hdrf,"// generated by Mozzi/extras/python/audio2huff.py \n"
124  print >>hdrf,"#ifndef " + options.name + "_H_"
125  print >>hdrf,"#define " + options.name + "_H_\n"
126  print >>hdrf,'#if ARDUINO >= 100'
127  print >>hdrf,'#include "Arduino.h"'
128  print >>hdrf,'#else'
129  print >>hdrf,'#include "WProgram.h"'
130  print >>hdrf,'#endif \n'
131  print >>hdrf,'#include "mozzi_pgmspace.h"\n \n'
132  print >>hdrf,"#define " + options.name + "_SAMPLERATE %i"%fs
133  print >>hdrf,"#define " + options.name + "_SAMPLE_BITS %i"%options.bits
134  print >>hdrf,'CONSTTABLE_STORAGE(int) ' + options.name + '_HUFFMAN[%i] = {\n%s\n};'%(len(decoder.huff),arrayformatter(decoder.huff))
135  print >>hdrf,'unsigned long const ' + options.name + '_SOUNDDATA_BITS = %iL;'%len(enc)
136  print >>hdrf,'CONSTTABLE_STORAGE(unsigned char) ' + options.name + '_SOUNDDATA[] = {\n%s\n};'%arrayformatter(enc.data)
137  print >>hdrf,"#endif /* " + options.name + "_H_ */"
+
1 #! /usr/bin/python
2 #
3 # Generator for compressed Arduino audio data
4 # Thomas Grill, 2011
5 # http://grrrr.org
6 #
7 # Modified by TIm Barrass 2013
8 # - changed PROGMEM to CONSTTABLE_STORAGE, to stop compiler warning
9 # - moved huffman table to progmem
10 # - added --name argument to give all constants specific names
11 # - changed all constant names to upper case
12 # - added include guards, Arduino and avr includes
13 #
14 # Dependencies:
15 # Numerical Python (numpy): http://numpy.scipy.org/
16 # scikits.audiolab: http://pypi.python.org/pypi/scikits.audiolab/
17 # purehuff: https://grrrr.org/data/dev/purehuff/
18 # pylab / matplotlib (only for plotting): http://matplotlib.sourceforge.net/
19 #
20 # NOTE: the scikits.audiolab dependency requires Python 2!
21 # see https://github.com/Roger-random/mozzi_wilhelm/issues/1#issuecomment-770141226
22 #
23 #For help on options invoke with:
24 # audio2huff --help
25 
26 import sys,os.path
27 from itertools import imap,chain,izip
28 
29 try:
30  import numpy as N
31 except ImportError:
32  print >>sys.stderr, "Error: Numerical Python not found"
33  exit(-1)
34 
35 try:
36  from scikits.audiolab import Sndfile
37 except ImportError:
38  print >>sys.stderr, "Error: scikits.audiolab not found"
39  exit(-1)
40 
41 try:
42  import purehuff
43 except ImportError:
44  print >>sys.stderr, "Error: purehuff module not found"
45  exit(-1)
46 
47 def grouper(n,seq):
48  """group list elements"""
49  it = iter(seq)
50  while True:
51  l = [v for _,v in izip(xrange(n),it)]
52  if l:
53  yield l
54  if len(l) < n:
55  break
56 
57 def arrayformatter(seq,perline=40):
58  """format list output linewise"""
59  return ",\n".join(",".join(imap(str,s)) for s in grouper(perline,seq))
60 
61 if __name__ == "__main__":
62  from optparse import OptionParser
63  parser = OptionParser()
64  parser.add_option("--bits", type="int", default=8, dest="bits",help="bit resolution")
65  parser.add_option("--sndfile", dest="sndfile",help="input sound file")
66  parser.add_option("--hdrfile", dest="hdrfile",help="output C header file")
67  parser.add_option("--name", dest="name",help="prefix for tables and constants in file")
68  parser.add_option("--plothist", type="int", default=0, dest="plothist",help="plot histogram")
69  (options, args) = parser.parse_args()
70 
71  if not options.sndfile:
72  print >>sys.stderr,"Error: --sndfile argument required"
73  exit(-1)
74 
75  sndf = Sndfile(options.sndfile,'r')
76  sound = sndf.read_frames(sndf.nframes)
77  fs = sndf.samplerate
78  del sndf
79 
80  # mix down multi-channel audio
81  if len(sound.shape) > 1:
82  sound = N.mean(sound,axis=1)
83 
84  # convert to n bits (no dithering, except it has already been done with the same bit resolution for the soundfile)
85  sound8 = N.clip((sound*(2**(options.bits-1))).astype(int),-2**(options.bits-1),2**(options.bits-1)-1)
86  # the following mapping with int is necessary as numpy.int32 types are not digested well by the HuffmanTree class
87  dsound8 = map(int,chain((sound8[0],),imap(lambda x: x[1]-x[0],izip(sound8[:-1],sound8[1:]))))
88 
89  print >>sys.stderr,"min/max: %i/%i"%(N.min(sound8),N.max(sound8))
90  print >>sys.stderr,"data bits: %i"%(len(sound8)*options.bits)
91 
92  hist = purehuff.histogram(dsound8)
93 
94  if options.plothist:
95  try:
96  import pylab as P
97  except ImportError:
98  print >>sys.stderr, "Plotting needs pylab"
99 
100  from collections import defaultdict
101  d = defaultdict(float)
102  for n,v in hist:
103  d[v] += n
104  x = range(min(d.iterkeys()),max(d.iterkeys())+1)
105  y = [d[xi] for xi in x]
106 
107  P.title("Histogram of sample differentials, file %s"%os.path.split(options.sndfile)[-1])
108  P.plot(x,y,marker='x')
109  P.show()
110 
111  hufftree = purehuff.HuffTree(hist)
112 
113  # get decoder instance
114  decoder = hufftree.decoder()
115  # get encoder instance
116  encoder = hufftree.encoder()
117  # encode data
118  enc = encoder(dsound8)
119 
120  print >>sys.stderr,"encoded bits: %i"%len(enc)
121  print >>sys.stderr,"ratio: %.0f%%"%((len(enc)*100.)/(len(sound8)*8))
122  print >>sys.stderr,"decoder length: %.0f words"%(len(decoder.huff))
123 
124  if options.hdrfile:
125  hdrf = file(options.hdrfile,'wt')
126  print >>hdrf,"// generated by Mozzi/extras/python/audio2huff.py \n"
127  print >>hdrf,"#ifndef " + options.name + "_H_"
128  print >>hdrf,"#define " + options.name + "_H_\n"
129  print >>hdrf,'#if ARDUINO >= 100'
130  print >>hdrf,'#include <Arduino.h>\n'
131  print >>hdrf,'#include "mozzi_pgmspace.h"\n \n'
132  print >>hdrf,"#define " + options.name + "_SAMPLERATE %i"%fs
133  print >>hdrf,"#define " + options.name + "_SAMPLE_BITS %i"%options.bits
134  print >>hdrf,'CONSTTABLE_STORAGE(int) ' + options.name + '_HUFFMAN[%i] = {\n%s\n};'%(len(decoder.huff),arrayformatter(decoder.huff))
135  print >>hdrf,'unsigned long const ' + options.name + '_SOUNDDATA_BITS = %iL;'%len(enc)
136  print >>hdrf,'CONSTTABLE_STORAGE(unsigned char) ' + options.name + '_SOUNDDATA[] = {\n%s\n};'%arrayformatter(enc.data)
137  print >>hdrf,"#endif /* " + options.name + "_H_ */"
-
1 #ifndef BLAHBLAH4B_H_
2 #define BLAHBLAH4B_H_
3 
4 #if ARDUINO >= 100
5 #include "Arduino.h"
6 #else
7 #include "WProgram.h"
8 #endif
9 #include "mozzi_pgmspace.h"
10 
11 #define BLAHBLAH4B_NUM_CELLS 22569
12 #define BLAHBLAH4B_SAMPLERATE 16384
13 
14 CONSTTABLE_STORAGE(int8_t) BLAHBLAH4B_DATA [] = { -1, 2, 6, 9, 12, 15, 17, 20, 22, 25, 28, 30,
15 32, 34, 37, 38, 40, 42, 44, 46, 47, 49, 50, 52, 53, 53, 54, 55, 55, 55, 54, 54,
16 53, 51, 48, 46, 42, 38, 34, 29, 25, 20, 15, 10, 5, -1, -6, -11, -16, -21, -25,
17 -29, -33, -37, -40, -43, -47, -50, -52, -55, -57, -58, -59, -59, -59, -59, -58,
18 -57, -56, -55, -54, -53, -51, -50, -48, -45, -42, -39, -35, -32, -27, -23, -18,
19 -14, -9, -5, -1, 3, 7, 10, 13, 16, 19, 22, 25, 28, 30, 33, 36, 38, 40, 43, 45,
20 47, 49, 51, 53, 54, 56, 57, 57, 58, 58, 58, 58, 58, 57, 56, 55, 52, 49, 46, 41,
21 37, 33, 28, 23, 17, 12, 7, 1, -5, -10, -15, -20, -25, -30, -34, -38, -42, -46,
22 -49, -52, -55, -57, -59, -61, -62, -63, -62, -62, -61, -60, -59, -58, -57, -56,
23 -54, -52, -51, -48, -45, -42, -38, -34, -31, -26, -22, -18, -13, -9, -5, -1, 3,
24 6, 9, 12, 15, 18, 21, 24, 27, 29, 32, 34, 37, 39, 41, 43, 45, 47, 49, 51, 53,
25 55, 56, 57, 59, 59, 59, 59, 58, 58, 57, 55, 53, 50, 47, 43, 38, 34, 29, 24, 19,
26 15, 9, 4, -2, -8, -13, -18, -24, -28, -32, -37, -40, -44, -47, -50, -54, -56,
27 -59, -61, -62, -64, -64, -64, -63, -62, -61, -60, -58, -58, -57, -55, -53, -50,
28 -48, -45, -42, -39, -35, -31, -27, -22, -22, -17, -8, -2, 4, 8, 12, 14, 17, 21,
29 23, 25, 28, 30, 32, 36, 39, 42, 44, 45, 46, 48, 50, 51, 53, 54, 56, 58, 58, 60,
30 60, 59, 59, 57, 55, 53, 51, 49, 46, 42, 39, 35, 29, 24, 19, 13, 8, 2, -4, -10,
31 -15, -20, -27, -31, -33, -39, -41, -45, -49, -50, -55, -56, -59, -61, -62, -64,
32 -64, -63, -62, -61, -59, -58, -54, -52, -50, -47, -44, -42, -42, -41, -39, -37,
33 -35, -34, -33, -30, -23, -15, -8, -2, 4, 6, 8, 11, 13, 16, 22, 26, 27, 27, 27,
34 28, 29, 29, 30, 33, 36, 40, 44, 47, 49, 49, 48, 48, 47, 46, 47, 48, 51, 53, 55,
35 56, 57, 56, 53, 49, 43, 39, 34, 30, 26, 22, 19, 17, 14, 9, 3, -2, -8, -14, -22,
36 -28, -32, -36, -38, -39, -41, -41, -43, -46, -49, -52, -55, -58, -60, -61, -59,
37 -58, -57, -55, -52, -50, -51, -51, -50, -49, -48, -47, -46, -42, -37, -34, -29,
38 -24, -20, -16, -12, -10, -7, -3, 0, 3, 6, 10, 14, 17, 20, 23, 26, 28, 29, 31,
39 33, 35, 36, 39, 42, 44, 47, 48, 50, 52, 53, 53, 54, 54, 55, 56, 56, 56, 56, 56,
40 54, 51, 47, 42, 37, 33, 29, 24, 19, 15, 10, 6, 0, -5, -10, -15, -21, -27, -33,
41 -37, -40, -42, -45, -48, -48, -50, -53, -55, -56, -57, -59, -60, -60, -58, -57,
42 -56, -55, -53, -52, -54, -53, -49, -48, -46, -48, -48, -48, -52, -43, -28, -21,
43 -14, -17, -20, -9, 0, 7, 14, 14, 13, 15, 21, 29, 34, 33, 32, 32, 32, 37, 44, 46,
44 46, 46, 45, 46, 49, 55, 56, 55, 55, 51, 49, 52, 54, 57, 58, 56, 55, 54, 52, 50,
45 48, 44, 35, 28, 23, 17, 13, 10, 5, -2, -11, -20, -26, -27, -33, -41, -44, -51,
46 -59, -62, -64, -65, -65, -66, -68, -70, -68, -67, -66, -63, -65, -59, -54, -57,
47 -52, -41, -38, -41, -43, -38, -32, -32, -31, -27, -23, -20, -23, -24, -12, -3,
48 0, 7, 11, 11, 14, 13, 17, 22, 16, 15, 20, 23, 28, 34, 38, 43, 40, 37, 37, 38,
49 44, 47, 47, 48, 47, 48, 51, 53, 57, 56, 54, 55, 56, 55, 55, 54, 54, 50, 43, 40,
50 39, 36, 32, 26, 16, 7, 0, -7, -14, -19, -23, -29, -38, -47, -52, -60, -65, -72,
51 -80, -84, -86, -87, -85, -86, -83, -84, -86, -82, -79, -73, -64, -57, -41, -30,
52 -32, -27, -15, -5, -6, -10, 0, 12, 16, 15, 19, 30, 33, 28, 29, 31, 31, 31, 21,
53 17, 17, 15, 18, 19, 22, 20, 17, 19, 19, 17, 14, 8, 8, 11, 11, 10, 8, 15, 21, 16,
54 10, 15, 24, 23, 18, 24, 30, 29, 30, 35, 37, 36, 37, 38, 40, 40, 37, 40, 43, 40,
55 34, 30, 27, 26, 19, 13, 9, 4, -1, -9, -15, -18, -28, -34, -37, -48, -54, -58,
56 -61, -60, -67, -71, -72, -72, -70, -77, -76, -70, -69, -68, -66, -60, -52, -42,
57 -33, -35, -32, -20, -14, -14, -15, -6, 6, 8, 7, 13, 22, 28, 26, 29, 36, 32, 32,
58 37, 40, 41, 39, 42, 48, 46, 42, 36, 33, 34, 30, 26, 23, 22, 26, 25, 19, 14, 16,
59 21, 13, 9, 16, 19, 16, 13, 18, 21, 14, 17, 21, 20, 20, 21, 27, 31, 26, 26, 26,
60 25, 24, 20, 18, 16, 14, 11, 5, 3, 0, -7, -10, -16, -20, -28, -33, -33, -39, -43,
61 -50, -53, -51, -58, -61, -60, -61, -61, -62, -63, -60, -60, -58, -53, -53, -52,
62 -48, -37, -25, -25, -24, -11, -1, -1, -3, 2, 13, 17, 18, 19, 24, 33, 36, 37, 38,
63 38, 37, 38, 39, 39, 39, 41, 41, 39, 38, 33, 29, 28, 25, 23, 18, 16, 18, 18, 14,
64 8, 4, 9, 14, 6, 1, 10, 18, 14, 8, 11, 16, 15, 15, 18, 19, 21, 25, 28, 31, 28,
65 23, 25, 28, 23, 15, 12, 19, 20, 10, 3, 1, -2, -7, -16, -22, -27, -30, -31, -37,
66 -46, -51, -52, -53, -57, -63, -66, -64, -62, -63, -65, -65, -61, -57, -56, -57,
67 -54, -51, -46, -40, -35, -24, -17, -15, -5, 4, 7, 2, 5, 20, 27, 24, 25, 31, 43,
68 46, 39, 39, 44, 44, 41, 38, 40, 42, 42, 43, 39, 35, 31, 26, 24, 23, 18, 14, 12,
69 13, 13, 8, 2, 4, 11, 8, -2, 1, 10, 10, 6, 6, 11, 11, 10, 12, 14, 17, 18, 20, 26,
70 26, 21, 20, 24, 24, 15, 10, 13, 15, 9, 3, 3, 0, -7, -13, -18, -21, -29, -34,
71 -32, -37, -46, -49, -49, -50, -56, -59, -59, -61, -59, -58, -59, -57, -54, -51,
72 -50, -49, -47, -42, -38, -36, -34, -24, -10, -11, -9, 3, 12, 13, 7, 14, 28, 30,
73 29, 30, 39, 48, 44, 44, 50, 49, 45, 43, 43, 44, 41, 39, 41, 38, 35, 29, 23, 23,
74 20, 14, 8, 4, 4, 6, 1, -2, 0, 5, 1, -5, -2, 2, 2, 1, 4, 8, 8, 8, 13, 16, 18, 17,
75 20, 26, 25, 21, 21, 23, 22, 17, 13, 14, 12, 9, 6, 3, -1, -8, -13, -14, -20, -29,
76 -32, -30, -36, -47, -45, -46, -51, -52, -55, -54, -55, -56, -53, -54, -52, -49,
77 -49, -44, -43, -42, -35, -34, -32, -27, -25, -15, -1, -3, -3, 8, 18, 17, 10, 18,
78 30, 30, 31, 29, 35, 45, 42, 40, 44, 43, 39, 37, 38, 38, 33, 34, 33, 30, 29, 22,
79 17, 17, 15, 11, 4, 0, 1, 4, 3, -4, -4, 5, 4, -4, -3, 4, 6, 5, 5, 11, 13, 13, 16,
80 19, 22, 19, 19, 27, 26, 20, 18, 21, 22, 16, 11, 8, 8, 7, -1, -6, -9, -16, -19,
81 -21, -27, -36, -38, -35, -43, -50, -47, -50, -53, -51, -52, -54, -54, -51, -47,
82 -48, -48, -44, -41, -36, -36, -36, -29, -27, -23, -19, -19, -13, 1, 8, 2, 4, 16,
83 22, 17, 15, 24, 32, 32, 28, 30, 38, 39, 34, 36, 41, 35, 29, 31, 32, 30, 25, 22,
84 23, 22, 18, 12, 10, 11, 8, 3, -1, -4, -2, 3, 0, -2, 3, 6, 3, 2, 6, 8, 7, 8, 13,
85 17, 17, 16, 22, 25, 23, 19, 21, 24, 19, 15, 16, 17, 12, 6, 5, 5, 0, -10, -11,
86 -9, -17, -26, -29, -28, -32, -40, -41, -41, -45, -46, -47, -50, -50, -50, -49,
87 -48, -49, -45, -42, -41, -37, -36, -34, -32, -30, -25, -22, -20, -17, -14, -5,
88 9, 6, 0, 11, 21, 22, 12, 13, 28, 32, 28, 24, 26, 35, 34, 30, 33, 34, 30, 29, 30,
89 29, 25, 21, 23, 22, 20, 16, 10, 13, 14, 9, 3, -3, -2, 3, 2, -4, -4, 7, 9, 0, -1,
90 5, 7, 4, 5, 10, 13, 13, 14, 18, 21, 18, 15, 21, 24, 16, 13, 14, 18, 14, 6, 3, 6,
91 5, -6, -7, -4, -14, -20, -17, -21, -31, -35, -29, -33, -39, -37, -40, -43, -39,
92 -43, -46, -42, -42, -41, -36, -36, -35, -32, -28, -29, -31, -25, -22, -23, -18,
93 -16, -16, -4, 6, -1, -2, 8, 13, 11, 6, 10, 20, 22, 19, 14, 20, 27, 22, 21, 28,
94 26, 22, 25, 24, 22, 21, 16, 16, 17, 15, 11, 9, 12, 11, 7, 2, -2, -1, 4, 3, -2,
95 3, 9, 8, 6, 4, 8, 12, 11, 9, 14, 19, 18, 19, 24, 26, 22, 22, 28, 27, 21, 19, 21,
96 22, 17, 9, 9, 11, 5, -3, -2, -2, -11, -18, -15, -20, -32, -32, -30, -35, -38,
97 -38, -40, -42, -42, -43, -46, -44, -41, -41, -38, -37, -37, -33, -31, -31, -30,
98 -27, -25, -25, -20, -19, -20, -16, -3, 2, -6, -4, 5, 12, 7, 0, 9, 19, 18, 13,
99 11, 19, 22, 19, 20, 23, 22, 22, 23, 22, 23, 18, 16, 18, 16, 15, 12, 11, 14, 13,
100 11, 5, 2, 5, 9, 7, 8, 12, 13, 14, 14, 13, 14, 15, 19, 21, 23, 24, 23, 28, 31,
101 30, 27, 29, 32, 29, 24, 23, 24, 20, 14, 11, 8, 6, 1, 0, -2, -8, -13, -20, -21,
102 -28, -33, -33, -38, -37, -41, -45, -44, -48, -47, -48, -50, -50, -49, -46, -45,
103 -45, -41, -37, -38, -37, -35, -34, -29, -29, -27, -24, -25, -20, -6, -1, -10,
104 -7, 7, 12, 3, -2, 12, 22, 18, 14, 13, 23, 29, 23, 26, 31, 28, 28, 30, 29, 28,
105 26, 27, 27, 23, 24, 22, 21, 23, 21, 17, 13, 8, 11, 15, 12, 12, 20, 19, 16, 17,
106 19, 18, 16, 21, 23, 20, 23, 24, 25, 29, 27, 24, 26, 28, 22, 18, 18, 18, 15, 8,
107 3, 5, 4, -6, -8, -7, -13, -24, -28, -25, -36, -44, -39, -42, -44, -49, -51, -49,
108 -52, -56, -56, -57, -57, -54, -52, -50, -49, -46, -40, -43, -42, -35, -34, -32,
109 -30, -28, -24, -22, -22, -19, -3, 6, -3, -4, 10, 18, 10, 4, 15, 26, 29, 24, 22,
110 31, 39, 36, 32, 37, 36, 35, 39, 37, 36, 37, 37, 36, 32, 31, 29, 25, 25, 24, 18,
111 14, 9, 8, 14, 12, 9, 11, 11, 11, 10, 6, 5, 6, 11, 11, 8, 10, 14, 16, 19, 18, 14,
112 16, 20, 16, 11, 10, 12, 12, 6, 2, 1, -1, -6, -9, -12, -19, -24, -28, -31, -35,
113 -40, -41, -44, -45, -47, -53, -51, -52, -54, -53, -55, -56, -53, -48, -45, -44,
114 -41, -38, -35, -32, -30, -29, -24, -18, -18, -16, -12, -10, -7, -4, 1, 13, 14,
115 9, 14, 24, 29, 21, 20, 33, 39, 37, 33, 32, 41, 47, 40, 38, 40, 41, 43, 39, 36,
116 35, 33, 34, 28, 21, 23, 20, 16, 14, 8, 3, 0, -5, -6, -3, -3, -4, -7, -5, 0, -6,
117 -10, -7, -1, 2, -2, -1, 6, 11, 11, 12, 14, 16, 17, 19, 15, 12, 14, 16, 13, 9, 8,
118 7, 5, 2, -4, -8, -11, -19, -21, -22, -29, -33, -31, -32, -37, -41, -41, -44,
119 -45, -43, -47, -48, -43, -41, -41, -38, -35, -33, -31, -27, -25, -25, -19, -16,
120 -15, -11, -9, -7, -3, 0, 1, 1, 1, 9, 21, 17, 11, 19, 29, 30, 20, 21, 33, 36, 33,
121 28, 27, 33, 34, 29, 31, 31, 27, 27, 24, 20, 17, 13, 14, 10, 4, 4, 1, -3, -4, -8,
122 -11, -14, -17, -12, -7, -10, -12, -8, -4, -5, -8, -4, 3, 7, 9, 10, 13, 19, 24,
123 26, 29, 30, 31, 33, 32, 27, 26, 26, 27, 26, 20, 16, 17, 13, 6, 1, -4, -8, -14,
124 -20, -19, -26, -32, -29, -34, -38, -41, -45, -44, -46, -48, -48, -49, -46, -41,
125 -42, -41, -37, -35, -31, -31, -31, -25, -23, -22, -18, -16, -13, -12, -10, -6,
126 -6, -5, -6, 2, 13, 9, 6, 13, 22, 22, 13, 15, 23, 25, 25, 20, 18, 26, 28, 25, 26,
127 23, 22, 23, 18, 14, 11, 11, 14, 8, 4, 6, 2, 0, -2, -4, -2, -5, -9, -2, 4, 1, -1,
128 3, 10, 10, 7, 10, 14, 20, 23, 22, 25, 32, 37, 37, 37, 40, 40, 39, 36, 32, 31,
129 29, 27, 26, 23, 17, 13, 11, 5, -4, -8, -11, -20, -24, -25, -32, -38, -36, -38,
130 -47, -50, -49, -52, -55, -56, -57, -56, -54, -53, -52, -47, -45, -43, -39, -39,
131 -38, -33, -30, -27, -24, -18, -14, -14, -10, -8, -5, -2, -2, -1, 9, 17, 11, 13,
132 23, 29, 27, 20, 24, 30, 32, 30, 24, 28, 35, 34, 30, 30, 30, 29, 27, 21, 17, 17,
133 18, 16, 10, 10, 10, 7, 7, 3, 3, 5, 3, 3, 5, 7, 7, 7, 11, 13, 13, 14, 16, 19, 24,
134 25, 24, 30, 33, 35, 35, 35, 36, 34, 32, 27, 23, 23, 21, 17, 11, 8, 6, -2, -7,
135 -13, -17, -20, -27, -35, -38, -39, -45, -50, -50, -50, -57, -63, -58, -59, -64,
136 -61, -60, -56, -55, -54, -49, -47, -43, -40, -38, -34, -30, -26, -20, -16, -14,
137 -9, -5, -3, 1, 2, 6, 8, 8, 20, 25, 24, 26, 32, 39, 36, 29, 33, 39, 39, 36, 33,
138 36, 41, 38, 36, 35, 32, 31, 28, 23, 21, 17, 19, 19, 13, 10, 8, 6, 4, -1, -4, -6,
139 -9, -7, -5, -7, -6, -4, -2, 0, -3, -2, 0, 4, 7, 6, 8, 14, 18, 21, 22, 23, 25,
140 24, 22, 22, 20, 18, 17, 18, 17, 10, 8, 9, 4, -3, -8, -9, -14, -20, -24, -27,
141 -30, -33, -35, -37, -41, -44, -44, -46, -51, -50, -47, -46, -45, -44, -40, -39,
142 -37, -34, -32, -29, -27, -22, -17, -15, -12, -7, -3, 0, 0, 2, 5, 7, 7, 7, 9, 13,
143 16, 21, 22, 22, 25, 27, 26, 23, 23, 25, 26, 25, 23, 23, 25, 25, 23, 22, 21, 18,
144 16, 14, 11, 10, 9, 8, 5, 1, -2, -5, -7, -9, -12, -12, -10, -11, -11, -8, -6, -6,
145 -6, -3, -1, -1, 2, 5, 9, 13, 16, 21, 26, 29, 32, 34, 37, 38, 38, 39, 38, 37, 38,
146 36, 33, 31, 26, 24, 19, 13, 8, 3, 0, -9, -14, -16, -23, -28, -32, -35, -39, -44,
147 -46, -49, -51, -52, -53, -54, -54, -51, -51, -49, -46, -44, -38, -38, -36, -28,
148 -27, -24, -18, -15, -13, -10, -5, -1, -1, 2, 5, 5, 6, 7, 7, 8, 8, 7, 12, 13, 12,
149 12, 15, 17, 14, 9, 12, 11, 9, 8, 5, 6, 8, 7, 6, 5, 4, 5, 4, 1, 0, -2, 2, 4, 1,
150 5, 9, 10, 13, 13, 17, 22, 22, 24, 28, 30, 32, 32, 37, 42, 41, 43, 47, 49, 51,
151 51, 50, 52, 51, 49, 44, 40, 37, 32, 25, 20, 13, 8, 2, -6, -9, -17, -27, -29,
152 -32, -40, -50, -52, -54, -61, -65, -67, -71, -71, -67, -71, -73, -69, -66, -62,
153 -63, -58, -54, -51, -43, -42, -34, -27, -26, -18, -11, -8, -5, 0, 6, 8, 9, 9,
154 13, 14, 16, 14, 16, 26, 27, 24, 28, 30, 30, 27, 23, 23, 22, 21, 18, 14, 15, 18,
155 16, 15, 14, 10, 11, 10, 4, 2, 3, 5, 1, -1, 2, 2, 2, 2, 2, 4, 4, 4, 8, 13, 14,
156 17, 21, 25, 27, 28, 32, 34, 37, 39, 39, 41, 46, 47, 47, 48, 49, 48, 45, 42, 38,
157 31, 28, 22, 15, 9, 2, 0, -5, -15, -19, -22, -30, -37, -42, -47, -54, -61, -59,
158 -64, -70, -67, -69, -68, -69, -70, -64, -64, -62, -56, -55, -49, -45, -41, -31,
159 -30, -24, -14, -13, -6, -1, 1, 7, 9, 14, 16, 16, 21, 20, 20, 23, 20, 21, 26, 26,
160 24, 26, 28, 28, 24, 23, 22, 18, 19, 17, 12, 14, 14, 13, 14, 13, 11, 11, 10, 8,
161 5, 4, 4, 1, -1, 1, -3, -3, -3, -3, -2, -1, 3, 4, 5, 11, 13, 14, 16, 19, 23, 25,
162 27, 30, 34, 38, 40, 42, 47, 48, 48, 50, 50, 47, 45, 42, 38, 33, 28, 23, 17, 12,
163 6, -2, -8, -14, -21, -28, -34, -42, -47, -51, -58, -64, -64, -65, -71, -71, -68,
164 -70, -71, -67, -66, -64, -58, -57, -52, -45, -39, -36, -30, -20, -17, -13, -5,
165 -2, 2, 6, 9, 12, 15, 19, 19, 20, 24, 24, 21, 22, 20, 16, 16, 13, 13, 12, 10, 11,
166 10, 11, 8, 4, 4, 3, -2, -5, -5, -6, -6, -5, -5, -4, -2, 0, 0, -1, 4, 5, 6, 9,
167 11, 15, 19, 21, 26, 31, 36, 39, 40, 43, 46, 46, 47, 46, 48, 51, 50, 49, 51, 52,
168 52, 48, 46, 44, 38, 32, 26, 19, 12, 4, -4, -8, -16, -26, -28, -34, -42, -48,
169 -50, -57, -63, -65, -69, -71, -73, -76, -75, -71, -69, -76, -68, -60, -62, -61,
170 -52, -44, -43, -35, -27, -24, -18, -11, -5, 0, 5, 7, 12, 18, 18, 20, 23, 25, 23,
171 22, 22, 19, 17, 15, 12, 14, 16, 12, 9, 13, 15, 9, 3, 3, 2, -1, -5, -9, -9, -5,
172 -4, -5, -3, -1, 1, 2, 2, -2, -3, 1, 2, -1, -1, 3, 8, 14, 18, 21, 31, 38, 38, 39,
173 44, 46, 42, 44, 48, 48, 49, 53, 55, 59, 61, 59, 59, 60, 57, 51, 45, 42, 36, 29,
174 21, 11, 6, 1, -8, -16, -19, -25, -38, -47, -47, -55, -65, -67, -68, -73, -76,
175 -76, -77, -78, -77, -73, -71, -71, -68, -62, -57, -52, -49, -40, -32, -29, -20,
176 -12, -8, -3, 6, 13, 13, 16, 20, 24, 25, 26, 27, 29, 29, 29, 27, 25, 22, 19, 20,
177 20, 14, 13, 16, 16, 12, 9, 9, 9, 7, 5, 2, 0, 2, 3, 4, 4, 4, 6, 9, 9, 8, 8, 10,
178 10, 8, 8, 6, 5, 7, 8, 8, 8, 10, 15, 16, 16, 18, 20, 21, 20, 21, 22, 22, 24, 28,
179 29, 30, 33, 36, 38, 38, 38, 39, 37, 35, 33, 30, 25, 22, 20, 15, 11, 6, 3, -1,
180 -8, -14, -21, -27, -33, -40, -43, -50, -52, -53, -55, -57, -62, -59, -57, -62,
181 -61, -59, -58, -58, -52, -48, -46, -40, -31, -26, -24, -18, -13, -10, -5, -4, 1,
182 3, 5, 9, 11, 14, 15, 17, 18, 17, 14, 12, 9, 4, 2, 0, -1, -1, -3, 0, 3, 5, 3, 0,
183 2, 2, -2, -4, -5, -4, 0, 2, 3, 7, 12, 17, 18, 17, 19, 22, 25, 24, 23, 29, 35,
184 37, 40, 45, 50, 54, 54, 53, 53, 53, 50, 47, 47, 46, 45, 45, 46, 46, 46, 44, 40,
185 37, 32, 25, 17, 10, 2, -5, -12, -19, -22, -28, -34, -36, -43, -49, -52, -58,
186 -62, -68, -71, -70, -74, -75, -72, -69, -67, -67, -60, -56, -55, -51, -46, -39,
187 -36, -34, -25, -19, -15, -9, -2, 5, 10, 14, 17, 19, 19, 23, 23, 20, 21, 19, 18,
188 13, 8, 9, 4, 5, 8, 5, 5, 6, 6, 6, 2, -1, -1, -3, -5, -8, -10, -4, -2, -1, 5, 8,
189 10, 12, 13, 13, 10, 11, 12, 10, 11, 12, 13, 18, 24, 27, 29, 35, 42, 41, 39, 42,
190 43, 41, 40, 39, 42, 43, 44, 46, 48, 50, 50, 49, 48, 46, 41, 39, 33, 28, 23, 15,
191 7, 0, -3, -10, -22, -25, -28, -37, -45, -51, -53, -58, -64, -67, -70, -71, -74,
192 -74, -73, -73, -72, -69, -64, -62, -59, -52, -47, -42, -35, -28, -24, -19, -8,
193 -4, -3, 5, 11, 14, 17, 20, 25, 25, 27, 29, 26, 26, 25, 20, 18, 16, 11, 8, 10,
194 10, 8, 8, 10, 8, 5, 5, 3, -1, 0, -2, -4, -3, -2, 1, 4, 7, 9, 10, 13, 12, 10, 10,
195 8, 6, 6, 5, 4, 5, 8, 9, 9, 12, 14, 15, 17, 17, 16, 19, 19, 19, 21, 24, 27, 29,
196 33, 36, 37, 40, 42, 42, 43, 43, 43, 42, 40, 38, 34, 31, 26, 21, 16, 11, 3, -3,
197 -8, -16, -22, -29, -36, -40, -47, -51, -56, -59, -63, -68, -67, -69, -70, -68,
198 -67, -65, -63, -58, -55, -52, -45, -41, -35, -29, -25, -19, -12, -7, -3, 1, 7,
199 9, 10, 13, 15, 14, 16, 18, 15, 14, 13, 9, 6, 1, -2, -2, -1, -2, -4, 0, 2, 0, 0,
200 1, 0, -2, -3, -4, -5, -3, 0, 2, 6, 10, 13, 16, 19, 19, 21, 27, 26, 24, 28, 33,
201 35, 36, 42, 46, 49, 51, 50, 49, 51, 49, 46, 45, 45, 43, 42, 43, 43, 43, 44, 42,
202 38, 36, 32, 25, 21, 17, 9, 2, -4, -10, -17, -22, -26, -33, -35, -39, -48, -51,
203 -53, -57, -61, -63, -64, -67, -66, -65, -68, -62, -59, -56, -56, -53, -45, -44,
204 -40, -34, -28, -22, -20, -14, -6, -3, -1, 4, 11, 12, 13, 13, 16, 18, 18, 17, 13,
205 15, 14, 6, 2, 1, -2, -6, -7, -6, -7, -6, -4, -4, -3, -2, -4, -4, -3, -4, -5, -3,
206 1, 3, 7, 12, 14, 19, 23, 24, 25, 25, 25, 23, 23, 21, 19, 19, 22, 22, 20, 25, 31,
207 32, 33, 35, 38, 35, 32, 32, 30, 30, 29, 28, 30, 34, 36, 38, 40, 42, 42, 41, 39,
208 35, 31, 27, 20, 13, 9, 3, -4, -8, -13, -19, -24, -29, -37, -42, -48, -55, -60,
209 -65, -68, -70, -72, -74, -71, -69, -68, -67, -63, -59, -59, -55, -48, -46, -42,
210 -32, -28, -23, -14, -8, -3, 4, 8, 9, 13, 16, 15, 16, 20, 20, 16, 18, 19, 12, 10,
211 7, 2, -1, -1, -2, -2, 0, 1, 2, 5, 6, 4, 5, 8, 6, 4, 7, 10, 12, 18, 22, 24, 30,
212 36, 37, 38, 40, 39, 37, 37, 35, 31, 30, 31, 29, 27, 27, 24, 21, 20, 16, 12, 9,
213 6, 3, 1, 1, -1, -1, 3, 5, 4, 6, 8, 9, 10, 10, 12, 12, 13, 14, 12, 12, 10, 8, 8,
214 6, 1, 0, -2, -7, -10, -13, -17, -22, -25, -29, -34, -37, -41, -46, -44, -49,
215 -51, -48, -49, -48, -48, -45, -41, -40, -35, -33, -30, -24, -23, -20, -14, -10,
216 -7, -4, 2, 6, 6, 11, 10, 9, 13, 8, 4, 4, 1, -5, -7, -11, -14, -17, -19, -16,
217 -17, -15, -11, -10, -5, -5, -7, -2, 0, -1, 0, 4, 8, 11, 17, 23, 28, 35, 40, 43,
218 46, 47, 47, 47, 46, 44, 42, 42, 42, 40, 42, 42, 40, 39, 36, 33, 28, 21, 19, 13,
219 9, 7, 4, 4, 6, 6, 8, 9, 10, 11, 10, 9, 7, 4, 2, -1, -6, -9, -12, -13, -12, -17,
220 -20, -20, -19, -24, -30, -30, -31, -38, -40, -43, -47, -46, -45, -46, -48, -43,
221 -41, -45, -41, -40, -38, -37, -36, -30, -28, -23, -21, -17, -7, -6, -3, 1, 2, 2,
222 5, 4, 1, 2, 2, 0, -2, 0, -2, -7, -6, -5, -12, -15, -16, -17, -16, -14, -14, -14,
223 -7, -3, -3, -2, 1, 3, 4, 6, 5, 5, 10, 14, 17, 19, 22, 26, 30, 32, 30, 29, 29,
224 28, 24, 21, 24, 24, 27, 36, 37, 40, 46, 48, 48, 46, 46, 42, 37, 37, 34, 32, 35,
225 37, 40, 45, 47, 46, 46, 45, 38, 30, 23, 12, 1, -7, -15, -24, -28, -31, -35, -40,
226 -43, -47, -53, -57, -64, -71, -73, -77, -81, -78, -74, -74, -70, -61, -55, -54,
227 -47, -40, -39, -34, -29, -26, -21, -14, -8, -2, 5, 11, 15, 21, 24, 21, 23, 20,
228 14, 12, 11, 6, -1, -2, -2, -7, -10, -12, -12, -10, -8, -9, -11, -7, -4, -4, -2,
229 -1, 3, 9, 14, 15, 19, 28, 34, 38, 40, 44, 47, 49, 50, 48, 47, 47, 45, 43, 38,
230 35, 32, 29, 25, 20, 15, 11, 5, 1, -2, -6, -10, -11, -11, -11, -12, -11, -8, -4,
231 -2, 1, 2, 7, 11, 13, 17, 20, 22, 26, 27, 26, 24, 23, 22, 19, 15, 11, 5, 2, -2,
232 -7, -11, -17, -20, -25, -32, -38, -43, -45, -51, -55, -55, -57, -59, -56, -53,
233 -53, -50, -43, -42, -39, -33, -30, -27, -22, -17, -12, -7, -3, 1, 7, 11, 12, 12,
234 15, 15, 11, 8, 4, 2, -2, -8, -12, -14, -17, -21, -21, -17, -18, -18, -13, -8,
235 -9, -8, -4, -3, 0, 1, 2, 6, 13, 17, 22, 30, 37, 42, 48, 52, 52, 52, 53, 52, 49,
236 46, 44, 43, 42, 40, 38, 37, 35, 31, 27, 24, 18, 12, 7, 3, -2, -5, -5, -5, -4, 0,
237 1, 3, 7, 9, 9, 9, 9, 7, 6, 4, 1, -3, -5, -6, -8, -9, -10, -11, -14, -16, -16,
238 -21, -24, -28, -32, -34, -39, -45, -45, -44, -47, -48, -46, -46, -42, -37, -36,
239 -36, -30, -22, -23, -25, -16, -9, -11, -11, -2, 1, 0, 3, 7, 8, 8, 9, 6, 4, 4,
240 -3, -7, -7, -11, -16, -17, -18, -22, -21, -16, -12, -11, -9, -4, -3, -1, -1, -2,
241 2, 4, 4, 4, 6, 12, 18, 21, 25, 28, 31, 33, 31, 29, 28, 25, 22, 21, 16, 15, 20,
242 25, 27, 30, 38, 42, 40, 39, 41, 38, 34, 31, 28, 28, 28, 28, 33, 39, 43, 46, 48,
243 48, 45, 40, 35, 25, 14, 5, -7, -18, -23, -29, -34, -37, -40, -44, -47, -51, -55,
244 -60, -65, -70, -74, -76, -76, -77, -72, -65, -61, -53, -46, -38, -31, -26, -21,
245 -16, -10, -9, -5, 2, 3, 9, 15, 19, 22, 25, 27, 25, 23, 19, 13, 9, 3, -5, -13,
246 -17, -18, -23, -26, -25, -26, -23, -19, -18, -16, -11, -7, -6, -3, -1, 3, 9, 14,
247 18, 22, 31, 37, 41, 45, 48, 48, 47, 46, 42, 37, 32, 27, 23, 18, 13, 8, 6, 5, 0,
248 -4, -6, -8, -10, -12, -13, -13, -12, -8, -4, -1, 4, 11, 18, 25, 30, 34, 41, 45,
249 48, 50, 51, 52, 53, 50, 46, 40, 35, 28, 20, 11, 1, -7, -17, -26, -34, -43, -52,
250 -57, -60, -69, -74, -73, -77, -82, -79, -76, -78, -74, -66, -62, -58, -49, -39,
251 -33, -23, -12, -8, -1, 11, 16, 18, 24, 27, 28, 30, 30, 26, 25, 26, 19, 14, 11,
252 6, -1, -9, -14, -23, -30, -35, -39, -38, -37, -35, -30, -23, -18, -13, -6, 0, 3,
253 8, 12, 16, 20, 27, 35, 42, 51, 57, 63, 70, 72, 72, 70, 67, 61, 53, 45, 36, 30,
254 24, 17, 12, 6, 1, -4, -8, -14, -21, -26, -30, -33, -36, -36, -34, -30, -23, -16,
255 -8, 1, 9, 16, 23, 28, 32, 35, 37, 37, 35, 33, 31, 26, 21, 19, 17, 11, 4, 0, -6,
256 -18, -24, -29, -40, -48, -52, -62, -69, -68, -72, -73, -68, -69, -67, -59, -53,
257 -51, -46, -33, -28, -29, -15, -6, -6, 5, 15, 17, 23, 32, 31, 30, 35, 33, 27, 24,
258 21, 12, 7, 4, -8, -13, -11, -20, -26, -19, -16, -22, -20, -12, -12, -14, -12,
259 -11, -10, -5, -4, -5, 3, 12, 16, 23, 31, 36, 41, 47, 46, 42, 43, 42, 34, 28, 25,
260 20, 16, 16, 14, 11, 15, 16, 14, 13, 12, 11, 8, 6, 4, 1, 3, 4, 5, 12, 17, 20, 27,
261 33, 34, 36, 36, 32, 26, 20, 11, 2, -5, -10, -17, -23, -24, -28, -34, -35, -36,
262 -42, -48, -54, -57, -64, -71, -70, -68, -70, -64, -53, -48, -41, -30, -21, -13,
263 -10, -5, 0, 4, 6, 4, 10, 17, 18, 20, 25, 27, 27, 28, 23, 17, 11, 3, -5, -19,
264 -27, -32, -43, -44, -46, -48, -39, -33, -29, -19, -12, -6, 0, 3, 7, 12, 15, 20,
265 23, 29, 40, 45, 52, 61, 65, 68, 69, 65, 60, 52, 42, 32, 21, 11, 1, -8, -13, -17,
266 -21, -22, -23, -25, -24, -25, -26, -25, -24, -21, -18, -13, -5, 5, 15, 26, 37,
267 47, 56, 62, 67, 70, 70, 66, 61, 56, 45, 34, 25, 14, 3, -5, -16, -29, -35, -43,
268 -57, -64, -71, -81, -86, -86, -94, -100, -90, -83, -83, -75, -62, -52, -42, -27,
269 -19, -9, 5, 14, 19, 26, 35, 38, 44, 49, 49, 52, 53, 50, 46, 42, 33, 21, 12, 3,
270 -13, -26, -35, -45, -54, -62, -68, -66, -61, -58, -51, -41, -32, -23, -13, -4,
271 4, 12, 22, 29, 35, 43, 53, 62, 70, 76, 81, 84, 84, 82, 75, 67, 57, 45, 31, 17,
272 3, -9, -19, -29, -37, -42, -48, -51, -52, -53, -53, -51, -45, -40, -35, -24,
273 -13, -2, 11, 25, 38, 50, 60, 70, 79, 83, 84, 84, 81, 76, 67, 56, 43, 30, 17, 2,
274 -11, -26, -38, -51, -64, -71, -79, -93, -99, -96, -101, -108, -105, -95, -86,
275 -81, -70, -55, -39, -24, -15, -2, 16, 27, 32, 45, 52, 53, 59, 63, 63, 62, 60,
276 54, 47, 41, 31, 16, 5, -4, -21, -36, -47, -60, -68, -76, -87, -88, -79, -76,
277 -73, -58, -42, -31, -19, -4, 7, 19, 31, 38, 44, 55, 64, 70, 77, 83, 87, 92, 92,
278 86, 81, 75, 62, 46, 32, 16, -1, -14, -26, -39, -46, -49, -52, -53, -50, -48,
279 -43, -38, -35, -32, -24, -12, -1, 10, 18, 26, 41, 59, 72, 80, 82, 79, 79, 79,
280 73, 60, 42, 21, 5, -6, -22, -39, -45, -55, -70, -74, -73, -81, -91, -91, -92,
281 -97, -97, -92, -89, -81, -69, -55, -36, -18, -6, 13, 32, 43, 55, 64, 68, 68, 71,
282 69, 61, 57, 55, 47, 38, 32, 21, 10, 1, -13, -27, -41, -57, -72, -85, -95, -96,
283 -88, -83, -79, -63, -41, -25, -13, 4, 21, 33, 40, 43, 47, 56, 62, 64, 68, 74,
284 78, 83, 84, 81, 77, 71, 58, 41, 25, 9, -9, -23, -35, -45, -48, -46, -42, -36,
285 -28, -19, -10, -3, 3, 8, 11, 14, 19, 24, 30, 33, 40, 49, 52, 53, 53, 50, 42, 29,
286 15, 1, -14, -34, -48, -57, -68, -78, -83, -81, -80, -82, -83, -79, -71, -71,
287 -70, -61, -51, -44, -34, -20, -7, 10, 25, 37, 50, 62, 68, 69, 73, 72, 64, 57,
288 49, 40, 28, 17, 5, -5, -13, -26, -39, -47, -56, -64, -68, -69, -70, -68, -59,
289 -51, -44, -32, -17, -4, 7, 17, 28, 39, 48, 54, 58, 65, 67, 67, 68, 66, 61, 57,
290 52, 43, 33, 23, 12, 1, -8, -20, -29, -34, -37, -40, -38, -32, -26, -17, -6, 1,
291 10, 21, 28, 35, 40, 42, 44, 47, 47, 43, 38, 35, 30, 20, 9, 1, -5, -20, -32, -37,
292 -50, -62, -65, -72, -82, -84, -84, -86, -83, -79, -70, -61, -51, -40, -27, -13,
293 -3, 9, 24, 31, 36, 46, 51, 51, 55, 53, 51, 48, 42, 34, 24, 16, 4, -9, -21, -35,
294 -47, -55, -64, -68, -62, -61, -58, -45, -33, -24, -13, 0, 11, 19, 25, 32, 38,
295 44, 49, 52, 58, 60, 62, 66, 65, 61, 56, 51, 42, 29, 16, 4, -8, -18, -29, -37,
296 -41, -41, -41, -38, -32, -25, -16, -6, 3, 9, 18, 28, 34, 39, 43, 47, 50, 49, 43,
297 39, 35, 27, 16, 4, -7, -18, -29, -41, -53, -59, -67, -76, -77, -79, -83, -80,
298 -74, -71, -64, -55, -45, -32, -19, -8, 4, 19, 31, 40, 50, 56, 59, 63, 64, 58,
299 53, 48, 39, 28, 16, 3, -9, -20, -32, -45, -56, -64, -68, -69, -71, -70, -61,
300 -52, -45, -33, -18, -6, 8, 21, 31, 41, 52, 61, 67, 70, 72, 75, 76, 72, 65, 61,
301 56, 46, 35, 24, 13, 1, -10, -22, -32, -39, -43, -46, -47, -44, -39, -32, -22,
302 -12, -2, 9, 18, 28, 37, 41, 42, 45, 45, 42, 38, 30, 23, 18, 9, -5, -14, -20,
303 -29, -39, -47, -56, -60, -64, -71, -73, -69, -68, -66, -58, -49, -42, -30, -15,
304 -6, 3, 17, 27, 34, 42, 46, 47, 49, 48, 43, 37, 32, 24, 15, 6, -4, -13, -20, -27,
305 -34, -38, -41, -43, -42, -41, -42, -38, -31, -27, -23, -15, -6, 3, 12, 21, 30,
306 39, 47, 52, 55, 58, 58, 57, 53, 48, 42, 37, 31, 24, 18, 12, 7, 4, 1, -3, -6, -6,
307 -7, -8, -8, -8, -6, -6, -7, -8, -10, -11, -13, -18, -21, -25, -29, -33, -35,
308 -37, -37, -37, -37, -33, -30, -30, -26, -20, -18, -17, -12, -8, -4, 0, 3, 8, 13,
309 17, 21, 24, 26, 27, 25, 22, 17, 11, 4, -3, -11, -20, -23, -25, -28, -29, -27,
310 -25, -20, -15, -12, -9, -6, -4, -2, 1, 3, 6, 9, 11, 17, 24, 28, 30, 34, 35, 34,
311 33, 29, 23, 17, 10, 4, -1, -5, -9, -10, -11, -10, -7, -5, -2, 1, 2, 4, 5, 5, 5,
312 4, 1, 1, -1, -3, -6, -8, -11, -14, -17, -19, -24, -26, -27, -30, -34, -32, -30,
313 -30, -30, -27, -22, -18, -15, -9, -5, -1, 3, 7, 11, 15, 15, 16, 17, 16, 15, 12,
314 9, 7, 8, 6, 5, 6, 8, 8, 8, 9, 10, 8, 5, 3, 0, -3, -5, -7, -8, -8, -6, -3, -1, 1,
315 4, 6, 6, 6, 6, 4, 1, 0, -2, -4, -3, -3, -2, 1, 5, 8, 10, 13, 14, 16, 16, 15, 12,
316 8, 5, 2, -1, -5, -9, -14, -18, -22, -27, -31, -34, -39, -42, -43, -44, -44, -42,
317 -38, -32, -26, -21, -13, -6, 2, 8, 13, 18, 22, 23, 25, 25, 24, 22, 19, 15, 11,
318 6, 1, -4, -9, -14, -16, -17, -18, -19, -17, -15, -11, -8, -6, -2, 2, 4, 6, 10,
319 13, 15, 16, 19, 21, 21, 21, 20, 18, 16, 12, 8, 4, -1, -6, -10, -13, -14, -15,
320 -16, -15, -14, -11, -8, -5, -1, 2, 4, 7, 9, 10, 11, 10, 10, 8, 5, 2, -1, -8,
321 -13, -20, -28, -33, -39, -47, -50, -51, -54, -51, -45, -42, -36, -28, -18, -11,
322 -4, 4, 9, 14, 18, 20, 22, 23, 21, 20, 18, 15, 11, 6, -1, -7, -12, -17, -21, -25,
323 -28, -30, -29, -28, -26, -23, -19, -15, -10, -5, 1, 7, 12, 15, 21, 26, 29, 30,
324 31, 30, 29, 27, 23, 18, 14, 8, 2, -2, -6, -10, -14, -17, -19, -19, -19, -19,
325 -18, -16, -14, -11, -8, -4, -2, 0, 2, 5, 6, 5, 4, 5, 2, -4, -7, -9, -16, -23,
326 -27, -29, -33, -36, -35, -34, -32, -27, -24, -20, -14, -10, -7, -4, -1, 1, 1, 0,
327 0, 0, -1, -4, -6, -7, -10, -12, -13, -13, -13, -13, -12, -9, -7, -6, -4, -3, -1,
328 0, 0, 2, 3, 4, 4, 5, 7, 7, 7, 7, 7, 5, 3, 1, -1, -4, -8, -10, -12, -12, -12,
329 -12, -11, -8, -5, -1, 2, 6, 9, 12, 15, 17, 18, 19, 19, 17, 15, 14, 10, 5, -1,
330 -7, -13, -20, -28, -34, -39, -47, -52, -53, -52, -53, -51, -42, -34, -28, -18,
331 -5, 4, 12, 20, 27, 30, 32, 32, 30, 25, 21, 15, 7, 0, -6, -13, -18, -20, -22,
332 -25, -25, -24, -24, -22, -22, -21, -20, -20, -18, -16, -13, -11, -6, -2, 2, 6,
333 10, 13, 14, 14, 14, 12, 9, 5, 1, -3, -6, -9, -10, -11, -10, -9, -7, -5, -3, -1,
334 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 4, 1, -1, -4, -8, -13, -19, -23, -28, -35, -38,
335 -39, -42, -45, -41, -37, -35, -29, -19, -14, -7, 3, 9, 14, 21, 24, 24, 24, 23,
336 20, 14, 8, 2, -6, -13, -18, -22, -26, -29, -28, -25, -24, -21, -15, -13, -10,
337 -5, -2, 0, 3, 5, 5, 8, 10, 11, 12, 13, 13, 13, 12, 9, 7, 2, -3, -7, -11, -16,
338 -20, -23, -25, -25, -24, -22, -19, -15, -10, -6, -1, 3, 6, 9, 10, 12, 12, 12,
339 11, 10, 9, 6, 4, 1, -2, -6, -9, -13, -18, -22, -26, -32, -36, -37, -42, -46,
340 -44, -42, -41, -35, -28, -22, -14, -4, 4, 10, 16, 20, 19, 19, 17, 11, 4, -2, -9,
341 -15, -18, -21, -23, -19, -16, -14, -7, -1, 1, 3, 7, 7, 6, 7, 5, 3, 3, 4, 4, 4,
342 7, 9, 9, 10, 11, 9, 5, 2, -2, -7, -11, -16, -19, -20, -20, -19, -16, -12, -7,
343 -1, 4, 9, 13, 16, 17, 18, 17, 14, 11, 8, 4, 1, -2, -5, -8, -10, -11, -15, -16,
344 -18, -23, -24, -27, -31, -34, -36, -36, -37, -37, -33, -30, -25, -17, -10, -3,
345 4, 11, 15, 19, 21, 19, 17, 13, 6, -1, -7, -15, -20, -22, -26, -27, -24, -21,
346 -17, -12, -6, -3, 0, 4, 5, 5, 6, 4, 3, 4, 4, 4, 5, 7, 9, 10, 12, 12, 11, 9, 7,
347 3, 0, -5, -9, -12, -14, -14, -13, -11, -7, -3, 2, 7, 10, 14, 17, 17, 17, 16, 14,
348 11, 7, 5, 2, 0, -2, -4, -4, -5, -6, -7, -8, -11, -14, -16, -21, -26, -29, -34,
349 -35, -36, -38, -35, -30, -24, -17, -9, -2, 6, 14, 19, 20, 22, 21, 15, 11, 5, -3,
350 -9, -14, -19, -22, -21, -19, -17, -13, -8, -5, 0, 3, 4, 6, 5, 4, 4, 2, 1, 0, 0,
351 2, 3, 4, 6, 7, 8, 9, 8, 5, 3, 0, -4, -7, -10, -12, -13, -13, -11, -9, -5, -1, 4,
352 8, 12, 15, 17, 18, 18, 16, 14, 11, 7, 5, 2, 0, 0, 0, 0, 2, 4, 5, 6, 6, 5, 3, 2,
353 -2, -6, -11, -16, -21, -26, -27, -32, -35, -32, -33, -29, -23, -21, -14, -7, -1,
354 6, 10, 14, 17, 18, 18, 17, 14, 11, 7, 4, 2, 0, -2, -3, -3, -3, -2, -1, -2, -2,
355 -1, -3, -3, -4, -6, -7, -6, -6, -5, -3, -1, 2, 5, 9, 11, 12, 14, 13, 12, 11, 8,
356 5, 2, -1, -3, -4, -4, -4, -2, 0, 3, 6, 9, 11, 13, 14, 15, 14, 12, 10, 8, 5, 2,
357 1, 0, -1, 1, 1, 3, 5, 5, 6, 6, 5, 2, 0, -3, -6, -9, -13, -15, -18, -20, -21,
358 -24, -22, -22, -21, -18, -14, -11, -7, -2, 1, 5, 8, 10, 12, 12, 11, 10, 8, 6, 4,
359 2, -1, -1, -3, -4, -3, -4, -3, -2, -2, -1, 0, 0, 1, 3, 4, 6, 8, 10, 12, 13, 14,
360 14, 13, 12, 9, 7, 4, 0, -3, -7, -9, -11, -13, -13, -13, -11, -8, -5, -2, 2, 6,
361 10, 13, 15, 17, 18, 18, 17, 16, 14, 12, 10, 7, 5, 3, 2, 1, 1, 1, 2, 2, 3, 4, 4,
362 4, 4, 4, 3, 1, 0, -1, -3, -5, -6, -10, -12, -16, -21, -24, -29, -33, -36, -38,
363 -36, -34, -28, -20, -11, 1, 12, 24, 33, 41, 45, 45, 44, 36, 29, 19, 6, -4, -15,
364 -24, -30, -34, -35, -33, -28, -22, -15, -7, 1, 7, 13, 17, 20, 21, 21, 20, 18,
365 16, 15, 12, 11, 9, 7, 6, 4, 2, -1, -4, -7, -10, -13, -15, -16, -16, -14, -11,
366 -7, -2, 4, 9, 15, 19, 22, 24, 23, 21, 17, 12, 6, -1, -7, -13, -17, -20, -21,
367 -20, -18, -14, -9, -3, 2, 7, 12, 15, 17, 18, 17, 15, 13, 11, 9, 8, 8, 9, 11, 14,
368 17, 20, 23, 24, 23, 21, 18, 11, 4, -3, -12, -20, -27, -33, -37, -38, -38, -35,
369 -32, -28, -23, -18, -10, -3, 2, 11, 16, 22, 28, 31, 34, 34, 32, 28, 24, 17, 9,
370 1, -7, -14, -20, -25, -27, -28, -26, -22, -17, -10, -2, 5, 12, 19, 24, 28, 30,
371 30, 30, 27, 24, 19, 14, 9, 4, 0, -5, -8, -10, -12, -13, -13, -12, -10, -8, -5,
372 -3, 1, 4, 7, 10, 13, 15, 16, 17, 17, 17, 16, 14, 11, 8, 4, 1, -3, -5, -8, -10,
373 -11, -11, -11, -9, -7, -4, -1, 3, 6, 9, 12, 14, 16, 17, 17, 17, 15, 13, 12, 9,
374 7, 4, 2, 1, -1, 0, 1, 4, 8, 12, 18, 23, 27, 31, 32, 31, 27, 21, 13, 4, -6, -16,
375 -24, -31, -35, -37, -36, -32, -27, -19, -11, -4, 4, 10, 15, 18, 19, 19, 18, 15,
376 12, 9, 5, 2, -1, -3, -6, -7, -8, -11, -12, -13, -14, -15, -14, -13, -10, -6, -2,
377 4, 9, 16, 21, 26, 30, 31, 32, 30, 26, 20, 14, 7, -1, -7, -14, -19, -22, -24,
378 -23, -22, -18, -14, -9, -3, 2, 7, 12, 16, 19, 21, 22, 22, 21, 20, 19, 16, 14,
379 11, 8, 5, 2, -2, -5, -8, -11, -13, -15, -15, -15, -14, -11, -8, -3, 1, 7, 13,
380 21, 30, 34, 41, 43, 42, 42, 35, 26, 15, 3, -10, -22, -32, -40, -46, -48, -47,
381 -43, -37, -29, -20, -11, 0, 9, 17, 24, 28, 32, 33, 33, 31, 26, 23, 17, 12, 7, 1,
382 -3, -7, -9, -11, -11, -11, -9, -7, -4, -1, 3, 6, 8, 11, 11, 12, 12, 10, 9, 5, 2,
383 -2, -6, -8, -10, -12, -12, -12, -10, -7, -5, -2, 1, 3, 6, 7, 8, 8, 8, 7, 7, 6,
384 6, 6, 5, 6, 6, 6, 7, 6, 6, 6, 4, 3, 1, 0, -2, -4, -5, -6, -6, -6, -4, -3, 2, 5,
385 9, 16, 18, 23, 27, 28, 29, 27, 25, 20, 15, 8, 1, -6, -12, -16, -20, -20, -20,
386 -18, -14, -11, -6, -2, 1, 3, 4, 3, 3, 0, -3, -5, -7, -9, -8, -7, -5, -1, 2, 8,
387 12, 16, 18, 19, 19, 17, 13, 8, 2, -4, -10, -14, -17, -18, -18, -16, -11, -6, 1,
388 8, 14, 20, 24, 26, 27, 26, 22, 18, 13, 8, 3, -2, -5, -7, -9, -8, -7, -6, -4, -2,
389 0, 3, 3, 4, 4, 3, 2, 1, 1, 0, 1, 1, 2, 4, 6, 9, 11, 13, 14, 14, 14, 13, 11, 8,
390 5, 2, -2, -5, -8, -4, -4, 1, 7, 9, 18, 22, 26, 29, 28, 25, 20, 14, 6, -2, -11,
391 -19, -25, -30, -31, -31, -29, -23, -17, -10, -2, 5, 12, 17, 22, 24, 24, 23, 21,
392 18, 14, 11, 8, 5, 4, 3, 3, 4, 5, 6, 7, 8, 8, 7, 6, 4, 2, 0, -1, -3, -3, -4, -3,
393 -3, -2, -1, -1, -1, 0, 0, -1, -1, -3, -2, -2, -2, -2, -2, -1, 0, 1, 3, 4, 5, 7,
394 9, 9, 11, 11, 11, 12, 11, 11, 10, 9, 8, 7, 7, 7, 6, 6, 7, 8, 9, 10, 11, 12, 13,
395 13, 13, 13, 12, 11, 9, 8, 7, 5, 4, 3, 2, 1, 1, 1, 1, 0, 0, 0, 0, -1, -1, -3, -3,
396 -5, -6, -7, -9, -9, -10, -10, -10, -10, -10, -9, -8, -6, -5, -4, -2, 1, 4, 5, 8,
397 9, 11, 13, 13, 13, 12, 11, 9, 7, 6, 4, 2, 1, 1, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3,
398 3, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 9, 8, 6, 5, 3, 2, 0,
399 -1, -1, -2, -2, -1, 0, 1, 3, 4, 6, 7, 8, 9, 9, 9, 9, 8, 7, 6, 4, 3, 2, 1, 0, 1,
400 2, 5, 9, 12, 17, 19, 21, 22, 20, 17, 12, 6, 0, -7, -13, -18, -22, -23, -23, -21,
401 -18, -13, -8, -2, 4, 9, 12, 14, 16, 16, 14, 12, 9, 6, 3, 1, 0, -1, 0, 1, 3, 6,
402 8, 11, 13, 13, 14, 13, 11, 8, 4, -1, -6, -11, -16, -22, -24, -26, -26, -24, -22,
403 -17, -12, -5, 2, 7, 12, 17, 20, 22, 23, 21, 20, 17, 14, 12, 8, 5, 3, 1, 1, 0, 0,
404 2, 2, 3, 4, 4, 4, 5, 4, 3, 3, 2, 2, 2, 2, 3, 4, 6, 8, 10, 12, 14, 15, 16, 15,
405 14, 13, 11, 8, 5, 2, -1, -4, -6, -8, -9, -10, -10, -10, -9, -8, -8, -7, -7, -7,
406 -6, -7, -6, -7, -8, -8, -8, -7, -6, -5, -4, -2, 0, 1, 4, 5, 6, 9, 9, 10, 10, 9,
407 10, 9, 8, 7, 5, 4, 3, 2, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4,
408 5, 6, 7, 8, 9, 9, 9, 10, 9, 8, 7, 6, 4, 2, 1, -1, -2, -3, -3, -3, -3, -2, -1, 1,
409 2, 4, 5, 6, 7, 7, 7, 7, 7, 6, 5, 5, 3, 7, 9, 10, 17, 15, 19, 22, 19, 20, 16, 10,
410 5, -3, -9, -15, -22, -25, -27, -28, -24, -21, -16, -9, -3, 4, 10, 15, 19, 21,
411 22, 22, 21, 18, 15, 12, 9, 7, 5, 4, 3, 4, 5, 6, 7, 9, 9, 9, 8, 6, 5, 0, -3, -8,
412 -13, -18, -24, -26, -28, -27, -24, -22, -16, -9, 0, 8, 16, 22, 28, 31, 33, 33,
413 30, 25, 19, 12, 5, -2, -9, -13, -17, -19, -19, -18, -15, -11, -7, -2, 3, 7, 11,
414 14, 16, 17, 18, 17, 17, 16, 14, 14, 12, 11, 10, 9, 9, 8, 7, 7, 5, 4, 2, 0, -2,
415 -4, -7, -9, -12, -14, -15, -17, -17, -17, -16, -14, -13, -9, -7, -5, 0, 2, 5, 8,
416 9, 10, 11, 10, 8, 6, 3, 0, -1, -5, -5, -6, -6, -3, -2, 0, 3, 5, 7, 8, 9, 8, 8,
417 5, 3, 2, -2, -3, -4, -5, -5, -4, -3, -1, 1, 3, 5, 6, 7, 8, 7, 7, 5, 3, 2, 0, -2,
418 -3, -4, -4, -3, -2, -1, 1, 2, 4, 6, 6, 7, 7, 6, 6, 4, 3, 1, -1, -1, -2, -2, -2,
419 1, 5, 6, 15, 17, 21, 29, 28, 31, 32, 25, 22, 16, 5, -1, -12, -22, -27, -35, -37,
420 -37, -38, -32, -27, -20, -11, -3, 5, 13, 18, 23, 25, 26, 26, 23, 20, 16, 12, 9,
421 5, 2, 1, -1, -1, 0, 0, 2, 3, 3, 4, 3, 1, -1, -5, -9, -15, -23, -29, -32, -34,
422 -35, -33, -30, -23, -12, -3, 9, 19, 27, 35, 41, 45, 44, 41, 34, 27, 18, 7, -2,
423 -12, -19, -24, -27, -27, -25, -21, -16, -9, -2, 4, 10, 14, 17, 19, 18, 17, 15,
424 13, 11, 9, 8, 7, 7, 8, 9, 10, 12, 12, 13, 12, 11, 8, 4, 0, -5, -10, -16, -20,
425 -24, -27, -28, -28, -26, -23, -17, -12, -6, 1, 6, 12, 16, 19, 21, 21, 20, 18,
426 15, 11, 7, 3, -1, -5, -10, -13, -16, -18, -17, -18, -18, -15, -13, -10, -5, -2,
427 1, 4, 6, 8, 10, 11, 11, 11, 10, 10, 9, 8, 7, 5, 5, 3, 2, 2, 0, -1, -1, -2, -3,
428 -3, -4, -4, -4, -4, -4, -4, -3, -2, -1, 0, 1, 3, 4, 5, 6, 6, 6, 6, 6, 5, 4, 2,
429 2, 1, 0, 1, 2, 3, 6, 8, 10, 13, 14, 16, 17, 16, 15, 12, 8, 4, -2, -7, -13, -18,
430 -22, -26, -28, -29, -29, -27, -23, -19, -14, -8, -2, 4, 9, 13, 17, 20, 21, 22,
431 21, 21, 19, 17, 15, 12, 10, 8, 6, 4, 3, 2, 1, -1, -2, -3, -4, -6, -8, -10, -13,
432 -16, -20, -26, -29, -28, -29, -28, -26, -23, -14, -5, 3, 13, 20, 27, 32, 37, 40,
433 38, 35, 30, 24, 17, 10, 2, -5, -11, -16, -19, -20, -20, -19, -17, -14, -10, -6,
434 -4, -1, 0, 1, 2, 2, 1, 0, 0, 1, 2, 4, 8, 10, 15, 21, 25, 29, 31, 32, 31, 28, 24,
435 18, 10, 1, -7, -16, -23, -30, -35, -38, -39, -37, -33, -29, -22, -16, -9, -1, 5,
436 10, 15, 17, 19, 20, 19, 19, 17, 16, 14, 13, 11, 10, 10, 9, 9, 8, 8, 7, 6, 4, 1,
437 -1, -5, -10, -14, -21, -28, -32, -34, -36, -37, -36, -31, -24, -15, -5, 5, 14,
438 23, 31, 38, 42, 42, 40, 36, 31, 24, 16, 7, -1, -9, -15, -20, -22, -24, -25, -23,
439 -20, -17, -13, -9, -6, -4, -1, 0, 2, 2, 1, 1, 1, 1, 2, 3, 4, 5, 8, 12, 14, 17,
440 20, 21, 24, 25, 25, 24, 20, 17, 12, 7, 1, -5, -11, -17, -21, -24, -27, -28, -27,
441 -26, -23, -19, -15, -10, -7, -3, 0, 3, 6, 8, 8, 9, 10, 11, 11, 11, 12, 12, 12,
442 13, 14, 14, 13, 12, 11, 9, 7, 5, 2, -1, -4, -7, -9, -11, -13, -15, -15, -16,
443 -18, -21, -23, -22, -21, -22, -20, -18, -13, -8, -3, 4, 8, 14, 19, 23, 27, 27,
444 26, 26, 22, 20, 15, 10, 6, -1, -5, -8, -12, -14, -16, -16, -16, -15, -12, -10,
445 -9, -7, -4, -2, 0, 1, 2, 4, 7, 8, 12, 14, 16, 20, 23, 26, 28, 27, 28, 25, 22,
446 19, 13, 7, 0, -7, -13, -20, -25, -29, -32, -33, -33, -30, -27, -23, -17, -11,
447 -5, 2, 7, 12, 15, 18, 20, 20, 20, 19, 17, 15, 13, 11, 9, 7, 6, 5, 4, 3, 2, 1,
448 -1, -3, -5, -10, -14, -18, -21, -24, -27, -28, -28, -25, -22, -16, -10, -4, 3,
449 11, 17, 23, 27, 30, 31, 31, 29, 26, 21, 16, 10, 5, 1, -4, -8, -11, -12, -13,
450 -12, -11, -9, -9, -7, -5, -4, -3, -3, -3, -3, -4, -4, -4, -4, -3, -1, 1, 4, 7,
451 9, 13, 17, 19, 22, 24, 25, 25, 25, 24, 21, 17, 13, 8, 2, -3, -8, -13, -17, -21,
452 -23, -24, -25, -24, -23, -21, -18, -15, -11, -9, -6, -2, 0, 2, 4, 5, 6, 7, 8, 9,
453 9, 10, 11, 12, 13, 13, 13, 13, 12, 12, 10, 9, 7, 4, 2, -1, -3, -5, -8, -9, -11,
454 -12, -12, -13, -14, -16, -18, -19, -19, -18, -19, -19, -18, -14, -11, -7, -3, 1,
455 6, 10, 15, 19, 21, 22, 23, 23, 22, 19, 16, 12, 7, 3, 0, -3, -7, -11, -13, -13,
456 -13, -13, -13, -11, -10, -9, -7, -4, -4, -4, -3, -2, 2, 4, 4, 8, 11, 14, 17, 20,
457 22, 19, 20, 20, 17, 15, 10, 5, 2, -5, -9, -12, -17, -20, -23, -22, -21, -21,
458 -19, -17, -14, -10, -7, -3, 0, 2, 4, 6, 8, 8, 7, 7, 7, 6, 7, 5, 5, 5, 4, 4, 4,
459 3, 2, -1, -3, -4, -6, -8, -12, -13, -14, -15, -14, -13, -12, -11, -8, -4, -1, 2,
460 5, 8, 11, 13, 14, 16, 15, 14, 12, 11, 10, 7, 4, 2, 0, -1, -3, -4, -4, -5, -5,
461 -4, -3, -3, -3, -2, -2, -2, -2, -2, -3, -3, -4, -3, -3, -3, -2, -1, 0, 2, 3, 5,
462 7, 8, 11, 14, 15, 17, 18, 20, 20, 20, 20, 17, 13, 12, 8, 4, 1, -5, -8, -11, -15,
463 -16, -18, -19, -20, -20, -18, -17, -16, -14, -13, -11, -8, -6, -4, -2, -1, 1, 3,
464 5, 7, 8, 10, 11, 13, 14, 15, 15, 16, 16, 16, 15, 14, 13, 11, 10, 8, 6, 3, 0, -3,
465 -6, -9, -12, -15, -17, -20, -23, -25, -27, -27, -26, -26, -25, -22, -18, -14,
466 -9, -3, 2, 6, 11, 16, 20, 22, 22, 23, 23, 23, 20, 17, 15, 12, 8, 5, 2, 0, -4,
467 -6, -8, -8, -10, -12, -12, -12, -13, -13, -12, -10, -8, -7, -4, 1, 5, 8, 11, 16,
468 18, 19, 20, 21, 20, 18, 15, 12, 9, 4, 0, -4, -7, -11, -13, -15, -17, -17, -17,
469 -17, -16, -15, -13, -12, -10, -9, -7, -5, -4, -4, -2, -2, -1, 0, 0, 1, 1, 1, 0,
470 -1, -2, -1, -2, -4, -5, -4, -4, -4, -3, -3, -3, -2, -1, 0, 1, 0, 0, 1, 1, 1, 0,
471 0, -1, -2, -2, -1, -1, -2, -2, -1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, -1, -2,
472 -2, -3, -3, -4, -4, -3, -3, -3, -2, -1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 3,
473 3, 5, 7, 9, 11, 13, 15, 16, 16, 15, 14, 13, 10, 6, 2, -2, -7, -11, -14, -19,
474 -22, -24, -25, -26, -26, -25, -24, -21, -18, -15, -12, -9, -5, -2, 1, 4, 6, 8,
475 9, 11, 12, 13, 14, 14, 14, 15, 15, 15, 14, 14, 13, 12, 11, 9, 7, 5, 2, -1, -5,
476 -9, -13, -17, -22, -26, -30, -31, -32, -34, -34, -31, -28, -24, -19, -13, -6,
477 -1, 5, 12, 18, 21, 24, 27, 29, 29, 27, 25, 23, 19, 15, 11, 8, 4, 0, -4, -5, -7,
478 -9, -11, -11, -11, -11, -11, -11, -11, -11, -11, -9, -7, -6, -5, -2, 2, 4, 7,
479 11, 13, 15, 17, 19, 20, 19, 19, 17, 15, 12, 9, 5, 1, -4, -8, -11, -15, -19, -21,
480 -23, -24, -24, -23, -22, -21, -19, -16, -13, -10, -7, -5, -2, 0, 2, 3, 3, 3, 3,
481 2, 1, 1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 6, 4, 4, 2, -1, -3, -4, -6,
482 -8, -9, -9, -9, -9, -9, -7, -5, -4, -2, 0, 3, 4, 6, 7, 8, 9, 8, 8, 8, 6, 5, 3,
483 2, 0, -1, -2, -2, -3, -3, -2, -2, -1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2,
484 4, 6, 8, 10, 11, 13, 14, 15, 15, 14, 12, 10, 8, 4, 0, -4, -8, -12, -16, -20,
485 -22, -24, -26, -26, -25, -24, -22, -20, -16, -13, -9, -5, -1, 3, 6, 9, 11, 14,
486 16, 16, 17, 17, 17, 17, 16, 15, 14, 13, 12, 10, 9, 7, 4, 2, -1, -5, -9, -13,
487 -17, -20, -24, -28, -30, -31, -32, -32, -30, -27, -23, -19, -14, -7, -1, 5, 10,
488 15, 21, 24, 26, 28, 29, 28, 26, 24, 21, 18, 13, 9, 5, 2, -1, -4, -7, -8, -9,
489 -10, -11, -11, -11, -11, -11, -11, -11, -11, -11, -9, -7, -8, -5, 0, 1, 4, 10,
490 13, 14, 18, 22, 23, 23, 24, 22, 20, 19, 14, 9, 5, -2, -7, -11, -16, -21, -24,
491 -26, -29, -29, -28, -27, -26, -23, -21, -18, -14, -12, -9, -7, -6, -4, -2, -2,
492 -3, -2, 0, 0, 0, 2, 3, 5, 7, 8, 11, 13, 13, 13, 14, 15, 13, 11, 9, 7, 4, 1, -3,
493 -6, -9, -12, -15, -16, -17, -18, -18, -17, -16, -14, -12, -10, -7, -4, -2, 1, 3,
494 5, 7, 8, 8, 9, 9, 8, 7, 7, 6, 5, 3, 2, 1, 0, -1, -2, -2, -3, -4, -4, -4, -5, -5,
495 -5, -4, -4, -4, -2, -1, 0, 2, 4, 5, 6, 8, 9, 10, 10, 10, 9, 8, 7, 5, 2, -1, -4,
496 -7, -10, -14, -17, -19, -22, -24, -24, -24, -24, -23, -21, -19, -16, -13, -10,
497 -7, -3, 0, 3, 6, 8, 10, 12, 13, 14, 14, 14, 13, 13, 11, 9, 7, 4, 0, -3, -6, -9,
498 -12, -15, -17, -18, -19, -19, -20, -19, -17, -16, -13, -11, -8, -5, -3, 0, 3, 6,
499 7, 9, 11, 12, 12, 12, 12, 12, 11, 10, 9, 9, 7, 6, 4, 4, 2, 1, 0, -1, -2, -3, -4,
500 -5, -6, -7, -8, -9, -9, -10, -10, -10, -10, -9, -8, -7, -4, -1, 2, 4, 9, 13, 15,
501 19, 22, 24, 24, 25, 25, 23, 21, 17, 13, 10, 5, -1, -5, -10, -15, -19, -22, -25,
502 -27, -28, -29, -28, -26, -24, -22, -19, -15, -13, -9, -6, -4, -1, 1, 1, 3, 4, 3,
503 3, 3, 2, 3, 3, 2, 3, 4, 5, 6, 8, 10, 11, 11, 12, 13, 13, 12, 10, 9, 7, 4, 1, -2,
504 -5, -9, -11, -14, -15, -16, -17, -16, -15, -13, -11, -8, -5, -2, 1, 4, 7, 9, 11,
505 12, 12, 12, 12, 11, 9, 7, 5, 3, 1, -1, -2, -3, -5, -5, -6, -6, -6, -5, -5, -3,
506 -1, 0, 2, 4, 7, 7, 9, 11, 11, 11, 12, 12, 11, 10, 8, 6, 4, 2, -1, -4, -7, -10,
507 -12, -14, -16, -18, -19, -20, -20, -19, -19, -18, -17, -15, -13, -11, -9, -7,
508 -4, -2, 0, 3, 6, 7, 9, 11, 12, 13, 14, 14, 13, 13, 12, 10, 8, 5, 1, -2, -5, -8,
509 -12, -14, -17, -19, -19, -20, -21, -20, -19, -17, -15, -12, -10, -7, -4, -1, 2,
510 4, 6, 7, 9, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -3,
511 -4, -5, -6, -8, -8, -9, -10, -10, -9, -8, -7, -5, -3, 0, 2, 6, 9, 11, 14, 16,
512 18, 19, 19, 19, 18, 16, 14, 11, 8, 4, -1, -5, -9, -14, -18, -22, -25, -27, -29,
513 -30, -30, -30, -28, -26, -23, -20, -16, -12, -9, -5, -1, 1, 4, 6, 7, 8, 8, 9, 9,
514 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 8, 8, 7, 5, 4, 2, -1, -3, -6, -8, -10,
515 -12, -14, -14, -15, -14, -14, -12, -10, -8, -6, -3, 0, 3, 5, 8, 10, 11, 13, 13,
516 13, 13, 13, 12, 10, 9, 7, 6, 4, 2, 0, -1, -2, -2, -2, -3, -1, 1, 2, 4, 7, 9, 10,
517 12, 14, 14, 15, 14, 13, 12, 10, 6, 3, 0, -6, -10, -14, -18, -22, -25, -27, -29,
518 -29, -29, -28, -26, -23, -20, -16, -11, -7, -2, 3, 6, 10, 14, 16, 18, 20, 20,
519 19, 19, 16, 14, 11, 7, 4, 1, -2, -6, -9, -11, -12, -13, -14, -14, -13, -11, -11,
520 -9, -7, -5, -4, -3, -1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 5, 6, 7,
521 7, 8, 9, 9, 9, 8, 8, 6, 5, 3, 1, -1, -3, -5, -7, -9, -10, -11, -13, -13, -10,
522 -9, -9, -4, 0, 2, 6, 11, 14, 18, 20, 23, 25, 25, 25, 23, 21, 19, 13, 8, 5, -2,
523 -8, -13, -19, -25, -28, -32, -35, -36, -36, -36, -35, -31, -28, -24, -20, -15,
524 -10, -5, -2, 3, 7, 10, 11, 13, 14, 14, 13, 13, 12, 10, 10, 9, 7, 7, 7, 6, 6, 7,
525 7, 8, 8, 8, 8, 8, 7, 6, 5, 3, 0, -2, -4, -7, -10, -12, -15, -16, -17, -18, -19,
526 -18, -17, -15, -13, -9, -6, -3, 1, 5, 9, 12, 15, 17, 19, 20, 20, 20, 19, 18, 16,
527 13, 10, 8, 5, 2, 1, -2, -3, -2, -2, -2, 0, 2, 3, 5, 7, 9, 10, 11, 11, 10, 9, 8,
528 4, 1, -2, -7, -11, -14, -19, -22, -24, -28, -29, -29, -29, -28, -25, -23, -19,
529 -15, -10, -5, 0, 5, 9, 13, 16, 19, 20, 21, 21, 19, 18, 15, 12, 9, 6, 2, 0, -2,
530 -4, -6, -7, -7, -6, -6, -4, -3, -1, 0, 2, 3, 5, 5, 5, 5, 4, 3, 2, 0, -2, -3, -5,
531 -7, -8, -8, -9, -9, -8, -7, -5, -2, 0, 2, 5, 8, 10, 12, 14, 15, 15, 16, 15, 14,
532 13, 10, 8, 6, 3, 0, -2, -3, -3, -6, -6, -3, -3, -1, 3, 5, 8, 10, 13, 16, 17, 17,
533 18, 15, 15, 13, 8, 5, 1, -6, -9, -14, -21, -24, -27, -31, -33, -33, -33, -32,
534 -31, -28, -25, -21, -17, -12, -8, -3, 1, 4, 8, 10, 12, 14, 16, 15, 15, 15, 14,
535 13, 13, 11, 11, 10, 9, 9, 9, 9, 8, 7, 8, 7, 7, 6, 5, 4, 3, 1, -2, -3, -5, -8,
536 -11, -13, -14, -16, -17, -18, -18, -17, -16, -15, -12, -9, -7, -4, 0, 4, 7, 10,
537 13, 16, 18, 19, 20, 21, 21, 20, 19, 17, 15, 14, 12, 10, 8, 8, 7, 5, 6, 6, 6, 6,
538 6, 7, 7, 6, 5, 3, 1, 0, -4, -7, -9, -14, -17, -20, -24, -25, -27, -29, -30, -28,
539 -28, -26, -24, -21, -16, -13, -10, -5, -1, 3, 6, 9, 12, 15, 16, 17, 18, 18, 18,
540 18, 17, 16, 15, 13, 11, 10, 9, 8, 6, 5, 4, 3, 3, 3, 2, 1, 1, 0, -1, -1, -2, -3,
541 -4, -6, -6, -7, -8, -9, -10, -10, -10, -10, -10, -8, -7, -6, -4, -2, 1, 4, 6, 9,
542 11, 13, 15, 16, 17, 18, 18, 17, 17, 16, 14, 13, 14, 12, 9, 11, 11, 9, 11, 11,
543 10, 11, 10, 10, 11, 9, 8, 6, 2, 2, -2, -7, -9, -14, -18, -20, -26, -27, -28,
544 -32, -33, -32, -32, -30, -29, -27, -23, -19, -16, -11, -6, -1, 3, 7, 11, 16, 18,
545 20, 22, 24, 25, 25, 24, 24, 23, 20, 18, 16, 15, 12, 9, 7, 6, 4, 2, 0, -1, -2,
546 -3, -5, -5, -5, -7, -8, -9, -9, -10, -11, -12, -12, -12, -12, -12, -11, -10, -9,
547 -8, -6, -3, -1, 1, 3, 6, 8, 10, 12, 13, 15, 16, 16, 16, 16, 16, 15, 16, 16, 13,
548 14, 15, 13, 14, 14, 13, 13, 13, 12, 12, 10, 9, 6, 2, 1, -1, -7, -10, -13, -18,
549 -21, -26, -29, -30, -34, -36, -37, -37, -36, -36, -35, -31, -28, -26, -20, -15,
550 -10, -5, -1, 5, 10, 15, 18, 23, 26, 28, 29, 31, 32, 31, 30, 29, 27, 25, 22, 18,
551 15, 13, 8, 5, 2, -1, -4, -7, -9, -11, -13, -15, -16, -17, -17, -18, -18, -18,
552 -17, -17, -16, -15, -14, -12, -11, -9, -7, -5, -3, 0, 2, 5, 7, 9, 12, 14, 16,
553 17, 18, 20, 21, 21, 21, 22, 23, 22, 22, 22, 22, 22, 21, 19, 18, 17, 15, 12, 10,
554 6, 3, -1, -5, -9, -14, -18, -23, -27, -31, -34, -38, -40, -41, -42, -42, -42,
555 -40, -37, -35, -31, -26, -21, -16, -10, -4, 2, 7, 12, 18, 23, 27, 30, 33, 36,
556 38, 39, 39, 40, 39, 37, 35, 33, 30, 27, 22, 19, 15, 10, 6, 1, -3, -7, -11, -14,
557 -17, -19, -22, -24, -25, -25, -26, -26, -25, -24, -23, -21, -19, -16, -14, -11,
558 -8, -4, -1, 3, 6, 10, 13, 16, 19, 22, 25, 27, 29, 31, 33, 34, 36, 36, 36, 36,
559 35, 34, 32, 29, 26, 22, 18, 13, 8, 3, -3, -9, -14, -20, -26, -30, -35, -39, -43,
560 -45, -47, -48, -49, -48, -46, -44, -41, -37, -32, -27, -22, -16, -9, -3, 2, 7,
561 14, 18, 22, 26, 30, 34, 36, 37, 39, 40, 40, 39, 38, 37, 35, 33, 30, 27, 24, 20,
562 16, 12, 9, 4, 0, -4, -7, -11, -15, -18, -21, -23, -25, -27, -28, -28, -29, -29,
563 -28, -26, -25, -23, -20, -17, -14, -11, -7, -3, 1, 4, 9, 13, 17, 21, 26, 30, 34,
564 37, 41, 44, 45, 46, 47, 46, 45, 42, 39, 34, 29, 22, 15, 8, 1, -7, -15, -22, -29,
565 -35, -41, -46, -50, -53, -55, -55, -55, -54, -51, -47, -43, -38, -32, -26, -20,
566 -14, -9, -2, 4, 9, 13, 18, 22, 25, 28, 31, 33, 35, 35, 36, 37, 38, 37, 37, 36,
567 35, 33, 31, 29, 27, 24, 20, 17, 13, 9, 5, 0, -4, -8, -12, -16, -19, -22, -25,
568 -28, -29, -30, -30, -30, -29, -28, -26, -23, -20, -17, -13, -9, -6, -2, 4, 8,
569 11, 17, 21, 24, 29, 32, 35, 37, 38, 38, 38, 37, 35, 32, 27, 25, 19, 13, 8, 2,
570 -3, -10, -16, -20, -24, -29, -33, -36, -38, -40, -41, -40, -39, -38, -36, -33,
571 -29, -26, -23, -19, -14, -11, -8, -3, 0, 3, 6, 9, 13, 16, 18, 21, 23, 26, 27,
572 29, 31, 32, 33, 33, 34, 33, 32, 31, 29, 27, 24, 20, 17, 13, 9, 4, 0, -4, -8,
573 -12, -15, -18, -21, -23, -24, -25, -25, -25, -24, -23, -21, -19, -17, -15, -10,
574 -7, -3, 2, 7, 11, 16, 20, 24, 27, 29, 30, 31, 30, 29, 27, 23, 20, 16, 10, 5, 0,
575 -5, -10, -16, -20, -23, -26, -29, -31, -31, -30, -30, -29, -26, -24, -22, -20,
576 -17, -13, -10, -8, -6, -4, -2, 0, 1, 3, 5, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19,
577 20, 21, 22, 22, 21, 21, 21, 20, 18, 15, 13, 11, 9, 6, 4, 1, -1, -4, -6, -7, -8,
578 -9, -11, -11, -11, -11, -11, -10, -10, -9, -7, -6, -3, 0, 2, 5, 8, 11, 14, 15,
579 17, 18, 19, 18, 17, 16, 14, 12, 9, 5, 2, -2, -6, -10, -13, -17, -19, -22, -23,
580 -25, -26, -26, -26, -25, -24, -23, -21, -19, -18, -16, -14, -11, -10, -8, -6,
581 -4, -2, 0, 3, 5, 7, 9, 11, 14, 16, 17, 18, 21, 22, 22, 23, 23, 23, 22, 21, 20,
582 19, 17, 14, 12, 9, 7, 4, 2, 0, -2, -4, -6, -7, -8, -8, -8, -9, -8, -8, -7, -6,
583 -5, -3, 0, 1, 3, 7, 10, 12, 14, 17, 18, 19, 18, 18, 18, 17, 13, 10, 8, 5, 1, -3,
584 -7, -10, -14, -18, -20, -23, -24, -26, -28, -28, -28, -28, -27, -26, -24, -23,
585 -22, -20, -17, -15, -13, -12, -9, -6, -5, -2, 0, 3, 5, 6, 9, 11, 13, 15, 17, 18,
586 19, 20, 21, 21, 21, 21, 20, 18, 17, 16, 14, 11, 9, 7, 5, 3, 1, -1, -2, -3, -4,
587 -5, -5, -5, -5, -5, -4, -3, -2, -1, 2, 4, 5, 8, 10, 11, 13, 13, 13, 13, 12, 10,
588 9, 7, 4, 1, -2, -4, -7, -10, -13, -15, -17, -20, -22, -22, -23, -24, -24, -24,
589 -24, -23, -22, -21, -20, -19, -18, -16, -14, -12, -11, -10, -8, -7, -6, -4, -3,
590 -1, -1, 0, 2, 3, 5, 7, 8, 9, 10, 10, 12, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7,
591 7, 7, 7, 7, 7, 6, 6, 7, 7, 7, 8, 8, 8, 9, 10, 10, 11, 11, 11, 11, 11, 9, 8, 7,
592 5, 2, 0, -2, -5, -7, -10, -13, -15, -18, -20, -21, -22, -24, -25, -24, -25, -25,
593 -24, -24, -23, -21, -21, -19, -17, -15, -13, -12, -9, -7, -6, -4, -2, -1, 0, 0,
594 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 3, 3, 3, 4, 5, 6, 6,
595 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, 18, 16, 16, 15, 12, 10,
596 8, 5, 2, -1, -4, -7, -10, -13, -16, -18, -21, -23, -25, -26, -27, -29, -29, -29,
597 -29, -29, -29, -28, -26, -25, -24, -22, -19, -16, -14, -11, -9, -6, -4, -3, -2,
598 0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 7,
599 6, 7, 7, 7, 7, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 15, 14, 12,
600 11, 9, 6, 4, 1, -1, -3, -6, -8, -11, -13, -15, -17, -19, -20, -22, -23, -24,
601 -25, -26, -27, -27, -27, -26, -26, -25, -22, -20, -18, -16, -14, -12, -10, -10,
602 -10, -9, -8, -7, -6, -4, -3, -2, -1, -1, 0, 0, 1, 1, 1, 2, 3, 4, 4, 5, 7, 8, 9,
603 10, 12, 13, 13, 14, 15, 16, 17, 17, 18, 19, 19, 19, 20, 20, 21, 20, 20, 19, 18,
604 17, 15, 13, 11, 8, 5, 2, -1, -3, -7, -10, -12, -15, -17, -20, -22, -24, -25,
605 -27, -28, -29, -29, -30, -30, -29, -28, -27, -25, -23, -20, -16, -14, -11, -9,
606 -8, -8, -7, -7, -7, -5, -4, -4, -4, -3, -3, -3, -3, -4, -4, -4, -5, -5, -4, -4,
607 -4, -3, -2, -1, 1, 2, 3, 5, 7, 8, 10, 11, 13, 14, 15, 17, 19, 20, 21, 22, 24,
608 24, 25, 25, 24, 24, 22, 21, 19, 17, 15, 13, 10, 8, 5, 2, 0, -2, -5, -8, -11,
609 -14, -16, -18, -20, -23, -25, -27, -29, -30, -30, -31, -30, -29, -28, -26, -23,
610 -21, -18, -16, -17, -16, -18, -16, -11, -11, -12, -13, -10, -6, -5, -5, -7, -6,
611 -4, -2, -2, -2, -2, 0, 2, 3, 4, 5, 7, 8, 10, 10, 11, 12, 13, 14, 15, 16, 16, 17,
612 19, 20, 20, 21, 21, 21, 21, 20, 20, 19, 17, 16, 14, 12, 11, 9, 7, 5, 3, 1, -1,
613 -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -22, -23, -24, -25, -25, -24, -23,
614 -22, -20, -19, -17, -16, -16, -16, -16, -16, -16, -15, -14, -13, -13, -13, -12,
615 -11, -10, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 2, 4, 5, 6, 8, 10, 11, 13, 14,
616 16, 18, 20, 21, 23, 24, 25, 26, 26, 26, 26, 25, 24, 23, 22, 20, 17, 15, 13, 11,
617 8, 6, 4, 1, -1, -4, -6, -9, -11, -13, -16, -18, -20, -22, -24, -25, -26, -27,
618 -26, -26, -24, -23, -21, -20, -19, -19, -19, -19, -18, -18, -18, -17, -16, -15,
619 -14, -13, -12, -11, -10, -9, -7, -6, -5, -3, -1, 0, 2, 4, 5, 7, 8, 10, 11, 12,
620 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 22, 22, 21, 20, 20, 19, 17, 16, 15,
621 13, 12, 10, 8, 6, 4, 2, 0, -2, -4, -5, -8, -10, -12, -14, -16, -18, -19, -21,
622 -22, -23, -23, -22, -21, -21, -20, -19, -18, -18, -19, -20, -21, -21, -21, -20,
623 -19, -18, -18, -17, -16, -14, -12, -11, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10,
624 12, 14, 15, 17, 19, 20, 22, 23, 25, 26, 26, 27, 28, 28, 27, 27, 26, 25, 23, 21,
625 19, 17, 15, 12, 10, 8, 5, 2, 0, -3, -5, -8, -11, -13, -16, -18, -20, -22, -24,
626 -26, -27, -27, -28, -28, -27, -25, -23, -21, -20, -19, -18, -18, -20, -19, -18,
627 -18, -17, -16, -15, -14, -13, -11, -9, -8, -6, -5, -3, -1, 0, 2, 4, 6, 8, 9, 11,
628 13, 14, 15, 16, 18, 19, 20, 21, 21, 22, 22, 23, 23, 22, 22, 22, 21, 19, 18, 17,
629 16, 14, 12, 11, 9, 7, 5, 3, 1, -2, -5, -7, -10, -13, -15, -18, -20, -23, -25,
630 -26, -27, -28, -27, -26, -25, -23, -22, -20, -20, -21, -22, -24, -24, -24, -24,
631 -23, -22, -21, -20, -18, -15, -13, -11, -9, -7, -5, -3, -1, 2, 4, 6, 8, 10, 12,
632 14, 16, 18, 19, 20, 22, 23, 25, 26, 26, 27, 27, 27, 27, 27, 25, 24, 23, 21, 19,
633 17, 14, 12, 10, 7, 4, 2, 0, -3, -5, -8, -10, -13, -16, -18, -20, -23, -25, -27,
634 -28, -30, -31, -31, -30, -29, -27, -25, -23, -21, -21, -21, -22, -22, -22, -22,
635 -21, -20, -18, -17, -15, -13, -10, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13,
636 15, 17, 18, 20, 21, 22, 24, 25, 26, 27, 27, 27, 27, 27, 26, 25, 23, 22, 20, 18,
637 16, 14, 12, 9, 6, 4, 1, -1, -4, -7, -9, -13, -15, -18, -20, -22, -26, -27, -29,
638 -30, -31, -31, -30, -29, -27, -25, -23, -20, -19, -19, -18, -18, -18, -19, -20,
639 -19, -19, -18, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 4, 5, 7, 9, 11, 13,
640 16, 17, 19, 21, 23, 25, 26, 28, 29, 30, 30, 30, 30, 30, 28, 27, 26, 23, 22, 19,
641 16, 15, 12, 8, 5, 3, 0, -3, -6, -9, -12, -15, -19, -22, -24, -27, -30, -32, -33,
642 -34, -35, -35, -34, -33, -31, -29, -26, -23, -21, -20, -20, -19, -19, -19, -18,
643 -17, -17, -16, -15, -12, -10, -7, -5, -3, 0, 2, 4, 7, 9, 10, 12, 14, 15, 17, 19,
644 21, 22, 24, 25, 26, 28, 28, 29, 29, 28, 28, 27, 26, 25, 22, 20, 18, 16, 13, 10,
645 8, 5, 3, -1, -3, -5, -7, -10, -12, -15, -17, -20, -22, -24, -26, -29, -31, -33,
646 -34, -35, -35, -34, -33, -32, -30, -27, -23, -21, -20, -20, -19, -19, -19, -19,
647 -18, -17, -16, -15, -13, -10, -8, -5, -4, -1, 1, 3, 5, 7, 9, 11, 12, 14, 16, 18,
648 20, 21, 23, 24, 26, 28, 29, 30, 30, 30, 30, 29, 29, 27, 26, 23, 21, 18, 15, 12,
649 9, 5, 2, -1, -4, -7, -10, -13, -16, -19, -22, -25, -26, -28, -31, -33, -35, -36,
650 -37, -38, -37, -37, -36, -34, -32, -28, -25, -23, -21, -20, -19, -18, -17, -17,
651 -16, -16, -15, -14, -11, -9, -6, -4, -2, 1, 3, 5, 8, 10, 12, 14, 15, 17, 19, 21,
652 23, 25, 26, 27, 29, 30, 31, 32, 32, 32, 31, 30, 29, 28, 25, 22, 19, 16, 13, 10,
653 7, 4, 0, -3, -6, -8, -11, -14, -16, -19, -21, -23, -26, -27, -29, -31, -34, -35,
654 -35, -36, -36, -36, -36, -34, -32, -29, -26, -23, -22, -20, -19, -18, -17, -17,
655 -16, -16, -15, -14, -13, -11, -8, -6, -3, -1, 1, 4, 6, 9, 11, 12, 14, 15, 17,
656 19, 21, 23, 24, 26, 27, 29, 31, 32, 33, 33, 34, 32, 32, 30, 28, 27, 24, 20, 18,
657 15, 11, 9, 4, 1, -2, -6, -9, -11, -15, -18, -20, -23, -26, -28, -31, -33, -35,
658 -38, -39, -39, -40, -40, -40, -40, -37, -34, -32, -28, -25, -23, -21, -21, -19,
659 -18, -17, -17, -16, -14, -14, -12, -9, -7, -4, -2, 1, 4, 6, 9, 11, 12, 14, 15,
660 17, 19, 20, 22, 23, 24, 26, 27, 29, 30, 31, 32, 32, 32, 31, 30, 29, 27, 24, 21,
661 18, 15, 12, 9, 6, 2, -1, -4, -6, -9, -12, -13, -16, -19, -21, -23, -25, -28,
662 -30, -33, -35, -36, -38, -39, -39, -38, -38, -37, -35, -32, -29, -27, -24, -23,
663 -21, -20, -20, -19, -18, -18, -17, -16, -15, -12, -10, -8, -5, -2, 1, 3, 6, 8,
664 10, 12, 14, 15, 17, 19, 21, 22, 24, 26, 27, 29, 31, 32, 32, 33, 33, 32, 32, 30,
665 28, 27, 23, 20, 17, 13, 10, 7, 3, 0, -4, -6, -8, -11, -13, -15, -17, -19, -22,
666 -24, -27, -29, -32, -34, -36, -37, -38, -39, -39, -39, -38, -37, -34, -32, -29,
667 -26, -25, -22, -21, -20, -19, -19, -18, -17, -16, -14, -12, -9, -7, -4, -1, 2,
668 4, 7, 9, 11, 13, 14, 16, 18, 20, 22, 24, 25, 27, 28, 29, 31, 32, 33, 33, 34, 32,
669 31, 30, 28, 25, 23, 20, 16, 14, 10, 6, 4, 0, -3, -5, -8, -10, -12, -14, -16,
670 -19, -21, -23, -25, -27, -30, -32, -34, -35, -36, -37, -37, -37, -36, -35, -34,
671 -31, -28, -27, -25, -23, -22, -20, -20, -19, -18, -17, -16, -15, -12, -9, -6,
672 -3, 0, 3, 6, 7, 10, 12, 14, 16, 17, 19, 21, 23, 24, 26, 28, 29, 31, 32, 32, 33,
673 33, 32, 32, 30, 29, 26, 23, 22, 17, 14, 12, 8, 6, 3, -1, -2, -6, -9, -10, -13,
674 -15, -17, -20, -22, -24, -26, -28, -30, -32, -33, -34, -35, -36, -36, -36, -35,
675 -34, -32, -30, -28, -27, -25, -24, -23, -22, -22, -22, -20, -19, -17, -15, -12,
676 -9, -7, -4, -1, 2, 5, 7, 9, 12, 14, 16, 18, 21, 23, 25, 27, 29, 31, 32, 34, 35,
677 36, 36, 35, 34, 33, 32, 30, 26, 24, 20, 16, 14, 11, 7, 6, 3, -1, -2, -5, -8, -9,
678 -12, -15, -16, -20, -22, -23, -26, -28, -28, -31, -32, -33, -35, -34, -34, -35,
679 -34, -33, -32, -30, -28, -27, -25, -23, -22, -21, -20, -20, -19, -18, -17, -15,
680 -12, -10, -6, -4, -1, 2, 4, 7, 9, 11, 14, 15, 17, 19, 22, 23, 26, 28, 30, 31,
681 33, 34, 35, 35, 35, 35, 34, 32, 31, 28, 25, 23, 19, 17, 15, 12, 9, 8, 5, 3, 1,
682 -2, -5, -7, -11, -14, -15, -19, -21, -22, -25, -27, -28, -31, -31, -32, -34,
683 -34, -34, -35, -34, -33, -32, -30, -29, -28, -27, -25, -25, -24, -23, -23, -21,
684 -20, -18, -15, -13, -11, -7, -5, -2, 1, 3, 6, 8, 10, 13, 15, 17, 20, 23, 24, 27,
685 30, 32, 34, 35, 36, 38, 38, 37, 37, 35, 35, 32, 29, 27, 24, 20, 19, 16, 13, 13,
686 10, 7, 6, 2, -1, -3, -7, -10, -12, -16, -18, -19, -22, -24, -25, -28, -29, -30,
687 -31, -32, -33, -34, -34, -34, -34, -33, -32, -31, -29, -28, -28, -26, -26, -26,
688 -24, -24, -22, -20, -18, -16, -13, -11, -8, -5, -3, 0, 2, 4, 6, 9, 10, 13, 15,
689 18, 21, 23, 26, 29, 31, 33, 35, 36, 37, 37, 37, 37, 35, 33, 31, 28, 25, 23, 19,
690 18, 17, 14, 13, 12, 8, 7, 4, 0, -3, -6, -9, -11, -14, -17, -19, -21, -24, -25,
691 -27, -29, -30, -31, -33, -34, -35, -36, -36, -36, -36, -35, -34, -34, -33, -32,
692 -31, -30, -29, -29, -27, -25, -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 3, 4,
693 7, 9, 11, 14, 17, 19, 22, 25, 26, 31, 32, 35, 36, 36, 37, 37, 36, 35, 34, 32,
694 29, 26, 23, 22, 20, 18, 17, 16, 14, 12, 10, 7, 4, 1, -3, -5, -8, -11, -14, -16,
695 -18, -20, -22, -23, -25, -26, -27, -28, -30, -31, -32, -33, -34, -34, -34, -34,
696 -34, -33, -32, -31, -30, -29, -28, -27, -25, -23, -21, -18, -16, -13, -10, -8,
697 -6, -3, -1, 1, 3, 5, 8, 10, 12, 15, 17, 20, 23, 26, 29, 31, 33, 35, 37, 37, 38,
698 38, 37, 36, 35, 33, 30, 28, 26, 23, 22, 21, 20, 19, 17, 15, 14, 10, 7, 4, 0, -3,
699 -6, -9, -12, -14, -17, -19, -20, -22, -24, -25, -26, -27, -28, -30, -31, -32,
700 -34, -35, -35, -35, -35, -34, -34, -32, -30, -29, -27, -25, -24, -22, -20, -18,
701 -16, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 10, 12, 14, 17, 20, 23, 25, 28,
702 31, 33, 35, 36, 37, 38, 37, 37, 35, 34, 32, 30, 27, 25, 24, 22, 21, 20, 20, 17,
703 16, 14, 10, 7, 3, -2, -5, -7, -11, -13, -15, -18, -20, -22, -24, -24, -26, -27,
704 -28, -29, -30, -31, -33, -34, -35, -36, -36, -36, -36, -35, -34, -32, -30, -28,
705 -26, -23, -21, -20, -18, -16, -14, -12, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 10,
706 12, 15, 18, 21, 23, 26, 29, 31, 34, 35, 36, 37, 38, 36, 36, 35, 32, 30, 29, 26,
707 23, 22, 20, 20, 19, 18, 16, 14, 11, 8, 4, 0, -5, -8, -12, -16, -17, -20, -22,
708 -23, -25, -26, -27, -27, -28, -29, -29, -31, -31, -33, -34, -35, -37, -37, -38,
709 -38, -37, -35, -34, -31, -28, -25, -22, -19, -17, -15, -14, -13, -12, -10, -9,
710 -7, -6, -4, -1, 0, 3, 5, 7, 10, 12, 15, 18, 22, 25, 27, 31, 33, 34, 36, 37, 38,
711 38, 37, 36, 36, 33, 30, 29, 26, 23, 22, 21, 19, 19, 18, 16, 14, 11, 8, 3, -1,
712 -6, -10, -13, -16, -19, -20, -21, -23, -23, -24, -24, -24, -25, -26, -26, -27,
713 -29, -30, -32, -34, -35, -37, -37, -37, -37, -36, -34, -32, -29, -25, -21, -17,
714 -14, -13, -11, -10, -10, -10, -9, -8, -7, -5, -3, 0, 3, 6, 8, 11, 14, 17, 19,
715 23, 26, 28, 31, 34, 35, 37, 38, 38, 39, 39, 38, 37, 36, 34, 31, 29, 26, 24, 21,
716 19, 17, 16, 14, 12, 10, 7, 3, -1, -5, -9, -12, -16, -18, -19, -20, -20, -21,
717 -21, -21, -22, -22, -23, -24, -25, -26, -28, -29, -30, -33, -34, -35, -36, -36,
718 -36, -35, -34, -32, -30, -27, -24, -20, -17, -15, -12, -10, -10, -9, -8, -8, -7,
719 -6, -5, -2, 1, 4, 8, 12, 15, 18, 20, 23, 26, 28, 30, 32, 34, 36, 37, 38, 39, 40,
720 40, 39, 38, 37, 35, 33, 30, 28, 24, 20, 17, 14, 12, 10, 8, 7, 5, 2, -1, -5, -9,
721 -12, -16, -19, -19, -21, -21, -21, -22, -21, -23, -24, -24, -26, -26, -28, -29,
722 -31, -32, -34, -35, -36, -38, -38, -37, -37, -35, -32, -30, -28, -25, -23, -19,
723 -17, -14, -11, -10, -7, -6, -5, -3, -2, -1, 1, 4, 7, 11, 14, 18, 21, 23, 26, 28,
724 30, 32, 34, 36, 37, 38, 39, 41, 40, 41, 40, 39, 39, 37, 36, 33, 30, 27, 22, 17,
725 14, 9, 6, 4, 3, 2, 1, -2, -5, -7, -11, -16, -19, -22, -23, -25, -25, -25, -25,
726 -26, -27, -27, -28, -29, -31, -32, -32, -34, -35, -35, -37, -38, -39, -40, -39,
727 -37, -35, -33, -29, -27, -24, -21, -18, -16, -13, -11, -8, -5, -3, 0, 2, 4, 6,
728 8, 10, 14, 17, 20, 24, 27, 29, 32, 34, 36, 38, 39, 40, 42, 43, 44, 45, 45, 45,
729 44, 43, 42, 38, 39, 36, 28, 29, 21, 16, 14, 5, 0, -2, -6, -9, -7, -10, -12, -11,
730 -15, -19, -21, -26, -30, -30, -32, -33, -30, -30, -30, -29, -30, -32, -32, -34,
731 -35, -35, -36, -36, -35, -37, -38, -37, -38, -37, -35, -33, -29, -25, -22, -18,
732 -15, -13, -10, -8, -6, -3, -1, 2, 6, 8, 10, 13, 15, 18, 22, 24, 27, 31, 33, 37,
733 40, 41, 43, 45, 45, 46, 48, 49, 49, 50, 50, 49, 48, 46, 43, 40, 36, 32, 27, 22,
734 17, 11, 5, -1, -7, -11, -16, -19, -19, -21, -21, -22, -24, -27, -28, -32, -36,
735 -36, -38, -38, -36, -35, -34, -33, -34, -35, -35, -36, -38, -38, -38, -37, -37,
736 -37, -36, -36, -34, -34, -33, -29, -25, -22, -18, -14, -11, -7, -5, -3, 0, 2, 4,
737 7, 10, 13, 17, 21, 24, 27, 30, 32, 35, 38, 40, 43, 45, 47, 49, 50, 50, 51, 52,
738 52, 52, 52, 51, 50, 48, 44, 40, 37, 31, 26, 21, 14, 8, 2, -5, -11, -15, -23,
739 -25, -26, -28, -29, -29, -30, -31, -32, -38, -39, -41, -46, -45, -44, -43, -40,
740 -38, -39, -37, -37, -40, -38, -40, -40, -37, -38, -36, -34, -33, -33, -30, -29,
741 -27, -22, -20, -15, -10, -5, -1, 2, 4, 7, 9, 11, 14, 17, 20, 24, 27, 30, 34, 36,
742 38, 41, 43, 45, 48, 50, 51, 54, 55, 55, 55, 55, 54, 53, 52, 50, 49, 47, 43, 39,
743 36, 30, 24, 21, 14, 7, 3, -4, -11, -14, -21, -28, -29, -35, -41, -41, -44, -47,
744 -45, -48, -48, -46, -48, -48, -47, -47, -47, -46, -46, -44, -43, -43, -41, -39,
745 -39, -37, -36, -34, -32, -30, -28, -25, -23, -19, -15, -12, -7, -4, 0, 4, 8, 10,
746 14, 17, 19, 22, 25, 27, 31, 34, 35, 38, 41, 42, 45, 47, 48, 50, 51, 52, 52, 53,
747 54, 52, 52, 52, 50, 49, 48, 44, 42, 40, 34, 31, 27, 20, 15, 10, 4, -3, -8, -16,
748 -21, -27, -35, -39, -44, -48, -51, -54, -56, -56, -58, -59, -58, -57, -56, -54,
749 -54, -54, -51, -50, -48, -44, -42, -39, -36, -35, -32, -30, -29, -27, -24, -22,
750 -17, -14, -11, -4, 0, 2, 7, 9, 12, 16, 18, 20, 25, 27, 29, 33, 35, 36, 38, 40,
751 41, 43, 45, 47, 49, 50, 51, 52, 51, 51, 51, 50, 48, 47, 47, 45, 44, 42, 39, 37,
752 33, 27, 23, 19, 12, 7, 3, -5, -11, -15, -24, -28, -33, -43, -46, -49, -56, -58,
753 -59, -64, -62, -62, -66, -63, -61, -62, -59, -55, -55, -51, -47, -47, -41, -39,
754 -38, -33, -30, -29, -25, -21, -19, -14, -11, -8, -3, 1, 5, 8, 13, 17, 19, 23,
755 26, 28, 32, 33, 35, 38, 40, 41, 44, 46, 47, 49, 51, 51, 53, 53, 52, 53, 53, 51,
756 51, 50, 48, 46, 45, 43, 41, 39, 36, 33, 29, 25, 20, 15, 11, 4, -2, -7, -13, -22,
757 -26, -32, -40, -44, -50, -55, -56, -60, -65, -64, -66, -70, -68, -67, -68, -65,
758 -63, -61, -57, -53, -51, -47, -42, -40, -35, -32, -27, -23, -20, -16, -12, -8,
759 -4, 1, 6, 12, 17, 21, 26, 29, 32, 35, 37, 40, 42, 43, 46, 49, 49, 52, 54, 54,
760 55, 56, 55, 56, 56, 54, 54, 54, 51, 50, 49, 45, 43, 42, 38, 35, 34, 30, 26, 25,
761 19, 14, 10, 4, -2, -7, -14, -20, -24, -31, -37, -41, -47, -52, -58, -60, -64,
762 -68, -69, -71, -71, -73, -72, -72, -71, -69, -68, -64, -61, -57, -53, -48, -43,
763 -38, -33, -29, -23, -18, -15, -9, -4, 2, 6, 13, 19, 24, 29, 33, 38, 41, 44, 47,
764 49, 51, 53, 55, 56, 58, 59, 60, 60, 60, 60, 59, 59, 58, 56, 55, 53, 51, 49, 46,
765 43, 40, 37, 33, 30, 26, 22, 18, 14, 9, 4, -2, -8, -12, -19, -25, -30, -36, -43,
766 -46, -53, -57, -59, -66, -70, -70, -74, -78, -76, -77, -77, -75, -74, -73, -68,
767 -66, -65, -59, -54, -51, -46, -40, -36, -30, -25, -20, -13, -8, -2, 4, 10, 17,
768 23, 28, 34, 40, 43, 46, 51, 53, 54, 57, 59, 59, 62, 63, 63, 66, 65, 64, 65, 65,
769 62, 61, 60, 57, 54, 52, 49, 46, 43, 39, 35, 32, 28, 23, 19, 16, 10, 4, 0, -7,
770 -14, -19, -26, -33, -37, -44, -50, -54, -58, -63, -68, -70, -74, -77, -79, -80,
771 -81, -81, -80, -80, -78, -75, -72, -69, -64, -59, -56, -50, -44, -39, -34, -29,
772 -21, -15, -9, -2, 4, 11, 19, 25, 30, 37, 43, 47, 52, 56, 59, 62, 64, 65, 67, 68,
773 69, 70, 71, 71, 70, 71, 70, 68, 66, 64, 61, 58, 55, 51, 48, 45, 40, 36, 33, 28,
774 23, 18, 13, 9, 2, -3, -9, -16, -21, -29, -37, -41, -45, -55, -60, -62, -67, -73,
775 -76, -77, -80, -81, -84, -85, -83, -82, -84, -82, -76, -75, -73, -67, -62, -58,
776 -52, -47, -42, -34, -29, -23, -15, -8, 0, 6, 14, 23, 29, 35, 44, 49, 52, 59, 62,
777 65, 69, 71, 72, 75, 78, 77, 78, 81, 79, 78, 78, 77, 74, 72, 69, 64, 62, 57, 52,
778 49, 44, 38, 34, 30, 24, 19, 14, 9, 3, -4, -10, -17, -24, -30, -37, -46, -50,
779 -55, -66, -66, -72, -78, -80, -84, -88, -89, -89, -91, -91, -90, -88, -88, -86,
780 -78, -78, -73, -66, -64, -55, -50, -44, -38, -29, -23, -17, -9, -2, 7, 15, 22,
781 31, 37, 44, 52, 57, 61, 68, 70, 73, 77, 77, 79, 82, 82, 82, 82, 83, 82, 80, 79,
782 77, 73, 70, 67, 61, 58, 53, 47, 44, 38, 32, 28, 23, 17, 11, 5, -1, -8, -15, -21,
783 -27, -35, -39, -48, -54, -56, -65, -69, -72, -77, -81, -85, -88, -89, -90, -91,
784 -91, -93, -87, -87, -87, -79, -76, -73, -66, -62, -55, -48, -42, -36, -29, -21,
785 -15, -9, 1, 9, 16, 25, 32, 41, 47, 54, 61, 65, 70, 72, 74, 78, 79, 80, 82, 82,
786 82, 83, 82, 82, 80, 78, 76, 72, 69, 65, 59, 56, 51, 45, 41, 36, 32, 26, 22, 18,
787 12, 6, 0, -5, -11, -19, -24, -31, -38, -42, -49, -56, -58, -62, -70, -72, -73,
788 -80, -81, -83, -87, -86, -86, -88, -87, -84, -82, -80, -78, -69, -67, -65, -54,
789 -51, -46, -35, -33, -27, -18, -13, -6, 1, 10, 18, 24, 34, 41, 47, 56, 61, 65,
790 69, 72, 74, 75, 78, 78, 77, 80, 78, 77, 79, 77, 76, 74, 71, 68, 65, 61, 57, 52,
791 48, 42, 37, 34, 29, 24, 21, 17, 13, 7, 2, -2, -9, -15, -21, -28, -34, -39, -47,
792 -52, -54, -61, -66, -68, -72, -75, -79, -80, -82, -85, -83, -86, -87, -83, -82,
793 -82, -76, -72, -68, -63, -57, -51, -46, -38, -32, -29, -20, -15, -10, -1, 4, 12,
794 19, 27, 35, 41, 51, 57, 60, 67, 70, 72, 75, 76, 76, 76, 76, 76, 74, 75, 75, 72,
795 72, 70, 66, 65, 60, 56, 53, 47, 42, 37, 33, 30, 25, 21, 18, 14, 10, 5, 1, -3,
796 -9, -15, -21, -26, -32, -38, -43, -50, -53, -56, -64, -65, -69, -72, -74, -79,
797 -81, -79, -83, -85, -81, -83, -79, -79, -76, -70, -68, -62, -58, -51, -44, -40,
798 -33, -28, -20, -17, -11, -2, 3, 8, 17, 24, 30, 40, 45, 52, 59, 62, 66, 68, 72,
799 73, 71, 73, 73, 72, 71, 71, 70, 69, 67, 65, 62, 61, 58, 53, 51, 46, 41, 38, 33,
800 30, 27, 23, 21, 18, 15, 12, 8, 4, -2, -7, -12, -18, -24, -29, -33, -39, -44,
801 -48, -52, -56, -60, -65, -66, -72, -75, -77, -80, -80, -83, -83, -80, -79, -78,
802 -72, -69, -63, -58, -56, -47, -43, -38, -32, -27, -20, -16, -11, -4, 3, 10, 16,
803 24, 33, 39, 46, 53, 58, 65, 66, 68, 71, 70, 71, 70, 69, 70, 68, 67, 67, 66, 65,
804 64, 61, 58, 55, 51, 46, 42, 38, 32, 30, 26, 24, 21, 20, 19, 17, 16, 13, 10, 7,
805 1, -5, -9, -15, -21, -26, -30, -33, -39, -42, -42, -51, -53, -53, -62, -65, -67,
806 -72, -76, -78, -78, -80, -79, -77, -74, -71, -66, -61, -58, -51, -45, -43, -39,
807 -30, -27, -24, -17, -14, -8, 0, 3, 11, 20, 27, 35, 41, 49, 55, 58, 62, 64, 64,
808 64, 65, 64, 62, 63, 62, 61, 63, 61, 60, 61, 59, 55, 52, 48, 45, 39, 33, 30, 25,
809 22, 20, 18, 18, 19, 18, 16, 15, 13, 9, 5, -1, -8, -11, -18, -24, -27, -31, -35,
810 -38, -41, -43, -45, -51, -54, -56, -64, -68, -72, -77, -77, -82, -81, -79, -77,
811 -73, -70, -64, -58, -53, -49, -44, -38, -34, -30, -26, -21, -18, -12, -9, -2, 5,
812 11, 20, 25, 34, 42, 47, 53, 57, 59, 61, 61, 59, 59, 59, 58, 56, 56, 56, 56, 57,
813 56, 56, 55, 52, 49, 44, 40, 35, 29, 24, 20, 18, 17, 17, 17, 18, 19, 19, 18, 16,
814 14, 9, 3, -4, -8, -15, -21, -24, -28, -31, -33, -36, -38, -40, -41, -47, -53,
815 -55, -63, -70, -71, -77, -81, -79, -79, -79, -75, -67, -64, -59, -50, -48, -43,
816 -37, -35, -32, -28, -24, -22, -18, -13, -7, 0, 8, 15, 24, 33, 40, 47, 52, 57,
817 58, 58, 58, 56, 57, 56, 54, 54, 55, 55, 56, 57, 57, 57, 56, 53, 48, 44, 38, 31,
818 26, 20, 16, 14, 13, 14, 16, 17, 19, 21, 20, 19, 16, 13, 7, 0, -7, -12, -17, -22,
819 -24, -27, -28, -28, -29, -33, -33, -36, -44, -49, -57, -62, -68, -74, -77, -80,
820 -78, -76, -74, -69, -61, -56, -52, -47, -42, -38, -36, -33, -32, -29, -25, -22,
821 -19, -12, -4, 2, 10, 19, 27, 34, 41, 46, 49, 52, 53, 52, 50, 51, 50, 49, 50, 50,
822 51, 53, 55, 55, 55, 55, 52, 49, 44, 39, 33, 28, 24, 19, 17, 19, 20, 21, 24, 26,
823 28, 28, 28, 25, 20, 16, 9, 0, -5, -10, -15, -17, -19, -21, -22, -22, -26, -31,
824 -30, -38, -46, -53, -62, -66, -75, -81, -80, -81, -81, -76, -74, -67, -59, -58,
825 -52, -47, -44, -42, -41, -37, -34, -31, -29, -23, -15, -10, -2, 6, 15, 24, 29,
826 35, 42, 46, 48, 49, 50, 51, 50, 50, 49, 52, 54, 53, 55, 56, 57, 56, 54, 52, 49,
827 44, 39, 33, 28, 24, 20, 19, 18, 19, 21, 22, 25, 26, 26, 27, 24, 21, 16, 11, 6,
828 -1, -6, -9, -12, -15, -16, -16, -18, -20, -25, -28, -31, -40, -47, -54, -62,
829 -68, -74, -79, -78, -79, -78, -74, -70, -65, -61, -56, -53, -49, -46, -45, -41,
830 -38, -35, -31, -27, -20, -13, -8, 0, 9, 16, 22, 28, 34, 38, 42, 44, 45, 48, 48,
831 48, 49, 50, 52, 52, 53, 54, 54, 54, 53, 50, 48, 44, 41, 36, 32, 29, 23, 21, 20,
832 19, 19, 20, 22, 23, 24, 25, 24, 23, 21, 18, 14, 10, 6, 0, -4, -5, -9, -10, -11,
833 -13, -15, -19, -24, -27, -33, -41, -48, -56, -60, -67, -73, -73, -74, -75, -72,
834 -70, -67, -61, -59, -56, -52, -48, -46, -44, -40, -37, -33, -28, -23, -15, -10,
835 -3, 3, 9, 17, 20, 25, 32, 34, 37, 40, 42, 45, 46, 48, 50, 51, 52, 52, 53, 53,
836 52, 51, 49, 47, 44, 40, 38, 34, 31, 29, 25, 24, 22, 21, 21, 21, 23, 23, 23, 25,
837 23, 22, 21, 18, 15, 11, 8, 3, 0, -2, -6, -8, -10, -14, -17, -20, -25, -31, -36,
838 -42, -49, -56, -62, -65, -70, -74, -73, -74, -72, -70, -68, -63, -60, -56, -53,
839 -50, -45, -43, -39, -35, -30, -24, -20, -13, -7, -2, 5, 9, 15, 20, 25, 30, 32,
840 37, 40, 41, 46, 46, 48, 50, 49, 51, 50, 50, 50, 48, 48, 45, 42, 40, 37, 36, 33,
841 30, 28, 25, 24, 22, 20, 21, 20, 22, 22, 23, 23, 23, 23, 23, 21, 19, 16, 13, 8,
842 5, 2, -2, -4, -7, -10, -13, -16, -21, -28, -30, -36, -45, -48, -56, -62, -64,
843 -71, -71, -72, -73, -70, -70, -66, -61, -59, -55, -51, -47, -44, -39, -35, -32,
844 -25, -21, -17, -8, -5, 2, 8, 12, 18, 22, 28, 31, 34, 39, 40, 44, 46, 46, 49, 48,
845 49, 50, 47, 49, 47, 45, 44, 42, 40, 37, 35, 33, 30, 29, 26, 23, 21, 19, 19, 18,
846 18, 19, 19, 21, 22, 23, 24, 23, 23, 21, 19, 17, 13, 10, 6, 4, 0, -3, -4, -8,
847 -12, -15, -21, -25, -30, -38, -44, -50, -56, -60, -65, -68, -69, -70, -70, -67,
848 -65, -62, -59, -57, -53, -49, -46, -42, -38, -33, -28, -22, -17, -12, -6, -1, 4,
849 8, 13, 18, 21, 26, 29, 32, 36, 39, 42, 45, 46, 48, 48, 49, 48, 46, 46, 45, 43,
850 41, 39, 37, 35, 34, 32, 29, 28, 26, 23, 21, 20, 19, 18, 18, 19, 20, 21, 22, 23,
851 24, 25, 25, 24, 23, 20, 17, 14, 10, 7, 3, 0, -3, -8, -10, -14, -21, -24, -29,
852 -36, -42, -47, -55, -60, -63, -69, -71, -72, -72, -72, -69, -66, -63, -60, -54,
853 -52, -48, -43, -39, -35, -30, -24, -20, -15, -9, -4, 1, 6, 11, 15, 19, 25, 28,
854 32, 36, 38, 41, 44, 46, 47, 47, 47, 47, 45, 45, 44, 43, 40, 40, 37, 34, 33, 31,
855 28, 27, 24, 22, 20, 18, 17, 16, 17, 17, 19, 21, 22, 24, 25, 26, 27, 26, 25, 24,
856 21, 18, 14, 11, 9, 5, 2, -1, -5, -8, -14, -18, -24, -30, -35, -45, -50, -55,
857 -64, -68, -72, -75, -75, -76, -74, -72, -69, -65, -63, -57, -54, -49, -45, -42,
858 -36, -33, -27, -21, -17, -8, -3, 2, 10, 13, 19, 24, 28, 33, 35, 39, 42, 43, 48,
859 48, 50, 51, 52, 52, 50, 49, 48, 45, 44, 40, 38, 35, 31, 29, 25, 24, 21, 18, 18,
860 15, 14, 13, 13, 14, 14, 17, 19, 20, 23, 24, 25, 26, 26, 27, 25, 25, 22, 18, 17,
861 13, 11, 7, 4, 1, -5, -9, -14, -21, -28, -34, -43, -50, -55, -61, -68, -71, -73,
862 -76, -76, -74, -74, -71, -68, -65, -63, -59, -54, -52, -46, -40, -34, -28, -20,
863 -13, -7, 0, 7, 11, 17, 23, 26, 29, 34, 36, 38, 41, 45, 48, 50, 53, 53, 54, 53,
864 51, 48, 46, 43, 39, 35, 32, 29, 25, 23, 21, 20, 19, 18, 16, 14, 14, 11, 10, 11,
865 11, 12, 14, 17, 19, 21, 25, 27, 29, 31, 32, 31, 29, 27, 23, 19, 17, 13, 11, 7,
866 3, -1, -6, -11, -19, -25, -30, -41, -48, -56, -64, -70, -77, -78, -80, -82, -79,
867 -79, -77, -73, -69, -66, -62, -55, -51, -47, -40, -36, -28, -21, -14, -5, 1, 9,
868 14, 20, 27, 29, 34, 37, 39, 41, 41, 43, 44, 46, 48, 48, 49, 48, 47, 45, 42, 40,
869 36, 31, 28, 23, 20, 15, 12, 10, 8, 8, 6, 6, 5, 4, 3, 3, 3, 6, 8, 11, 14, 17, 20,
870 24, 28, 31, 34, 37, 38, 38, 36, 34, 32, 28, 26, 23, 19, 15, 9, 5, -3, -10, -16,
871 -25, -33, -41, -51, -59, -66, -74, -79, -81, -83, -84, -82, -81, -79, -75, -73,
872 -68, -64, -58, -53, -50, -42, -35, -30, -22, -13, -4, 4, 11, 17, 22, 27, 29, 32,
873 35, 35, 36, 37, 37, 40, 41, 44, 47, 48, 49, 47, 45, 41, 38, 33, 27, 23, 17, 12,
874 9, 5, 4, 3, 4, 4, 4, 5, 3, 2, 1, 0, 2, 4, 7, 11, 15, 20, 25, 31, 38, 44, 48, 51,
875 53, 52, 49, 47, 43, 39, 36, 32, 29, 24, 20, 14, 6, 2, -5, -16, -22, -34, -46,
876 -55, -66, -74, -80, -85, -88, -89, -88, -89, -86, -82, -79, -74, -70, -65, -61,
877 -58, -52, -47, -41, -32, -25, -15, -6, 2, 10, 15, 22, 28, 31, 36, 37, 37, 36,
878 36, 37, 38, 42, 45, 47, 50, 49, 48, 46, 43, 40, 35, 30, 24, 17, 12, 6, 2, 2, 1,
879 2, 4, 4, 5, 4, 3, 2, 2, 5, 8, 10, 14, 19, 23, 28, 35, 42, 48, 54, 57, 59, 59,
880 57, 54, 51, 50, 47, 42, 38, 33, 28, 21, 15, 7, -1, -9, -20, -32, -43, -54, -65,
881 -75, -82, -87, -91, -95, -97, -97, -97, -96, -93, -89, -85, -81, -76, -72, -66,
882 -60, -53, -44, -35, -25, -15, -6, 3, 11, 19, 24, 30, 36, 38, 41, 42, 41, 42, 41,
883 41, 44, 47, 50, 51, 52, 51, 49, 46, 41, 38, 32, 25, 18, 11, 6, 1, -3, -4, -3,
884 -3, -3, -3, -5, -7, -8, -8, -8, -6, -2, 4, 9, 16, 25, 31, 38, 46, 53, 59, 62,
885 61, 62, 63, 61, 59, 58, 59, 58, 54, 52, 48, 42, 35, 26, 15, 5, -8, -24, -38,
886 -49, -62, -73, -80, -87, -91, -96, -99, -100, -102, -102, -103, -102, -98, -99,
887 -96, -91, -86, -78, -71, -59, -49, -37, -24, -16, -4, 6, 14, 22, 28, 35, 39, 41,
888 44, 46, 48, 49, 51, 52, 52, 57, 56, 56, 58, 54, 52, 48, 43, 37, 30, 24, 16, 11,
889 6, 2, -1, -4, -4, -4, -5, -4, -6, -6, -6, -8, -9, -9, -9, -8, -5, 1, 7, 14, 22,
890 29, 36, 42, 47, 50, 52, 54, 54, 54, 54, 52, 52, 52, 51, 51, 48, 43, 37, 30, 19,
891 10, 1, -14, -23, -33, -47, -52, -60, -69, -72, -77, -81, -84, -88, -92, -94,
892 -95, -97, -97, -93, -89, -83, -78, -70, -60, -53, -43, -33, -24, -14, -7, 0, 7,
893 13, 20, 24, 30, 35, 38, 42, 45, 47, 48, 49, 50, 48, 48, 48, 46, 45, 43, 40, 38,
894 34, 30, 25, 21, 18, 12, 8, 5, 1, -2, -4, -6, -7, -8, -9, -11, -10, -10, -12,
895 -12, -11, -9, -7, -1, 4, 9, 16, 20, 24, 30, 33, 37, 39, 41, 43, 45, 46, 47, 49,
896 52, 53, 54, 53, 51, 46, 38, 31, 22, 14, 6, -4, -12, -20, -30, -37, -42, -50,
897 -56, -57, -65, -72, -75, -83, -89, -90, -92, -92, -88, -87, -84, -75, -70, -64,
898 -55, -49, -40, -34, -28, -21, -18, -12, -8, -2, 4, 11, 17, 20, 26, 30, 32, 35,
899 35, 35, 32, 28, 27, 24, 25, 25, 25, 27, 27, 25, 24, 22, 20, 16, 13, 9, 4, 1, -5,
900 -7, -8, -9, -6, -5, -1, 3, 5, 8, 10, 12, 14, 16, 17, 21, 24, 27, 31, 37, 41, 46,
901 52, 57, 61, 64, 66, 67, 68, 68, 66, 64, 62, 58, 54, 48, 40, 31, 24, 14, 4, -4,
902 -14, -26, -36, -45, -54, -62, -68, -75, -80, -83, -90, -95, -96, -100, -100,
903 -100, -99, -94, -91, -86, -80, -72, -63, -58, -49, -40, -33, -26, -20, -14, -8,
904 -2, 4, 8, 16, 19, 20, 23, 24, 26, 25, 24, 24, 29, 35, 36, 41, 44, 43, 43, 39,
905 38, 35, 30, 26, 21, 17, 12, 7, 5, 5, 7, 6, 6, 6, 1, -1, -5, -10, -14, -18, -22,
906 -24, -23, -20, -16, -5, 6, 17, 29, 39, 45, 48, 51, 53, 54, 57, 57, 60, 66, 69,
907 72, 78, 87, 93, 96, 98, 94, 86, 73, 54, 37, 22, 6, -9, -20, -27, -37, -44, -51,
908 -57, -61, -65, -72, -80, -89, -100, -110, -121, -125, -127, -128, -121, -115,
909 -106, -94, -87, -75, -64, -56, -46, -40, -36, -33, -31, -28, -22, -15, -8, 4,
910 15, 23, 33, 37, 41, 45, 41, 42, 48, 47, 48, 49, 47, 46, 46, 44, 46, 49, 48, 46,
911 43, 38, 32, 24, 17, 14, 9, 4, 0, -7, -11, -14, -20, -22, -23, -24, -27, -28,
912 -30, -33, -33, -32, -28, -21, -11, -2, 6, 16, 24, 31, 40, 47, 53, 61, 67, 70,
913 73, 77, 81, 85, 91, 96, 100, 101, 99, 92, 84, 73, 59, 46, 35, 21, 8, -6, -19,
914 -31, -42, -51, -58, -65, -73, -81, -90, -100, -107, -116, -122, -122, -124,
915 -123, -119, -116, -108, -101, -98, -84, -74, -69, -58, -50, -45, -38, -34, -31,
916 -22, -14, -9, 0, 7, 12, 18, 20, 24, 28, 28, 34, 39, 43, 48, 49, 49, 49, 49, 47,
917 45, 45, 41, 38, 34, 28, 25, 19, 17, 16, 13, 12, 7, 4, 1, -6, -9, -13, -13, -13,
918 -13, -9, -6, -2, 2, 7, 14, 20, 27, 30, 35, 40, 41, 45, 49, 52, 59, 64, 70, 75,
919 79, 82, 83, 84, 82, 79, 75, 67, 58, 47, 36, 24, 12, 2, -7, -14, -23, -32, -40,
920 -49, -57, -65, -74, -81, -88, -96, -103, -107, -112, -114, -112, -110, -103,
921 -97, -91, -83, -77, -69, -61, -53, -43, -37, -30, -23, -18, -12, -7, 0, 8, 15,
922 22, 23, 28, 31, 29, 29, 27, 25, 20, 13, 10, 10, 13, 15, 17, 23, 26, 26, 25, 23,
923 23, 19, 14, 11, 8, 4, 0, -2, 0, 3, 7, 9, 14, 16, 16, 15, 9, 5, 2, -4, -7, -8,
924 -8, -8, -5, 1, 9, 18, 27, 35, 41, 44, 46, 46, 44, 44, 43, 45, 49, 51, 55, 60,
925 65, 70, 73, 76, 76, 72, 64, 54, 42, 28, 14, 3, -5, -12, -20, -25, -30, -35, -41,
926 -47, -53, -60, -68, -75, -84, -92, -100, -105, -106, -104, -102, -96, -86, -80,
927 -73, -67, -61, -53, -50, -44, -37, -35, -31, -29, -27, -20, -15, -10, -1, 7, 11,
928 15, 16, 15, 16, 12, 6, 3, -2, -3, 0, 3, 8, 14, 19, 24, 28, 29, 31, 30, 26, 23,
929 19, 14, 13, 11, 12, 16, 20, 25, 30, 34, 37, 38, 35, 31, 27, 22, 17, 12, 9, 8, 7,
930 8, 12, 17, 23, 28, 30, 33, 34, 33, 31, 28, 27, 27, 27, 28, 32, 36, 41, 46, 50,
931 54, 55, 53, 48, 41, 33, 23, 13, 5, -1, -5, -8, -12, -15, -16, -20, -24, -28,
932 -35, -42, -50, -59, -68, -74, -80, -85, -83, -82, -79, -72, -68, -64, -58, -56,
933 -53, -51, -47, -47, -45, -41, -41, -37, -33, -29, -21, -17, -11, -7, -2, 2, -1,
934 0, -2, -5, -9, -17, -19, -19, -17, -7, 0, 10, 20, 24, 27, 29, 30, 27, 25, 22,
935 17, 16, 11, 8, 11, 15, 22, 29, 35, 41, 43, 41, 38, 31, 23, 16, 11, 7, 6, 7, 8,
936 14, 20, 28, 39, 46, 51, 52, 51, 49, 45, 40, 37, 37, 41, 43, 47, 54, 60, 65, 68,
937 71, 71, 67, 58, 45, 33, 19, 5, -7, -15, -18, -21, -23, -26, -29, -32, -38, -44,
938 -52, -60, -69, -79, -86, -94, -99, -101, -100, -93, -89, -82, -73, -70, -64,
939 -58, -56, -50, -47, -45, -39, -36, -35, -31, -25, -23, -16, -8, -4, 3, 6, 8, 9,
940 6, 5, 1, -3, -6, -14, -17, -15, -14, -6, 3, 11, 19, 23, 25, 24, 24, 20, 16, 12,
941 8, 7, 3, 3, 9, 13, 21, 30, 36, 44, 47, 46, 43, 38, 32, 26, 23, 21, 22, 24, 27,
942 34, 40, 48, 57, 61, 64, 64, 60, 56, 50, 44, 40, 40, 41, 42, 45, 49, 53, 55, 56,
943 54, 50, 43, 31, 18, 5, -9, -21, -30, -35, -37, -38, -39, -40, -42, -45, -49,
944 -55, -63, -69, -77, -85, -90, -96, -98, -96, -93, -88, -79, -70, -63, -55, -50,
945 -48, -42, -39, -37, -33, -31, -28, -23, -20, -13, -6, 1, 7, 14, 17, 19, 21, 16,
946 15, 13, 6, 2, -3, -10, -13, -14, -9, 0, 8, 18, 26, 28, 28, 25, 20, 19, 16, 9, 7,
947 8, 4, 4, 8, 14, 23, 32, 38, 43, 44, 41, 34, 25, 20, 14, 10, 11, 14, 17, 23, 30,
948 37, 47, 56, 60, 62, 60, 54, 47, 41, 36, 33, 36, 41, 46, 53, 59, 64, 67, 68, 66,
949 61, 52, 39, 23, 8, -6, -20, -29, -32, -33, -33, -33, -35, -40, -43, -48, -57,
950 -62, -70, -80, -86, -93, -97, -97, -95, -89, -81, -70, -64, -58, -50, -47, -42,
951 -39, -34, -29, -29, -25, -23, -19, -13, -8, 0, 9, 18, 19, 21, 24, 18, 16, 13, 7,
952 5, -2, -10, -18, -22, -21, -18, -8, 4, 13, 19, 20, 20, 16, 12, 10, 6, 4, 2, -1,
953 -2, 0, 5, 13, 24, 36, 44, 50, 51, 47, 41, 33, 26, 22, 19, 19, 19, 22, 27, 32,
954 41, 51, 60, 65, 65, 61, 53, 46, 38, 32, 31, 32, 36, 40, 46, 51, 56, 61, 63, 63,
955 60, 51, 39, 23, 9, -5, -17, -22, -26, -26, -25, -26, -28, -31, -34, -39, -47,
956 -55, -64, -75, -84, -90, -95, -95, -91, -86, -78, -71, -65, -58, -54, -50, -46,
957 -43, -40, -39, -37, -34, -31, -23, -16, -7, 4, 11, 15, 18, 18, 17, 14, 11, 7, 3,
958 -1, -5, -9, -13, -15, -18, -23, -22, -18, -17, -11, -4, -3, 0, 2, 0, 2, 6, 6, 8,
959 11, 14, 16, 20, 26, 35, 42, 48, 55, 56, 58, 58, 53, 49, 47, 42, 39, 40, 40, 40,
960 43, 44, 46, 50, 51, 51, 47, 42, 35, 28, 24, 20, 18, 20, 24, 27, 30, 35, 39, 41,
961 44, 42, 40, 36, 27, 17, 7, -2, -12, -18, -21, -24, -24, -26, -28, -31, -35, -39,
962 -44, -51, -57, -65, -74, -78, -84, -88, -85, -84, -81, -75, -69, -64, -58, -52,
963 -48, -40, -34, -31, -24, -21, -14, -11, -9, -1, 4, 7, 14, 18, 21, 25, 26, 25,
964 28, 27, 21, 20, 15, 12, 9, 3, -2, -7, -11, -16, -16, -11, -10, -8, -4, -4, -3,
965 -1, 3, 12, 19, 22, 24, 21, 19, 18, 17, 24, 34, 37, 40, 46, 47, 49, 51, 50, 56,
966 60, 57, 54, 49, 45, 40, 36, 37, 41, 41, 40, 36, 32, 28, 24, 20, 21, 23, 22, 19,
967 16, 14, 15, 17, 20, 23, 25, 21, 14, 5, -4, -13, -20, -24, -25, -27, -30, -31,
968 -34, -35, -34, -32, -31, -32, -39, -46, -54, -65, -71, -73, -73, -68, -64, -60,
969 -54, -50, -43, -32, -25, -19, -10, -8, -10, -9, -8, -9, -7, -4, 0, 6, 8, 11, 13,
970 13, 17, 15, 9, 8, 2, -12, -20, -30, -43, -46, -47, -46, -35, -26, -16, -4, 4,
971 12, 17, 18, 20, 19, 13, 13, 13, 11, 17, 28, 37, 51, 63, 70, 76, 78, 75, 69, 62,
972 54, 45, 36, 29, 25, 23, 24, 29, 34, 40, 43, 40, 37, 32, 23, 15, 10, 5, 3, 5, 7,
973 13, 21, 29, 35, 42, 45, 42, 35, 28, 15, 3, -6, -16, -22, -22, -22, -20, -13, -9,
974 -3, 1, 0, -5, -16, -30, -43, -56, -64, -65, -68, -66, -59, -53, -40, -35, -33,
975 -22, -22, -30, -36, -30, -25, -39, -40, -29, -26, -26, -21, -7, 1, 2, -5, -3, 3,
976 -5, -8, -15, -14, -12, -32, -35, -30, -36, -37, -42, -43, -31, -25, -20, -2, 15,
977 21, 28, 32, 41, 51, 44, 45, 52, 50, 51, 52, 56, 63, 66, 69, 72, 74, 69, 58, 49,
978 39, 27, 13, 1, -2, -4, -5, -3, 3, 11, 18, 22, 26, 29, 28, 23, 22, 23, 25, 29,
979 32, 41, 55, 67, 78, 87, 95, 98, 95, 90, 80, 66, 50, 35, 21, 9, -1, -11, -17,
980 -20, -25, -29, -33, -38, -43, -49, -57, -63, -68, -71, -71, -70, -68, -63, -58,
981 -52, -42, -35, -33, -28, -27, -23, -16, -9, -1, 5, 1, 8, 15, 4, 0, 2, -2, -8,
982 -13, -12, -17, -28, -31, -33, -34, -35, -41, -46, -45, -51, -65, -66, -72, -76,
983 -65, -58, -39, -13, 5, 27, 47, 60, 73, 78, 79, 84, 82, 70, 65, 60, 54, 61, 67,
984 70, 76, 72, 61, 55, 43, 25, 6, -14, -35, -52, -67, -75, -73, -67, -55, -38, -24,
985 -7, 3, 9, 18, 22, 23, 26, 29, 35, 43, 53, 65, 82, 98, 112, 120, 121, 115, 102,
986 84, 67, 47, 25, 3, -17, -32, -43, -51, -55, -57, -59, -63, -67, -73, -81, -88,
987 -93, -94, -94, -90, -82, -73, -60, -46, -33, -24, -16, -10, -12, -12, -13, -13,
988 -14, -16, -13, -16, -20, -16, -15, -12, -8, -15, -26, -34, -48, -61, -65, -68,
989 -69, -71, -73, -67, -64, -60, -49, -44, -43, -41, -50, -61, -59, -54, -41, -16,
990 11, 36, 54, 69, 83, 91, 99, 102, 95, 82, 66, 44, 27, 23, 24, 27, 32, 32, 27, 18,
991 9, -1, -14, -28, -47, -68, -85, -95, -96, -84, -62, -38, -12, 13, 31, 42, 54,
992 62, 66, 67, 65, 61, 58, 59, 65, 77, 93, 106, 113, 114, 107, 93, 74, 54, 30, 3,
993 -23, -49, -68, -80, -84, -81, -76, -70, -67, -68, -69, -73, -76, -77, -79, -78,
994 -73, -70, -64, -50, -34, -15, 6, 19, 22, 19, 8, 1, -4, -10, -12, -17, -26, -35,
995 -37, -37, -36, -30, -30, -33, -43, -56, -64, -70, -71, -72, -73, -71, -68, -67,
996 -60, -44, -27, -17, -16, -16, -29, -39, -37, -38, -22, 7, 23, 38, 56, 67, 75,
997 88, 95, 93, 82, 57, 33, 11, 1, 3, 0, 5, 10, 4, 3, 4, -1, -5, -13, -26, -47, -66,
998 -78, -86, -82, -67, -43, -16, 9, 37, 60, 77, 91, 97, 97, 94, 84, 71, 66, 65, 66,
999 78, 90, 99, 103, 100, 95, 85, 71, 52, 26, -1, -28, -52, -67, -71, -71, -68, -61,
1000 -55, -50, -45, -43, -43, -45, -48, -52, -56, -54, -47, -35, -21, -8, 3, 9, 11,
1001 8, 3, -3, -15, -24, -36, -48, -52, -56, -59, -55, -50, -49, -46, -46, -53, -55,
1002 -56, -59, -62, -61, -58, -57, -51, -40, -32, -24, -15, -12, -10, -8, -12, -18,
1003 -21, -27, -36, -37, -27, -12, 11, 35, 47, 56, 62, 61, 60, 59, 52, 40, 25, 11, 6,
1004 6, 12, 23, 30, 35, 36, 28, 22, 17, 5, -10, -25, -41, -52, -53, -39, -16, 1, 19,
1005 34, 42, 49, 54, 54, 54, 49, 39, 36, 41, 45, 55, 72, 89, 101, 106, 106, 102, 93,
1006 80, 63, 44, 26, 7, -9, -14, -14, -14, -11, -8, -9, -12, -18, -27, -35, -41, -47,
1007 -52, -52, -49, -41, -29, -15, -1, 5, 7, 6, 1, -8, -16, -25, -38, -44, -44, -42,
1008 -36, -26, -19, -14, -11, -14, -21, -29, -40, -53, -63, -68, -71, -70, -59, -44,
1009 -32, -21, -8, -1, 1, 1, -8, -19, -26, -37, -44, -44, -43, -43, -40, -30, -16, 3,
1010 23, 42, 54, 53, 52, 46, 39, 40, 35, 27, 22, 18, 17, 26, 41, 50, 57, 56, 47, 38,
1011 26, 15, 4, -10, -21, -31, -37, -31, -21, -6, 11, 25, 34, 41, 47, 49, 50, 49, 46,
1012 46, 47, 52, 59, 68, 80, 89, 94, 97, 93, 85, 74, 62, 47, 34, 21, 9, -1, -7, -10,
1013 -9, -9, -10, -15, -20, -27, -34, -38, -40, -42, -41, -38, -31, -22, -11, 1, 9,
1014 14, 16, 10, 4, -4, -16, -26, -36, -46, -48, -46, -43, -35, -28, -26, -27, -32,
1015 -37, -40, -48, -56, -65, -72, -76, -74, -63, -48, -33, -23, -13, -9, -7, -7,
1016 -12, -17, -26, -37, -46, -52, -50, -47, -45, -43, -43, -34, -19, -3, 17, 29, 30,
1017 28, 28, 29, 33, 37, 36, 32, 30, 29, 35, 43, 51, 55, 49, 41, 30, 18, 10, 1, -10,
1018 -23, -36, -44, -46, -40, -30, -11, 4, 14, 27, 36, 41, 47, 49, 51, 53, 50, 48,
1019 54, 61, 69, 79, 86, 91, 89, 81, 76, 68, 56, 43, 25, 7, -9, -22, -29, -31, -33,
1020 -37, -40, -43, -45, -46, -47, -47, -49, -48, -45, -40, -31, -21, -11, -3, 0, 1,
1021 0, -5, -13, -21, -33, -42, -48, -52, -47, -41, -36, -33, -35, -35, -38, -47,
1022 -53, -62, -72, -78, -81, -79, -67, -55, -45, -27, -9, 1, 9, 16, 16, 9, 2, -6,
1023 -16, -17, -16, -22, -16, -7, -11, -12, -13, -7, 2, 6, 11, 8, 1, -2, 1, 4, 12,
1024 21, 14, 13, 18, 17, 25, 32, 34, 34, 30, 23, 15, 17, 19, 16, 12, 3, -2, -5, -1,
1025 9, 11, 16, 19, 17, 23, 33, 38, 39, 42, 43, 43, 47, 51, 54, 59, 62, 64, 64, 67,
1026 68, 65, 65, 63, 56, 49, 43, 34, 27, 22, 13, 5, 0, -6, -11, -15, -18, -20, -22,
1027 -22, -25, -26, -25, -26, -24, -21, -21, -24, -25, -25, -27, -27, -27, -31, -33,
1028 -34, -36, -40, -42, -44, -47, -46, -44, -43, -41, -36, -34, -31, -27, -28, -33,
1029 -35, -34, -35, -36, -35, -37, -33, -30, -27, -21, -16, -14, -17, -18, -18, -22,
1030 -30, -36, -41, -49, -55, -61, -58, -36, -14, 7, 24, 33, 40, 43, 47, 52, 50, 42,
1031 30, 22, 21, 25, 34, 42, 52, 55, 52, 47, 39, 33, 20, 3, -15, -37, -51, -55, -52,
1032 -42, -29, -14, -1, 14, 29, 38, 44, 44, 39, 36, 35, 35, 40, 48, 60, 72, 83, 91,
1033 97, 97, 94, 87, 74, 59, 41, 23, 9, 0, -7, -11, -13, -15, -16, -17, -20, -23,
1034 -29, -37, -46, -52, -53, -51, -45, -35, -24, -16, -9, -2, 2, 3, -1, -9, -17,
1035 -25, -35, -41, -41, -41, -39, -35, -29, -24, -24, -24, -30, -37, -44, -57, -65,
1036 -64, -65, -62, -52, -41, -29, -16, -7, 0, 6, 0, -6, -11, -21, -25, -30, -32,
1037 -28, -26, -22, -17, -15, -13, -18, -21, -13, -7, 0, 4, 7, 12, 20, 31, 41, 49,
1038 51, 48, 46, 44, 46, 46, 42, 41, 37, 33, 29, 24, 23, 19, 11, 1, -12, -19, -24,
1039 -27, -25, -19, -13, -7, 3, 14, 24, 31, 35, 40, 45, 47, 50, 56, 62, 68, 76, 83,
1040 88, 90, 89, 88, 84, 75, 63, 47, 31, 17, 4, -5, -12, -19, -25, -28, -30, -33,
1041 -34, -36, -40, -44, -47, -49, -47, -40, -33, -25, -17, -9, -4, 3, 7, 7, 4, -4,
1042 -10, -18, -25, -29, -32, -36, -40, -40, -36, -34, -32, -30, -33, -40, -48, -52,
1043 -54, -53, -54, -54, -48, -45, -39, -27, -15, -6, -4, -3, -2, -7, -9, -11, -12,
1044 -16, -19, -22, -27, -24, -24, -30, -24, -18, -10, 5, 12, 14, 21, 24, 26, 31, 35,
1045 34, 31, 27, 28, 33, 36, 41, 46, 43, 42, 37, 29, 27, 21, 8, -2, -14, -24, -26,
1046 -25, -22, -13, -4, 3, 11, 20, 26, 29, 31, 33, 35, 36, 39, 45, 53, 63, 71, 77,
1047 82, 85, 81, 78, 72, 61, 50, 36, 23, 12, 3, -2, -7, -9, -13, -16, -19, -22, -25,
1048 -29, -33, -38, -42, -41, -38, -31, -21, -14, -6, 0, 3, 7, 7, 4, -1, -9, -17,
1049 -23, -30, -34, -37, -40, -40, -41, -43, -41, -41, -41, -40, -40, -43, -46, -45,
1050 -46, -42, -37, -35, -31, -25, -22, -18, -9, -2, -1, 2, 1, -3, -7, -9, -10, -13,
1051 -14, -19, -28, -31, -34, -41, -42, -31, -23, -13, 3, 8, 13, 25, 28, 34, 41, 39,
1052 32, 29, 28, 30, 36, 40, 44, 45, 43, 43, 39, 34, 31, 19, 4, -7, -20, -27, -26,
1053 -23, -15, -7, -1, 7, 16, 24, 29, 32, 32, 31, 30, 32, 39, 46, 54, 63, 69, 74, 77,
1054 76, 74, 70, 60, 48, 36, 22, 12, 5, 0, -2, -5, -8, -10, -12, -14, -16, -19, -24,
1055 -29, -32, -34, -31, -27, -22, -15, -10, -6, -2, -1, -1, -2, -9, -15, -19, -25,
1056 -28, -29, -31, -32, -34, -33, -31, -31, -33, -36, -37, -37, -41, -42, -42, -41,
1057 -42, -35, -30, -29, -22, -16, -14, -8, -7, -8, -11, -13, -15, -17, -18, -19,
1058 -19, -20, -20, -23, -26, -27, -32, -39, -42, -38, -32, -20, -1, 9, 17, 26, 32,
1059 40, 48, 49, 44, 37, 30, 26, 28, 32, 36, 36, 35, 35, 32, 28, 26, 17, 4, -9, -23,
1060 -33, -35, -31, -23, -15, -8, -1, 7, 16, 24, 29, 29, 27, 25, 26, 32, 40, 47, 57,
1061 65, 70, 74, 76, 75, 72, 65, 54, 42, 29, 19, 12, 8, 6, 2, -2, -4, -8, -11, -14,
1062 -18, -25, -31, -35, -37, -35, -29, -25, -18, -11, -6, -1, 3, 3, 0, -5, -12, -21,
1063 -26, -29, -28, -28, -26, -26, -30, -28, -26, -26, -27, -29, -36, -45, -50, -52,
1064 -50, -48, -48, -42, -36, -31, -25, -17, -8, -5, -8, -7, -8, -12, -15, -13, -12,
1065 -13, -16, -18, -18, -19, -22, -24, -29, -39, -44, -40, -32, -18, -4, 2, 11, 19,
1066 25, 33, 39, 39, 33, 28, 22, 20, 24, 27, 33, 37, 35, 35, 31, 30, 28, 18, 8, -5,
1067 -19, -25, -23, -16, -10, -3, 3, 8, 16, 22, 28, 31, 30, 27, 26, 30, 35, 43, 53,
1068 64, 70, 73, 77, 78, 76, 72, 62, 50, 37, 24, 15, 9, 6, 2, -3, -7, -10, -14, -17,
1069 -19, -24, -30, -35, -38, -38, -33, -27, -22, -17, -11, -6, -3, 0, 0, -4, -10,
1070 -17, -21, -24, -26, -27, -28, -28, -29, -30, -31, -30, -29, -33, -37, -40, -44,
1071 -46, -46, -43, -41, -38, -33, -29, -22, -16, -12, -7, -4, -3, -5, -7, -10, -11,
1072 -12, -15, -15, -18, -21, -24, -27, -29, -34, -44, -47, -41, -35, -24, -7, 0, 7,
1073 16, 22, 31, 38, 37, 34, 31, 26, 24, 28, 32, 36, 38, 35, 34, 31, 26, 24, 15, 2,
1074 -12, -26, -32, -32, -27, -19, -12, -5, 2, 11, 19, 27, 31, 30, 30, 29, 32, 41,
1075 49, 60, 70, 77, 81, 85, 86, 84, 79, 69, 55, 41, 27, 18, 10, 6, 3, -2, -5, -7,
1076 -9, -11, -13, -18, -25, -30, -34, -35, -31, -27, -20, -13, -8, -3, 2, 5, 5, 3,
1077 -2, -9, -16, -23, -27, -31, -33, -34, -36, -36, -36, -38, -41, -41, -43, -48,
1078 -50, -51, -50, -48, -44, -35, -30, -27, -21, -15, -10, -8, -4, -3, -4, -4, -6,
1079 -7, -7, -8, -8, -10, -13, -17, -24, -29, -34, -40, -51, -61, -56, -46, -35, -16,
1080 0, 7, 16, 26, 34, 42, 42, 34, 30, 25, 21, 26, 33, 41, 47, 48, 49, 49, 45, 40,
1081 32, 17, 1, -16, -29, -32, -27, -23, -16, -7, 0, 8, 16, 23, 27, 26, 23, 21, 22,
1082 27, 35, 45, 57, 68, 73, 79, 84, 82, 79, 72, 59, 45, 32, 21, 15, 12, 10, 8, 6, 4,
1083 1, -3, -6, -12, -22, -30, -37, -41, -40, -36, -30, -23, -17, -12, -7, -3, -2,
1084 -3, -7, -12, -20, -28, -29, -29, -29, -28, -28, -28, -27, -23, -20, -19, -22,
1085 -30, -35, -39, -40, -40, -39, -38, -37, -34, -30, -23, -18, -13, -10, -13, -15,
1086 -15, -16, -16, -16, -17, -19, -22, -22, -22, -21, -20, -25, -29, -33, -42, -50,
1087 -47, -34, -23, -6, 9, 16, 28, 38, 47, 57, 57, 51, 42, 34, 31, 30, 33, 38, 41,
1088 39, 37, 38, 36, 35, 28, 13, -1, -16, -27, -29, -26, -24, -22, -17, -11, -4, 6,
1089 13, 17, 17, 16, 17, 18, 26, 34, 43, 53, 61, 68, 73, 79, 80, 77, 71, 60, 48, 37,
1090 28, 22, 16, 13, 9, 5, 3, 1, -1, -4, -9, -17, -24, -30, -34, -34, -32, -29, -26,
1091 -22, -16, -11, -7, -5, -7, -11, -15, -19, -21, -22, -24, -25, -24, -23, -21,
1092 -19, -22, -25, -28, -32, -33, -38, -41, -40, -42, -41, -38, -32, -27, -22, -18,
1093 -15, -11, -14, -14, -11, -12, -12, -13, -12, -11, -14, -14, -12, -13, -16, -21,
1094 -25, -31, -37, -48, -56, -58, -52, -42, -27, -4, 12, 22, 37, 47, 54, 57, 56, 51,
1095 44, 38, 34, 38, 45, 49, 54, 56, 57, 56, 51, 45, 34, 19, 4, -11, -21, -25, -25,
1096 -23, -17, -11, -7, 0, 5, 8, 9, 9, 9, 9, 13, 20, 31, 44, 56, 67, 74, 80, 82, 79,
1097 76, 68, 56, 45, 33, 24, 17, 13, 9, 5, 1, -4, -8, -12, -18, -25, -32, -38, -43,
1098 -45, -44, -39, -34, -28, -22, -18, -14, -10, -8, -7, -7, -8, -10, -11, -10, -9,
1099 -8, -9, -10, -12, -16, -19, -23, -27, -32, -35, -36, -36, -35, -33, -30, -25,
1100 -20, -16, -17, -19, -21, -20, -20, -20, -18, -17, -15, -12, -7, -3, -1, 1, -1,
1101 -5, -8, -14, -23, -28, -30, -37, -43, -45, -47, -46, -37, -23, -9, 9, 18, 24,
1102 33, 38, 40, 44, 43, 39, 34, 32, 34, 40, 46, 50, 53, 50, 47, 43, 36, 32, 21, 7,
1103 -5, -15, -21, -21, -18, -15, -11, -7, -4, 2, 6, 10, 12, 13, 14, 17, 22, 31, 41,
1104 52, 60, 67, 70, 72, 71, 67, 63, 54, 43, 33, 22, 16, 11, 7, 4, -2, -6, -10, -15,
1105 -19, -23, -29, -36, -40, -42, -43, -38, -34, -29, -23, -19, -15, -12, -9, -9,
1106 -12, -15, -16, -15, -14, -10, -8, -8, -9, -12, -13, -16, -22, -25, -30, -38,
1107 -42, -41, -41, -42, -38, -35, -33, -30, -25, -19, -16, -13, -12, -12, -11, -10,
1108 -9, -7, -8, -8, -8, -7, -5, -3, -2, -5, -8, -11, -18, -23, -27, -32, -41, -48,
1109 -48, -43, -35, -25, -7, 7, 15, 24, 31, 35, 37, 36, 34, 31, 28, 26, 31, 40, 45,
1110 50, 54, 54, 52, 47, 42, 36, 24, 13, 2, -4, -6, -6, -2, 3, 8, 9, 11, 14, 14, 14,
1111 14, 13, 13, 15, 21, 30, 41, 50, 58, 62, 63, 63, 59, 54, 47, 37, 28, 20, 13, 10,
1112 7, 5, 2, -2, -7, -14, -19, -25, -32, -38, -44, -46, -48, -46, -41, -35, -29,
1113 -21, -17, -13, -10, -9, -11, -13, -15, -15, -11, -9, -7, -3, -2, -5, -4, -2, -5,
1114 -10, -14, -19, -21, -22, -24, -25, -25, -27, -29, -24, -19, -19, -18, -17, -19,
1115 -18, -16, -13, -9, -7, -8, -8, -4, -1, 1, -1, -2, -7, -15, -18, -17, -19, -23,
1116 -25, -25, -29, -30, -27, -24, -23, -25, -23, -22, -22, -13, 0, 10, 17, 23, 29,
1117 34, 40, 45, 49, 48, 42, 40, 37, 35, 38, 40, 39, 38, 36, 33, 32, 31, 26, 21, 14,
1118 6, 1, -3, -2, 1, 2, 5, 8, 11, 15, 21, 26, 31, 35, 35, 36, 39, 41, 45, 47, 47,
1119 45, 42, 39, 36, 32, 26, 18, 10, 2, -6, -12, -16, -21, -26, -31, -35, -38, -39,
1120 -40, -41, -41, -41, -42, -37, -32, -29, -24, -17, -14, -11, -6, 0, 1, 0, 1, 0,
1121 -3, -6, -6, -5, -7, -11, -12, -11, -12, -14, -13, -14, -17, -22, -27, -29, -30,
1122 -33, -33, -29, -29, -29, -24, -20, -17, -14, -12, -12, -12, -12, -16, -15, -11,
1123 -15, -17, -17, -17, -20, -22, -23, -26, -27, -31, -34, -31, -30, -27, -25, -20,
1124 -15, -12, -1, 12, 20, 26, 33, 38, 38, 42, 46, 45, 46, 42, 39, 40, 39, 39, 40,
1125 40, 36, 31, 29, 25, 22, 17, 13, 7, 1, -1, -3, -2, 1, 3, 5, 9, 13, 17, 22, 28,
1126 32, 35, 37, 39, 43, 46, 48, 49, 48, 47, 43, 39, 35, 29, 22, 15, 6, -2, -8, -14,
1127 -19, -23, -27, -32, -35, -37, -39, -40, -40, -40, -39, -38, -34, -29, -24, -18,
1128 -13, -9, -6, -4, -3, -3, -4, -2, -3, -4, -5, -5, -3, -2, -3, -4, -6, -11, -17,
1129 -19, -23, -28, -31, -34, -33, -32, -31, -24, -21, -19, -18, -16, -16, -14, -13,
1130 -15, -12, -10, -12, -6, -1, 1, 2, 2, -2, -7, -10, -14, -18, -20, -22, -25, -26,
1131 -25, -22, -21, -20, -21, -27, -30, -32, -30, -25, -17, -9, -4, 6, 14, 21, 31,
1132 34, 33, 31, 28, 24, 21, 27, 31, 30, 37, 41, 44, 47, 50, 52, 47, 40, 30, 21, 18,
1133 13, 13, 17, 19, 21, 26, 33, 35, 38, 38, 34, 29, 25, 24, 22, 25, 28, 28, 32, 34,
1134 35, 35, 33, 28, 18, 9, 0, -10, -15, -20, -23, -24, -24, -22, -21, -19, -18, -19,
1135 -22, -29, -34, -38, -39, -41, -40, -34, -30, -24, -17, -11, -7, -8, -11, -14,
1136 -17, -19, -20, -20, -22, -22, -18, -16, -11, -10, -12, -13, -17, -21, -24, -24,
1137 -26, -29, -27, -26, -22, -17, -13, -9, -9, -11, -11, -13, -14, -15, -14, -14,
1138 -15, -14, -15, -12, -13, -15, -13, -17, -22, -23, -25, -26, -25, -22, -21, -22,
1139 -22, -21, -16, -13, -7, 0, 4, 7, 10, 15, 20, 23, 25, 26, 27, 26, 26, 27, 28, 31,
1140 31, 32, 34, 34, 36, 37, 37, 36, 31, 28, 25, 23, 21, 21, 23, 23, 25, 27, 30, 33,
1141 35, 36, 34, 32, 32, 30, 29, 29, 29, 29, 28, 27, 26, 25, 23, 18, 14, 7, 0, -5,
1142 -10, -14, -17, -20, -21, -21, -21, -22, -21, -22, -24, -27, -29, -31, -32, -32,
1143 -32, -33, -31, -29, -27, -23, -20, -18, -20, -21, -21, -20, -19, -20, -17, -16,
1144 -16, -15, -14, -11, -12, -13, -13, -14, -16, -17, -16, -15, -16, -15, -15, -15,
1145 -16, -17, -15, -13, -15, -16, -16, -15, -15, -13, -12, -13, -14, -16, -16, -17,
1146 -18, -17, -18, -19, -21, -20, -19, -19, -18, -18, -17, -18, -19, -16, -14, -12,
1147 -8, -4, 2, 5, 10, 16, 20, 22, 23, 25, 25, 24, 25, 28, 32, 33, 36, 40, 41, 42,
1148 44, 44, 43, 39, 36, 33, 30, 28, 27, 27, 26, 28, 27, 26, 27, 25, 24, 22, 19, 17,
1149 16, 15, 16, 18, 19, 19, 21, 21, 19, 18, 15, 11, 6, 1, -3, -7, -10, -12, -13,
1150 -14, -15, -16, -17, -18, -23, -27, -28, -31, -35, -37, -38, -37, -38, -37, -35,
1151 -31, -30, -30, -27, -24, -23, -22, -20, -18, -15, -15, -15, -10, -8, -9, -8, -4,
1152 -3, -6, -8, -7, -10, -13, -13, -14, -16, -19, -18, -16, -15, -15, -14, -13, -17,
1153 -18, -18, -21, -21, -21, -22, -22, -24, -22, -22, -24, -22, -22, -22, -23, -23,
1154 -20, -20, -20, -18, -20, -20, -15, -12, -11, -4, 1, 6, 10, 12, 18, 22, 23, 26,
1155 27, 27, 28, 30, 32, 33, 37, 39, 40, 42, 42, 43, 43, 41, 40, 36, 32, 30, 28, 26,
1156 26, 26, 26, 26, 25, 26, 26, 24, 24, 22, 21, 22, 20, 22, 23, 23, 24, 24, 24, 23,
1157 20, 18, 15, 10, 6, 3, -1, -5, -7, -8, -9, -11, -13, -16, -17, -20, -23, -26,
1158 -29, -32, -34, -37, -37, -36, -37, -36, -34, -32, -30, -27, -25, -22, -21, -20,
1159 -18, -17, -15, -15, -15, -12, -12, -13, -10, -9, -10, -8, -5, -5, -5, -5, -5,
1160 -7, -12, -11, -10, -14, -14, -13, -16, -17, -16, -18, -19, -19, -21, -22, -23,
1161 -25, -25, -26, -25, -24, -27, -27, -26, -29, -30, -29, -27, -24, -24, -19, -12,
1162 -8, -3, 7, 14, 15, 19, 26, 27, 26, 29, 35, 37, 39, 43, 46, 48, 49, 50, 52, 51,
1163 48, 45, 42, 38, 34, 32, 30, 28, 25, 23, 22, 21, 19, 18, 17, 15, 11, 9, 9, 9, 10,
1164 12, 15, 16, 18, 20, 22, 24, 25, 25, 24, 22, 20, 17, 15, 13, 10, 7, 4, 1, -3, -5,
1165 -8, -10, -14, -19, -23, -28, -33, -36, -39, -41, -44, -46, -46, -46, -44, -43,
1166 -41, -40, -38, -37, -36, -31, -26, -23, -20, -17, -13, -12, -12, -8, -4, -4, -3,
1167 -1, 0, -2, -2, 0, 3, 0, -2, -2, -3, -7, -11, -12, -13, -19, -24, -24, -28, -33,
1168 -33, -33, -36, -38, -39, -41, -44, -46, -46, -46, -45, -44, -44, -39, -33, -28,
1169 -20, -11, -2, 4, 10, 17, 22, 25, 31, 35, 37, 39, 42, 46, 50, 54, 57, 61, 63, 62,
1170 61, 60, 58, 53, 48, 44, 39, 34, 29, 27, 24, 22, 20, 17, 14, 10, 7, 6, 5, 3, 2,
1171 2, 2, 3, 5, 8, 10, 12, 13, 15, 15, 15, 15, 15, 14, 13, 12, 11, 9, 9, 8, 6, 4, 1,
1172 -3, -6, -10, -13, -16, -19, -22, -26, -28, -29, -31, -32, -32, -32, -33, -34,
1173 -34, -34, -33, -33, -31, -30, -28, -27, -24, -21, -20, -17, -15, -13, -11, -9,
1174 -10, -9, -6, -7, -7, -5, -4, -6, -6, -4, -4, -7, -7, -7, -10, -12, -14, -15,
1175 -18, -20, -22, -23, -25, -27, -28, -29, -31, -34, -33, -31, -33, -34, -30, -27,
1176 -25, -21, -17, -13, -9, -6, -3, 0, 2, 4, 7, 11, 13, 15, 20, 23, 25, 29, 34, 35,
1177 37, 40, 41, 41, 43, 44, 42, 42, 43, 42, 41, 41, 40, 38, 37, 35, 32, 30, 29, 27,
1178 25, 25, 23, 23, 22, 22, 21, 22, 21, 19, 19, 18, 17, 16, 15, 13, 12, 11, 10, 8,
1179 7, 5, 3, 2, 0, -3, -4, -5, -8, -11, -12, -14, -17, -20, -22, -25, -29, -32, -33,
1180 -35, -37, -38, -38, -38, -39, -40, -38, -37, -38, -37, -36, -36, -36, -35, -33,
1181 -31, -31, -28, -25, -23, -22, -20, -16, -14, -13, -11, -8, -9, -10, -8, -7, -7,
1182 -8, -7, -6, -7, -8, -7, -7, -9, -10, -11, -12, -15, -17, -16, -15, -17, -16,
1183 -10, -7, -8, -5, 1, 2, 2, 3, 6, 6, 6, 8, 11, 14, 17, 21, 25, 29, 31, 34, 37, 39,
1184 38, 40, 41, 41, 40, 40, 41, 42, 42, 42, 42, 40, 38, 35, 32, 31, 27, 24, 23, 22,
1185 22, 23, 23, 24, 24, 24, 23, 21, 19, 18, 16, 16, 14, 13, 13, 13, 12, 13, 13, 12,
1186 10, 7, 4, 1, -2, -5, -8, -11, -13, -15, -17, -19, -20, -22, -26, -30, -33, -36,
1187 -40, -43, -44, -44, -45, -43, -40, -38, -37, -34, -30, -29, -28, -27, -26, -25,
1188 -23, -20, -18, -15, -13, -12, -9, -7, -7, -4, -3, -3, -4, -4, -5, -7, -7, -8,
1189 -9, -12, -16, -19, -24, -27, -31, -36, -39, -41, -41, -39, -35, -30, -24, -13,
1190 -4, 1, 8, 14, 19, 25, 29, 33, 36, 40, 45, 49, 55, 60, 64, 67, 67, 66, 63, 60,
1191 55, 47, 42, 35, 27, 20, 15, 12, 8, 5, 2, -2, -5, -8, -10, -12, -11, -9, -6, -1,
1192 5, 12, 21, 29, 38, 44, 49, 52, 53, 54, 54, 54, 53, 51, 48, 44, 40, 35, 28, 22,
1193 13, 5, -5, -16, -25, -33, -40, -47, -51, -54, -57, -59, -58, -55, -52, -49, -48,
1194 -47, -44, -42, -37, -30, -24, -19, -13, -9, -5, 1, 4, 8, 12, 10, 9, 6, 1, -4,
1195 -9, -14, -18, -25, -31, -36, -39, -41, -41, -42, -42, -42, -44, -44, -44, -42,
1196 -37, -37, -35, -34, -34, -31, -28, -24, -19, -19, -22, -22, -14, -7, 1, 15, 31,
1197 39, 42, 52, 54, 50, 53, 49, 43, 37, 29, 27, 24, 27, 29, 28, 29, 24, 19, 14, 11,
1198 6, 0, -3, -8, -9, -7, -6, 2, 10, 16, 17, 17, 19, 17, 19, 24, 28, 35, 37, 43, 51,
1199 57, 64, 67, 67, 61, 54, 45, 37, 32, 27, 23, 20, 14, 10, 5, 1, -3, -8, -14, -20,
1200 -26, -30, -32, -29, -25, -21, -19, -17, -14, -14, -15, -14, -15, -18, -21, -22,
1201 -23, -21, -18, -16, -14, -17, -20, -23, -27, -30, -32, -34, -37, -37, -37, -36,
1202 -33, -29, -28, -30, -29, -29, -28, -26, -27, -23, -21, -24, -18, -11, -10, -6,
1203 -1, -3, -8, -13, -17, -20, -27, -27, -26, -33, -35, -35, -38, -42, -43, -35,
1204 -30, -26, -14, -1, 14, 27, 40, 54, 55, 56, 58, 55, 54, 51, 50, 50, 47, 47, 46,
1205 44, 41, 36, 32, 22, 12, 1, -8, -16, -19, -18, -21, -18, -14, -11, -4, -1, 4, 9,
1206 11, 16, 22, 28, 36, 45, 55, 62, 68, 72, 72, 70, 66, 60, 52, 43, 34, 27, 20, 14,
1207 9, 3, -4, -9, -16, -21, -25, -28, -29, -30, -29, -27, -23, -21, -16, -10, -8,
1208 -7, -7, -8, -10, -12, -11, -10, -11, -10, -11, -16, -18, -21, -26, -30, -33,
1209 -37, -40, -43, -47, -47, -47, -48, -39, -34, -36, -30, -27, -31, -27, -22, -16,
1210 -14, -11, -2, -3, -1, 6, 2, 1, 1, -8, -16, -18, -22, -26, -25, -26, -28, -36,
1211 -38, -40, -52, -49, -48, -55, -45, -36, -26, -5, 16, 28, 40, 51, 50, 51, 51, 50,
1212 48, 46, 46, 46, 47, 51, 50, 50, 46, 38, 30, 19, 8, 0 };
1213 
1214 #endif /* BLAHBLAH4B_H_ */
#define CONSTTABLE_STORAGE(X)
+
1 #ifndef BLAHBLAH4B_H_
2 #define BLAHBLAH4B_H_
3 
4 #include <Arduino.h>
5 #include "mozzi_pgmspace.h"
6 
7 #define BLAHBLAH4B_NUM_CELLS 22569
8 #define BLAHBLAH4B_SAMPLERATE 16384
9 
10 CONSTTABLE_STORAGE(int8_t) BLAHBLAH4B_DATA [] = { -1, 2, 6, 9, 12, 15, 17, 20, 22, 25, 28, 30,
11 32, 34, 37, 38, 40, 42, 44, 46, 47, 49, 50, 52, 53, 53, 54, 55, 55, 55, 54, 54,
12 53, 51, 48, 46, 42, 38, 34, 29, 25, 20, 15, 10, 5, -1, -6, -11, -16, -21, -25,
13 -29, -33, -37, -40, -43, -47, -50, -52, -55, -57, -58, -59, -59, -59, -59, -58,
14 -57, -56, -55, -54, -53, -51, -50, -48, -45, -42, -39, -35, -32, -27, -23, -18,
15 -14, -9, -5, -1, 3, 7, 10, 13, 16, 19, 22, 25, 28, 30, 33, 36, 38, 40, 43, 45,
16 47, 49, 51, 53, 54, 56, 57, 57, 58, 58, 58, 58, 58, 57, 56, 55, 52, 49, 46, 41,
17 37, 33, 28, 23, 17, 12, 7, 1, -5, -10, -15, -20, -25, -30, -34, -38, -42, -46,
18 -49, -52, -55, -57, -59, -61, -62, -63, -62, -62, -61, -60, -59, -58, -57, -56,
19 -54, -52, -51, -48, -45, -42, -38, -34, -31, -26, -22, -18, -13, -9, -5, -1, 3,
20 6, 9, 12, 15, 18, 21, 24, 27, 29, 32, 34, 37, 39, 41, 43, 45, 47, 49, 51, 53,
21 55, 56, 57, 59, 59, 59, 59, 58, 58, 57, 55, 53, 50, 47, 43, 38, 34, 29, 24, 19,
22 15, 9, 4, -2, -8, -13, -18, -24, -28, -32, -37, -40, -44, -47, -50, -54, -56,
23 -59, -61, -62, -64, -64, -64, -63, -62, -61, -60, -58, -58, -57, -55, -53, -50,
24 -48, -45, -42, -39, -35, -31, -27, -22, -22, -17, -8, -2, 4, 8, 12, 14, 17, 21,
25 23, 25, 28, 30, 32, 36, 39, 42, 44, 45, 46, 48, 50, 51, 53, 54, 56, 58, 58, 60,
26 60, 59, 59, 57, 55, 53, 51, 49, 46, 42, 39, 35, 29, 24, 19, 13, 8, 2, -4, -10,
27 -15, -20, -27, -31, -33, -39, -41, -45, -49, -50, -55, -56, -59, -61, -62, -64,
28 -64, -63, -62, -61, -59, -58, -54, -52, -50, -47, -44, -42, -42, -41, -39, -37,
29 -35, -34, -33, -30, -23, -15, -8, -2, 4, 6, 8, 11, 13, 16, 22, 26, 27, 27, 27,
30 28, 29, 29, 30, 33, 36, 40, 44, 47, 49, 49, 48, 48, 47, 46, 47, 48, 51, 53, 55,
31 56, 57, 56, 53, 49, 43, 39, 34, 30, 26, 22, 19, 17, 14, 9, 3, -2, -8, -14, -22,
32 -28, -32, -36, -38, -39, -41, -41, -43, -46, -49, -52, -55, -58, -60, -61, -59,
33 -58, -57, -55, -52, -50, -51, -51, -50, -49, -48, -47, -46, -42, -37, -34, -29,
34 -24, -20, -16, -12, -10, -7, -3, 0, 3, 6, 10, 14, 17, 20, 23, 26, 28, 29, 31,
35 33, 35, 36, 39, 42, 44, 47, 48, 50, 52, 53, 53, 54, 54, 55, 56, 56, 56, 56, 56,
36 54, 51, 47, 42, 37, 33, 29, 24, 19, 15, 10, 6, 0, -5, -10, -15, -21, -27, -33,
37 -37, -40, -42, -45, -48, -48, -50, -53, -55, -56, -57, -59, -60, -60, -58, -57,
38 -56, -55, -53, -52, -54, -53, -49, -48, -46, -48, -48, -48, -52, -43, -28, -21,
39 -14, -17, -20, -9, 0, 7, 14, 14, 13, 15, 21, 29, 34, 33, 32, 32, 32, 37, 44, 46,
40 46, 46, 45, 46, 49, 55, 56, 55, 55, 51, 49, 52, 54, 57, 58, 56, 55, 54, 52, 50,
41 48, 44, 35, 28, 23, 17, 13, 10, 5, -2, -11, -20, -26, -27, -33, -41, -44, -51,
42 -59, -62, -64, -65, -65, -66, -68, -70, -68, -67, -66, -63, -65, -59, -54, -57,
43 -52, -41, -38, -41, -43, -38, -32, -32, -31, -27, -23, -20, -23, -24, -12, -3,
44 0, 7, 11, 11, 14, 13, 17, 22, 16, 15, 20, 23, 28, 34, 38, 43, 40, 37, 37, 38,
45 44, 47, 47, 48, 47, 48, 51, 53, 57, 56, 54, 55, 56, 55, 55, 54, 54, 50, 43, 40,
46 39, 36, 32, 26, 16, 7, 0, -7, -14, -19, -23, -29, -38, -47, -52, -60, -65, -72,
47 -80, -84, -86, -87, -85, -86, -83, -84, -86, -82, -79, -73, -64, -57, -41, -30,
48 -32, -27, -15, -5, -6, -10, 0, 12, 16, 15, 19, 30, 33, 28, 29, 31, 31, 31, 21,
49 17, 17, 15, 18, 19, 22, 20, 17, 19, 19, 17, 14, 8, 8, 11, 11, 10, 8, 15, 21, 16,
50 10, 15, 24, 23, 18, 24, 30, 29, 30, 35, 37, 36, 37, 38, 40, 40, 37, 40, 43, 40,
51 34, 30, 27, 26, 19, 13, 9, 4, -1, -9, -15, -18, -28, -34, -37, -48, -54, -58,
52 -61, -60, -67, -71, -72, -72, -70, -77, -76, -70, -69, -68, -66, -60, -52, -42,
53 -33, -35, -32, -20, -14, -14, -15, -6, 6, 8, 7, 13, 22, 28, 26, 29, 36, 32, 32,
54 37, 40, 41, 39, 42, 48, 46, 42, 36, 33, 34, 30, 26, 23, 22, 26, 25, 19, 14, 16,
55 21, 13, 9, 16, 19, 16, 13, 18, 21, 14, 17, 21, 20, 20, 21, 27, 31, 26, 26, 26,
56 25, 24, 20, 18, 16, 14, 11, 5, 3, 0, -7, -10, -16, -20, -28, -33, -33, -39, -43,
57 -50, -53, -51, -58, -61, -60, -61, -61, -62, -63, -60, -60, -58, -53, -53, -52,
58 -48, -37, -25, -25, -24, -11, -1, -1, -3, 2, 13, 17, 18, 19, 24, 33, 36, 37, 38,
59 38, 37, 38, 39, 39, 39, 41, 41, 39, 38, 33, 29, 28, 25, 23, 18, 16, 18, 18, 14,
60 8, 4, 9, 14, 6, 1, 10, 18, 14, 8, 11, 16, 15, 15, 18, 19, 21, 25, 28, 31, 28,
61 23, 25, 28, 23, 15, 12, 19, 20, 10, 3, 1, -2, -7, -16, -22, -27, -30, -31, -37,
62 -46, -51, -52, -53, -57, -63, -66, -64, -62, -63, -65, -65, -61, -57, -56, -57,
63 -54, -51, -46, -40, -35, -24, -17, -15, -5, 4, 7, 2, 5, 20, 27, 24, 25, 31, 43,
64 46, 39, 39, 44, 44, 41, 38, 40, 42, 42, 43, 39, 35, 31, 26, 24, 23, 18, 14, 12,
65 13, 13, 8, 2, 4, 11, 8, -2, 1, 10, 10, 6, 6, 11, 11, 10, 12, 14, 17, 18, 20, 26,
66 26, 21, 20, 24, 24, 15, 10, 13, 15, 9, 3, 3, 0, -7, -13, -18, -21, -29, -34,
67 -32, -37, -46, -49, -49, -50, -56, -59, -59, -61, -59, -58, -59, -57, -54, -51,
68 -50, -49, -47, -42, -38, -36, -34, -24, -10, -11, -9, 3, 12, 13, 7, 14, 28, 30,
69 29, 30, 39, 48, 44, 44, 50, 49, 45, 43, 43, 44, 41, 39, 41, 38, 35, 29, 23, 23,
70 20, 14, 8, 4, 4, 6, 1, -2, 0, 5, 1, -5, -2, 2, 2, 1, 4, 8, 8, 8, 13, 16, 18, 17,
71 20, 26, 25, 21, 21, 23, 22, 17, 13, 14, 12, 9, 6, 3, -1, -8, -13, -14, -20, -29,
72 -32, -30, -36, -47, -45, -46, -51, -52, -55, -54, -55, -56, -53, -54, -52, -49,
73 -49, -44, -43, -42, -35, -34, -32, -27, -25, -15, -1, -3, -3, 8, 18, 17, 10, 18,
74 30, 30, 31, 29, 35, 45, 42, 40, 44, 43, 39, 37, 38, 38, 33, 34, 33, 30, 29, 22,
75 17, 17, 15, 11, 4, 0, 1, 4, 3, -4, -4, 5, 4, -4, -3, 4, 6, 5, 5, 11, 13, 13, 16,
76 19, 22, 19, 19, 27, 26, 20, 18, 21, 22, 16, 11, 8, 8, 7, -1, -6, -9, -16, -19,
77 -21, -27, -36, -38, -35, -43, -50, -47, -50, -53, -51, -52, -54, -54, -51, -47,
78 -48, -48, -44, -41, -36, -36, -36, -29, -27, -23, -19, -19, -13, 1, 8, 2, 4, 16,
79 22, 17, 15, 24, 32, 32, 28, 30, 38, 39, 34, 36, 41, 35, 29, 31, 32, 30, 25, 22,
80 23, 22, 18, 12, 10, 11, 8, 3, -1, -4, -2, 3, 0, -2, 3, 6, 3, 2, 6, 8, 7, 8, 13,
81 17, 17, 16, 22, 25, 23, 19, 21, 24, 19, 15, 16, 17, 12, 6, 5, 5, 0, -10, -11,
82 -9, -17, -26, -29, -28, -32, -40, -41, -41, -45, -46, -47, -50, -50, -50, -49,
83 -48, -49, -45, -42, -41, -37, -36, -34, -32, -30, -25, -22, -20, -17, -14, -5,
84 9, 6, 0, 11, 21, 22, 12, 13, 28, 32, 28, 24, 26, 35, 34, 30, 33, 34, 30, 29, 30,
85 29, 25, 21, 23, 22, 20, 16, 10, 13, 14, 9, 3, -3, -2, 3, 2, -4, -4, 7, 9, 0, -1,
86 5, 7, 4, 5, 10, 13, 13, 14, 18, 21, 18, 15, 21, 24, 16, 13, 14, 18, 14, 6, 3, 6,
87 5, -6, -7, -4, -14, -20, -17, -21, -31, -35, -29, -33, -39, -37, -40, -43, -39,
88 -43, -46, -42, -42, -41, -36, -36, -35, -32, -28, -29, -31, -25, -22, -23, -18,
89 -16, -16, -4, 6, -1, -2, 8, 13, 11, 6, 10, 20, 22, 19, 14, 20, 27, 22, 21, 28,
90 26, 22, 25, 24, 22, 21, 16, 16, 17, 15, 11, 9, 12, 11, 7, 2, -2, -1, 4, 3, -2,
91 3, 9, 8, 6, 4, 8, 12, 11, 9, 14, 19, 18, 19, 24, 26, 22, 22, 28, 27, 21, 19, 21,
92 22, 17, 9, 9, 11, 5, -3, -2, -2, -11, -18, -15, -20, -32, -32, -30, -35, -38,
93 -38, -40, -42, -42, -43, -46, -44, -41, -41, -38, -37, -37, -33, -31, -31, -30,
94 -27, -25, -25, -20, -19, -20, -16, -3, 2, -6, -4, 5, 12, 7, 0, 9, 19, 18, 13,
95 11, 19, 22, 19, 20, 23, 22, 22, 23, 22, 23, 18, 16, 18, 16, 15, 12, 11, 14, 13,
96 11, 5, 2, 5, 9, 7, 8, 12, 13, 14, 14, 13, 14, 15, 19, 21, 23, 24, 23, 28, 31,
97 30, 27, 29, 32, 29, 24, 23, 24, 20, 14, 11, 8, 6, 1, 0, -2, -8, -13, -20, -21,
98 -28, -33, -33, -38, -37, -41, -45, -44, -48, -47, -48, -50, -50, -49, -46, -45,
99 -45, -41, -37, -38, -37, -35, -34, -29, -29, -27, -24, -25, -20, -6, -1, -10,
100 -7, 7, 12, 3, -2, 12, 22, 18, 14, 13, 23, 29, 23, 26, 31, 28, 28, 30, 29, 28,
101 26, 27, 27, 23, 24, 22, 21, 23, 21, 17, 13, 8, 11, 15, 12, 12, 20, 19, 16, 17,
102 19, 18, 16, 21, 23, 20, 23, 24, 25, 29, 27, 24, 26, 28, 22, 18, 18, 18, 15, 8,
103 3, 5, 4, -6, -8, -7, -13, -24, -28, -25, -36, -44, -39, -42, -44, -49, -51, -49,
104 -52, -56, -56, -57, -57, -54, -52, -50, -49, -46, -40, -43, -42, -35, -34, -32,
105 -30, -28, -24, -22, -22, -19, -3, 6, -3, -4, 10, 18, 10, 4, 15, 26, 29, 24, 22,
106 31, 39, 36, 32, 37, 36, 35, 39, 37, 36, 37, 37, 36, 32, 31, 29, 25, 25, 24, 18,
107 14, 9, 8, 14, 12, 9, 11, 11, 11, 10, 6, 5, 6, 11, 11, 8, 10, 14, 16, 19, 18, 14,
108 16, 20, 16, 11, 10, 12, 12, 6, 2, 1, -1, -6, -9, -12, -19, -24, -28, -31, -35,
109 -40, -41, -44, -45, -47, -53, -51, -52, -54, -53, -55, -56, -53, -48, -45, -44,
110 -41, -38, -35, -32, -30, -29, -24, -18, -18, -16, -12, -10, -7, -4, 1, 13, 14,
111 9, 14, 24, 29, 21, 20, 33, 39, 37, 33, 32, 41, 47, 40, 38, 40, 41, 43, 39, 36,
112 35, 33, 34, 28, 21, 23, 20, 16, 14, 8, 3, 0, -5, -6, -3, -3, -4, -7, -5, 0, -6,
113 -10, -7, -1, 2, -2, -1, 6, 11, 11, 12, 14, 16, 17, 19, 15, 12, 14, 16, 13, 9, 8,
114 7, 5, 2, -4, -8, -11, -19, -21, -22, -29, -33, -31, -32, -37, -41, -41, -44,
115 -45, -43, -47, -48, -43, -41, -41, -38, -35, -33, -31, -27, -25, -25, -19, -16,
116 -15, -11, -9, -7, -3, 0, 1, 1, 1, 9, 21, 17, 11, 19, 29, 30, 20, 21, 33, 36, 33,
117 28, 27, 33, 34, 29, 31, 31, 27, 27, 24, 20, 17, 13, 14, 10, 4, 4, 1, -3, -4, -8,
118 -11, -14, -17, -12, -7, -10, -12, -8, -4, -5, -8, -4, 3, 7, 9, 10, 13, 19, 24,
119 26, 29, 30, 31, 33, 32, 27, 26, 26, 27, 26, 20, 16, 17, 13, 6, 1, -4, -8, -14,
120 -20, -19, -26, -32, -29, -34, -38, -41, -45, -44, -46, -48, -48, -49, -46, -41,
121 -42, -41, -37, -35, -31, -31, -31, -25, -23, -22, -18, -16, -13, -12, -10, -6,
122 -6, -5, -6, 2, 13, 9, 6, 13, 22, 22, 13, 15, 23, 25, 25, 20, 18, 26, 28, 25, 26,
123 23, 22, 23, 18, 14, 11, 11, 14, 8, 4, 6, 2, 0, -2, -4, -2, -5, -9, -2, 4, 1, -1,
124 3, 10, 10, 7, 10, 14, 20, 23, 22, 25, 32, 37, 37, 37, 40, 40, 39, 36, 32, 31,
125 29, 27, 26, 23, 17, 13, 11, 5, -4, -8, -11, -20, -24, -25, -32, -38, -36, -38,
126 -47, -50, -49, -52, -55, -56, -57, -56, -54, -53, -52, -47, -45, -43, -39, -39,
127 -38, -33, -30, -27, -24, -18, -14, -14, -10, -8, -5, -2, -2, -1, 9, 17, 11, 13,
128 23, 29, 27, 20, 24, 30, 32, 30, 24, 28, 35, 34, 30, 30, 30, 29, 27, 21, 17, 17,
129 18, 16, 10, 10, 10, 7, 7, 3, 3, 5, 3, 3, 5, 7, 7, 7, 11, 13, 13, 14, 16, 19, 24,
130 25, 24, 30, 33, 35, 35, 35, 36, 34, 32, 27, 23, 23, 21, 17, 11, 8, 6, -2, -7,
131 -13, -17, -20, -27, -35, -38, -39, -45, -50, -50, -50, -57, -63, -58, -59, -64,
132 -61, -60, -56, -55, -54, -49, -47, -43, -40, -38, -34, -30, -26, -20, -16, -14,
133 -9, -5, -3, 1, 2, 6, 8, 8, 20, 25, 24, 26, 32, 39, 36, 29, 33, 39, 39, 36, 33,
134 36, 41, 38, 36, 35, 32, 31, 28, 23, 21, 17, 19, 19, 13, 10, 8, 6, 4, -1, -4, -6,
135 -9, -7, -5, -7, -6, -4, -2, 0, -3, -2, 0, 4, 7, 6, 8, 14, 18, 21, 22, 23, 25,
136 24, 22, 22, 20, 18, 17, 18, 17, 10, 8, 9, 4, -3, -8, -9, -14, -20, -24, -27,
137 -30, -33, -35, -37, -41, -44, -44, -46, -51, -50, -47, -46, -45, -44, -40, -39,
138 -37, -34, -32, -29, -27, -22, -17, -15, -12, -7, -3, 0, 0, 2, 5, 7, 7, 7, 9, 13,
139 16, 21, 22, 22, 25, 27, 26, 23, 23, 25, 26, 25, 23, 23, 25, 25, 23, 22, 21, 18,
140 16, 14, 11, 10, 9, 8, 5, 1, -2, -5, -7, -9, -12, -12, -10, -11, -11, -8, -6, -6,
141 -6, -3, -1, -1, 2, 5, 9, 13, 16, 21, 26, 29, 32, 34, 37, 38, 38, 39, 38, 37, 38,
142 36, 33, 31, 26, 24, 19, 13, 8, 3, 0, -9, -14, -16, -23, -28, -32, -35, -39, -44,
143 -46, -49, -51, -52, -53, -54, -54, -51, -51, -49, -46, -44, -38, -38, -36, -28,
144 -27, -24, -18, -15, -13, -10, -5, -1, -1, 2, 5, 5, 6, 7, 7, 8, 8, 7, 12, 13, 12,
145 12, 15, 17, 14, 9, 12, 11, 9, 8, 5, 6, 8, 7, 6, 5, 4, 5, 4, 1, 0, -2, 2, 4, 1,
146 5, 9, 10, 13, 13, 17, 22, 22, 24, 28, 30, 32, 32, 37, 42, 41, 43, 47, 49, 51,
147 51, 50, 52, 51, 49, 44, 40, 37, 32, 25, 20, 13, 8, 2, -6, -9, -17, -27, -29,
148 -32, -40, -50, -52, -54, -61, -65, -67, -71, -71, -67, -71, -73, -69, -66, -62,
149 -63, -58, -54, -51, -43, -42, -34, -27, -26, -18, -11, -8, -5, 0, 6, 8, 9, 9,
150 13, 14, 16, 14, 16, 26, 27, 24, 28, 30, 30, 27, 23, 23, 22, 21, 18, 14, 15, 18,
151 16, 15, 14, 10, 11, 10, 4, 2, 3, 5, 1, -1, 2, 2, 2, 2, 2, 4, 4, 4, 8, 13, 14,
152 17, 21, 25, 27, 28, 32, 34, 37, 39, 39, 41, 46, 47, 47, 48, 49, 48, 45, 42, 38,
153 31, 28, 22, 15, 9, 2, 0, -5, -15, -19, -22, -30, -37, -42, -47, -54, -61, -59,
154 -64, -70, -67, -69, -68, -69, -70, -64, -64, -62, -56, -55, -49, -45, -41, -31,
155 -30, -24, -14, -13, -6, -1, 1, 7, 9, 14, 16, 16, 21, 20, 20, 23, 20, 21, 26, 26,
156 24, 26, 28, 28, 24, 23, 22, 18, 19, 17, 12, 14, 14, 13, 14, 13, 11, 11, 10, 8,
157 5, 4, 4, 1, -1, 1, -3, -3, -3, -3, -2, -1, 3, 4, 5, 11, 13, 14, 16, 19, 23, 25,
158 27, 30, 34, 38, 40, 42, 47, 48, 48, 50, 50, 47, 45, 42, 38, 33, 28, 23, 17, 12,
159 6, -2, -8, -14, -21, -28, -34, -42, -47, -51, -58, -64, -64, -65, -71, -71, -68,
160 -70, -71, -67, -66, -64, -58, -57, -52, -45, -39, -36, -30, -20, -17, -13, -5,
161 -2, 2, 6, 9, 12, 15, 19, 19, 20, 24, 24, 21, 22, 20, 16, 16, 13, 13, 12, 10, 11,
162 10, 11, 8, 4, 4, 3, -2, -5, -5, -6, -6, -5, -5, -4, -2, 0, 0, -1, 4, 5, 6, 9,
163 11, 15, 19, 21, 26, 31, 36, 39, 40, 43, 46, 46, 47, 46, 48, 51, 50, 49, 51, 52,
164 52, 48, 46, 44, 38, 32, 26, 19, 12, 4, -4, -8, -16, -26, -28, -34, -42, -48,
165 -50, -57, -63, -65, -69, -71, -73, -76, -75, -71, -69, -76, -68, -60, -62, -61,
166 -52, -44, -43, -35, -27, -24, -18, -11, -5, 0, 5, 7, 12, 18, 18, 20, 23, 25, 23,
167 22, 22, 19, 17, 15, 12, 14, 16, 12, 9, 13, 15, 9, 3, 3, 2, -1, -5, -9, -9, -5,
168 -4, -5, -3, -1, 1, 2, 2, -2, -3, 1, 2, -1, -1, 3, 8, 14, 18, 21, 31, 38, 38, 39,
169 44, 46, 42, 44, 48, 48, 49, 53, 55, 59, 61, 59, 59, 60, 57, 51, 45, 42, 36, 29,
170 21, 11, 6, 1, -8, -16, -19, -25, -38, -47, -47, -55, -65, -67, -68, -73, -76,
171 -76, -77, -78, -77, -73, -71, -71, -68, -62, -57, -52, -49, -40, -32, -29, -20,
172 -12, -8, -3, 6, 13, 13, 16, 20, 24, 25, 26, 27, 29, 29, 29, 27, 25, 22, 19, 20,
173 20, 14, 13, 16, 16, 12, 9, 9, 9, 7, 5, 2, 0, 2, 3, 4, 4, 4, 6, 9, 9, 8, 8, 10,
174 10, 8, 8, 6, 5, 7, 8, 8, 8, 10, 15, 16, 16, 18, 20, 21, 20, 21, 22, 22, 24, 28,
175 29, 30, 33, 36, 38, 38, 38, 39, 37, 35, 33, 30, 25, 22, 20, 15, 11, 6, 3, -1,
176 -8, -14, -21, -27, -33, -40, -43, -50, -52, -53, -55, -57, -62, -59, -57, -62,
177 -61, -59, -58, -58, -52, -48, -46, -40, -31, -26, -24, -18, -13, -10, -5, -4, 1,
178 3, 5, 9, 11, 14, 15, 17, 18, 17, 14, 12, 9, 4, 2, 0, -1, -1, -3, 0, 3, 5, 3, 0,
179 2, 2, -2, -4, -5, -4, 0, 2, 3, 7, 12, 17, 18, 17, 19, 22, 25, 24, 23, 29, 35,
180 37, 40, 45, 50, 54, 54, 53, 53, 53, 50, 47, 47, 46, 45, 45, 46, 46, 46, 44, 40,
181 37, 32, 25, 17, 10, 2, -5, -12, -19, -22, -28, -34, -36, -43, -49, -52, -58,
182 -62, -68, -71, -70, -74, -75, -72, -69, -67, -67, -60, -56, -55, -51, -46, -39,
183 -36, -34, -25, -19, -15, -9, -2, 5, 10, 14, 17, 19, 19, 23, 23, 20, 21, 19, 18,
184 13, 8, 9, 4, 5, 8, 5, 5, 6, 6, 6, 2, -1, -1, -3, -5, -8, -10, -4, -2, -1, 5, 8,
185 10, 12, 13, 13, 10, 11, 12, 10, 11, 12, 13, 18, 24, 27, 29, 35, 42, 41, 39, 42,
186 43, 41, 40, 39, 42, 43, 44, 46, 48, 50, 50, 49, 48, 46, 41, 39, 33, 28, 23, 15,
187 7, 0, -3, -10, -22, -25, -28, -37, -45, -51, -53, -58, -64, -67, -70, -71, -74,
188 -74, -73, -73, -72, -69, -64, -62, -59, -52, -47, -42, -35, -28, -24, -19, -8,
189 -4, -3, 5, 11, 14, 17, 20, 25, 25, 27, 29, 26, 26, 25, 20, 18, 16, 11, 8, 10,
190 10, 8, 8, 10, 8, 5, 5, 3, -1, 0, -2, -4, -3, -2, 1, 4, 7, 9, 10, 13, 12, 10, 10,
191 8, 6, 6, 5, 4, 5, 8, 9, 9, 12, 14, 15, 17, 17, 16, 19, 19, 19, 21, 24, 27, 29,
192 33, 36, 37, 40, 42, 42, 43, 43, 43, 42, 40, 38, 34, 31, 26, 21, 16, 11, 3, -3,
193 -8, -16, -22, -29, -36, -40, -47, -51, -56, -59, -63, -68, -67, -69, -70, -68,
194 -67, -65, -63, -58, -55, -52, -45, -41, -35, -29, -25, -19, -12, -7, -3, 1, 7,
195 9, 10, 13, 15, 14, 16, 18, 15, 14, 13, 9, 6, 1, -2, -2, -1, -2, -4, 0, 2, 0, 0,
196 1, 0, -2, -3, -4, -5, -3, 0, 2, 6, 10, 13, 16, 19, 19, 21, 27, 26, 24, 28, 33,
197 35, 36, 42, 46, 49, 51, 50, 49, 51, 49, 46, 45, 45, 43, 42, 43, 43, 43, 44, 42,
198 38, 36, 32, 25, 21, 17, 9, 2, -4, -10, -17, -22, -26, -33, -35, -39, -48, -51,
199 -53, -57, -61, -63, -64, -67, -66, -65, -68, -62, -59, -56, -56, -53, -45, -44,
200 -40, -34, -28, -22, -20, -14, -6, -3, -1, 4, 11, 12, 13, 13, 16, 18, 18, 17, 13,
201 15, 14, 6, 2, 1, -2, -6, -7, -6, -7, -6, -4, -4, -3, -2, -4, -4, -3, -4, -5, -3,
202 1, 3, 7, 12, 14, 19, 23, 24, 25, 25, 25, 23, 23, 21, 19, 19, 22, 22, 20, 25, 31,
203 32, 33, 35, 38, 35, 32, 32, 30, 30, 29, 28, 30, 34, 36, 38, 40, 42, 42, 41, 39,
204 35, 31, 27, 20, 13, 9, 3, -4, -8, -13, -19, -24, -29, -37, -42, -48, -55, -60,
205 -65, -68, -70, -72, -74, -71, -69, -68, -67, -63, -59, -59, -55, -48, -46, -42,
206 -32, -28, -23, -14, -8, -3, 4, 8, 9, 13, 16, 15, 16, 20, 20, 16, 18, 19, 12, 10,
207 7, 2, -1, -1, -2, -2, 0, 1, 2, 5, 6, 4, 5, 8, 6, 4, 7, 10, 12, 18, 22, 24, 30,
208 36, 37, 38, 40, 39, 37, 37, 35, 31, 30, 31, 29, 27, 27, 24, 21, 20, 16, 12, 9,
209 6, 3, 1, 1, -1, -1, 3, 5, 4, 6, 8, 9, 10, 10, 12, 12, 13, 14, 12, 12, 10, 8, 8,
210 6, 1, 0, -2, -7, -10, -13, -17, -22, -25, -29, -34, -37, -41, -46, -44, -49,
211 -51, -48, -49, -48, -48, -45, -41, -40, -35, -33, -30, -24, -23, -20, -14, -10,
212 -7, -4, 2, 6, 6, 11, 10, 9, 13, 8, 4, 4, 1, -5, -7, -11, -14, -17, -19, -16,
213 -17, -15, -11, -10, -5, -5, -7, -2, 0, -1, 0, 4, 8, 11, 17, 23, 28, 35, 40, 43,
214 46, 47, 47, 47, 46, 44, 42, 42, 42, 40, 42, 42, 40, 39, 36, 33, 28, 21, 19, 13,
215 9, 7, 4, 4, 6, 6, 8, 9, 10, 11, 10, 9, 7, 4, 2, -1, -6, -9, -12, -13, -12, -17,
216 -20, -20, -19, -24, -30, -30, -31, -38, -40, -43, -47, -46, -45, -46, -48, -43,
217 -41, -45, -41, -40, -38, -37, -36, -30, -28, -23, -21, -17, -7, -6, -3, 1, 2, 2,
218 5, 4, 1, 2, 2, 0, -2, 0, -2, -7, -6, -5, -12, -15, -16, -17, -16, -14, -14, -14,
219 -7, -3, -3, -2, 1, 3, 4, 6, 5, 5, 10, 14, 17, 19, 22, 26, 30, 32, 30, 29, 29,
220 28, 24, 21, 24, 24, 27, 36, 37, 40, 46, 48, 48, 46, 46, 42, 37, 37, 34, 32, 35,
221 37, 40, 45, 47, 46, 46, 45, 38, 30, 23, 12, 1, -7, -15, -24, -28, -31, -35, -40,
222 -43, -47, -53, -57, -64, -71, -73, -77, -81, -78, -74, -74, -70, -61, -55, -54,
223 -47, -40, -39, -34, -29, -26, -21, -14, -8, -2, 5, 11, 15, 21, 24, 21, 23, 20,
224 14, 12, 11, 6, -1, -2, -2, -7, -10, -12, -12, -10, -8, -9, -11, -7, -4, -4, -2,
225 -1, 3, 9, 14, 15, 19, 28, 34, 38, 40, 44, 47, 49, 50, 48, 47, 47, 45, 43, 38,
226 35, 32, 29, 25, 20, 15, 11, 5, 1, -2, -6, -10, -11, -11, -11, -12, -11, -8, -4,
227 -2, 1, 2, 7, 11, 13, 17, 20, 22, 26, 27, 26, 24, 23, 22, 19, 15, 11, 5, 2, -2,
228 -7, -11, -17, -20, -25, -32, -38, -43, -45, -51, -55, -55, -57, -59, -56, -53,
229 -53, -50, -43, -42, -39, -33, -30, -27, -22, -17, -12, -7, -3, 1, 7, 11, 12, 12,
230 15, 15, 11, 8, 4, 2, -2, -8, -12, -14, -17, -21, -21, -17, -18, -18, -13, -8,
231 -9, -8, -4, -3, 0, 1, 2, 6, 13, 17, 22, 30, 37, 42, 48, 52, 52, 52, 53, 52, 49,
232 46, 44, 43, 42, 40, 38, 37, 35, 31, 27, 24, 18, 12, 7, 3, -2, -5, -5, -5, -4, 0,
233 1, 3, 7, 9, 9, 9, 9, 7, 6, 4, 1, -3, -5, -6, -8, -9, -10, -11, -14, -16, -16,
234 -21, -24, -28, -32, -34, -39, -45, -45, -44, -47, -48, -46, -46, -42, -37, -36,
235 -36, -30, -22, -23, -25, -16, -9, -11, -11, -2, 1, 0, 3, 7, 8, 8, 9, 6, 4, 4,
236 -3, -7, -7, -11, -16, -17, -18, -22, -21, -16, -12, -11, -9, -4, -3, -1, -1, -2,
237 2, 4, 4, 4, 6, 12, 18, 21, 25, 28, 31, 33, 31, 29, 28, 25, 22, 21, 16, 15, 20,
238 25, 27, 30, 38, 42, 40, 39, 41, 38, 34, 31, 28, 28, 28, 28, 33, 39, 43, 46, 48,
239 48, 45, 40, 35, 25, 14, 5, -7, -18, -23, -29, -34, -37, -40, -44, -47, -51, -55,
240 -60, -65, -70, -74, -76, -76, -77, -72, -65, -61, -53, -46, -38, -31, -26, -21,
241 -16, -10, -9, -5, 2, 3, 9, 15, 19, 22, 25, 27, 25, 23, 19, 13, 9, 3, -5, -13,
242 -17, -18, -23, -26, -25, -26, -23, -19, -18, -16, -11, -7, -6, -3, -1, 3, 9, 14,
243 18, 22, 31, 37, 41, 45, 48, 48, 47, 46, 42, 37, 32, 27, 23, 18, 13, 8, 6, 5, 0,
244 -4, -6, -8, -10, -12, -13, -13, -12, -8, -4, -1, 4, 11, 18, 25, 30, 34, 41, 45,
245 48, 50, 51, 52, 53, 50, 46, 40, 35, 28, 20, 11, 1, -7, -17, -26, -34, -43, -52,
246 -57, -60, -69, -74, -73, -77, -82, -79, -76, -78, -74, -66, -62, -58, -49, -39,
247 -33, -23, -12, -8, -1, 11, 16, 18, 24, 27, 28, 30, 30, 26, 25, 26, 19, 14, 11,
248 6, -1, -9, -14, -23, -30, -35, -39, -38, -37, -35, -30, -23, -18, -13, -6, 0, 3,
249 8, 12, 16, 20, 27, 35, 42, 51, 57, 63, 70, 72, 72, 70, 67, 61, 53, 45, 36, 30,
250 24, 17, 12, 6, 1, -4, -8, -14, -21, -26, -30, -33, -36, -36, -34, -30, -23, -16,
251 -8, 1, 9, 16, 23, 28, 32, 35, 37, 37, 35, 33, 31, 26, 21, 19, 17, 11, 4, 0, -6,
252 -18, -24, -29, -40, -48, -52, -62, -69, -68, -72, -73, -68, -69, -67, -59, -53,
253 -51, -46, -33, -28, -29, -15, -6, -6, 5, 15, 17, 23, 32, 31, 30, 35, 33, 27, 24,
254 21, 12, 7, 4, -8, -13, -11, -20, -26, -19, -16, -22, -20, -12, -12, -14, -12,
255 -11, -10, -5, -4, -5, 3, 12, 16, 23, 31, 36, 41, 47, 46, 42, 43, 42, 34, 28, 25,
256 20, 16, 16, 14, 11, 15, 16, 14, 13, 12, 11, 8, 6, 4, 1, 3, 4, 5, 12, 17, 20, 27,
257 33, 34, 36, 36, 32, 26, 20, 11, 2, -5, -10, -17, -23, -24, -28, -34, -35, -36,
258 -42, -48, -54, -57, -64, -71, -70, -68, -70, -64, -53, -48, -41, -30, -21, -13,
259 -10, -5, 0, 4, 6, 4, 10, 17, 18, 20, 25, 27, 27, 28, 23, 17, 11, 3, -5, -19,
260 -27, -32, -43, -44, -46, -48, -39, -33, -29, -19, -12, -6, 0, 3, 7, 12, 15, 20,
261 23, 29, 40, 45, 52, 61, 65, 68, 69, 65, 60, 52, 42, 32, 21, 11, 1, -8, -13, -17,
262 -21, -22, -23, -25, -24, -25, -26, -25, -24, -21, -18, -13, -5, 5, 15, 26, 37,
263 47, 56, 62, 67, 70, 70, 66, 61, 56, 45, 34, 25, 14, 3, -5, -16, -29, -35, -43,
264 -57, -64, -71, -81, -86, -86, -94, -100, -90, -83, -83, -75, -62, -52, -42, -27,
265 -19, -9, 5, 14, 19, 26, 35, 38, 44, 49, 49, 52, 53, 50, 46, 42, 33, 21, 12, 3,
266 -13, -26, -35, -45, -54, -62, -68, -66, -61, -58, -51, -41, -32, -23, -13, -4,
267 4, 12, 22, 29, 35, 43, 53, 62, 70, 76, 81, 84, 84, 82, 75, 67, 57, 45, 31, 17,
268 3, -9, -19, -29, -37, -42, -48, -51, -52, -53, -53, -51, -45, -40, -35, -24,
269 -13, -2, 11, 25, 38, 50, 60, 70, 79, 83, 84, 84, 81, 76, 67, 56, 43, 30, 17, 2,
270 -11, -26, -38, -51, -64, -71, -79, -93, -99, -96, -101, -108, -105, -95, -86,
271 -81, -70, -55, -39, -24, -15, -2, 16, 27, 32, 45, 52, 53, 59, 63, 63, 62, 60,
272 54, 47, 41, 31, 16, 5, -4, -21, -36, -47, -60, -68, -76, -87, -88, -79, -76,
273 -73, -58, -42, -31, -19, -4, 7, 19, 31, 38, 44, 55, 64, 70, 77, 83, 87, 92, 92,
274 86, 81, 75, 62, 46, 32, 16, -1, -14, -26, -39, -46, -49, -52, -53, -50, -48,
275 -43, -38, -35, -32, -24, -12, -1, 10, 18, 26, 41, 59, 72, 80, 82, 79, 79, 79,
276 73, 60, 42, 21, 5, -6, -22, -39, -45, -55, -70, -74, -73, -81, -91, -91, -92,
277 -97, -97, -92, -89, -81, -69, -55, -36, -18, -6, 13, 32, 43, 55, 64, 68, 68, 71,
278 69, 61, 57, 55, 47, 38, 32, 21, 10, 1, -13, -27, -41, -57, -72, -85, -95, -96,
279 -88, -83, -79, -63, -41, -25, -13, 4, 21, 33, 40, 43, 47, 56, 62, 64, 68, 74,
280 78, 83, 84, 81, 77, 71, 58, 41, 25, 9, -9, -23, -35, -45, -48, -46, -42, -36,
281 -28, -19, -10, -3, 3, 8, 11, 14, 19, 24, 30, 33, 40, 49, 52, 53, 53, 50, 42, 29,
282 15, 1, -14, -34, -48, -57, -68, -78, -83, -81, -80, -82, -83, -79, -71, -71,
283 -70, -61, -51, -44, -34, -20, -7, 10, 25, 37, 50, 62, 68, 69, 73, 72, 64, 57,
284 49, 40, 28, 17, 5, -5, -13, -26, -39, -47, -56, -64, -68, -69, -70, -68, -59,
285 -51, -44, -32, -17, -4, 7, 17, 28, 39, 48, 54, 58, 65, 67, 67, 68, 66, 61, 57,
286 52, 43, 33, 23, 12, 1, -8, -20, -29, -34, -37, -40, -38, -32, -26, -17, -6, 1,
287 10, 21, 28, 35, 40, 42, 44, 47, 47, 43, 38, 35, 30, 20, 9, 1, -5, -20, -32, -37,
288 -50, -62, -65, -72, -82, -84, -84, -86, -83, -79, -70, -61, -51, -40, -27, -13,
289 -3, 9, 24, 31, 36, 46, 51, 51, 55, 53, 51, 48, 42, 34, 24, 16, 4, -9, -21, -35,
290 -47, -55, -64, -68, -62, -61, -58, -45, -33, -24, -13, 0, 11, 19, 25, 32, 38,
291 44, 49, 52, 58, 60, 62, 66, 65, 61, 56, 51, 42, 29, 16, 4, -8, -18, -29, -37,
292 -41, -41, -41, -38, -32, -25, -16, -6, 3, 9, 18, 28, 34, 39, 43, 47, 50, 49, 43,
293 39, 35, 27, 16, 4, -7, -18, -29, -41, -53, -59, -67, -76, -77, -79, -83, -80,
294 -74, -71, -64, -55, -45, -32, -19, -8, 4, 19, 31, 40, 50, 56, 59, 63, 64, 58,
295 53, 48, 39, 28, 16, 3, -9, -20, -32, -45, -56, -64, -68, -69, -71, -70, -61,
296 -52, -45, -33, -18, -6, 8, 21, 31, 41, 52, 61, 67, 70, 72, 75, 76, 72, 65, 61,
297 56, 46, 35, 24, 13, 1, -10, -22, -32, -39, -43, -46, -47, -44, -39, -32, -22,
298 -12, -2, 9, 18, 28, 37, 41, 42, 45, 45, 42, 38, 30, 23, 18, 9, -5, -14, -20,
299 -29, -39, -47, -56, -60, -64, -71, -73, -69, -68, -66, -58, -49, -42, -30, -15,
300 -6, 3, 17, 27, 34, 42, 46, 47, 49, 48, 43, 37, 32, 24, 15, 6, -4, -13, -20, -27,
301 -34, -38, -41, -43, -42, -41, -42, -38, -31, -27, -23, -15, -6, 3, 12, 21, 30,
302 39, 47, 52, 55, 58, 58, 57, 53, 48, 42, 37, 31, 24, 18, 12, 7, 4, 1, -3, -6, -6,
303 -7, -8, -8, -8, -6, -6, -7, -8, -10, -11, -13, -18, -21, -25, -29, -33, -35,
304 -37, -37, -37, -37, -33, -30, -30, -26, -20, -18, -17, -12, -8, -4, 0, 3, 8, 13,
305 17, 21, 24, 26, 27, 25, 22, 17, 11, 4, -3, -11, -20, -23, -25, -28, -29, -27,
306 -25, -20, -15, -12, -9, -6, -4, -2, 1, 3, 6, 9, 11, 17, 24, 28, 30, 34, 35, 34,
307 33, 29, 23, 17, 10, 4, -1, -5, -9, -10, -11, -10, -7, -5, -2, 1, 2, 4, 5, 5, 5,
308 4, 1, 1, -1, -3, -6, -8, -11, -14, -17, -19, -24, -26, -27, -30, -34, -32, -30,
309 -30, -30, -27, -22, -18, -15, -9, -5, -1, 3, 7, 11, 15, 15, 16, 17, 16, 15, 12,
310 9, 7, 8, 6, 5, 6, 8, 8, 8, 9, 10, 8, 5, 3, 0, -3, -5, -7, -8, -8, -6, -3, -1, 1,
311 4, 6, 6, 6, 6, 4, 1, 0, -2, -4, -3, -3, -2, 1, 5, 8, 10, 13, 14, 16, 16, 15, 12,
312 8, 5, 2, -1, -5, -9, -14, -18, -22, -27, -31, -34, -39, -42, -43, -44, -44, -42,
313 -38, -32, -26, -21, -13, -6, 2, 8, 13, 18, 22, 23, 25, 25, 24, 22, 19, 15, 11,
314 6, 1, -4, -9, -14, -16, -17, -18, -19, -17, -15, -11, -8, -6, -2, 2, 4, 6, 10,
315 13, 15, 16, 19, 21, 21, 21, 20, 18, 16, 12, 8, 4, -1, -6, -10, -13, -14, -15,
316 -16, -15, -14, -11, -8, -5, -1, 2, 4, 7, 9, 10, 11, 10, 10, 8, 5, 2, -1, -8,
317 -13, -20, -28, -33, -39, -47, -50, -51, -54, -51, -45, -42, -36, -28, -18, -11,
318 -4, 4, 9, 14, 18, 20, 22, 23, 21, 20, 18, 15, 11, 6, -1, -7, -12, -17, -21, -25,
319 -28, -30, -29, -28, -26, -23, -19, -15, -10, -5, 1, 7, 12, 15, 21, 26, 29, 30,
320 31, 30, 29, 27, 23, 18, 14, 8, 2, -2, -6, -10, -14, -17, -19, -19, -19, -19,
321 -18, -16, -14, -11, -8, -4, -2, 0, 2, 5, 6, 5, 4, 5, 2, -4, -7, -9, -16, -23,
322 -27, -29, -33, -36, -35, -34, -32, -27, -24, -20, -14, -10, -7, -4, -1, 1, 1, 0,
323 0, 0, -1, -4, -6, -7, -10, -12, -13, -13, -13, -13, -12, -9, -7, -6, -4, -3, -1,
324 0, 0, 2, 3, 4, 4, 5, 7, 7, 7, 7, 7, 5, 3, 1, -1, -4, -8, -10, -12, -12, -12,
325 -12, -11, -8, -5, -1, 2, 6, 9, 12, 15, 17, 18, 19, 19, 17, 15, 14, 10, 5, -1,
326 -7, -13, -20, -28, -34, -39, -47, -52, -53, -52, -53, -51, -42, -34, -28, -18,
327 -5, 4, 12, 20, 27, 30, 32, 32, 30, 25, 21, 15, 7, 0, -6, -13, -18, -20, -22,
328 -25, -25, -24, -24, -22, -22, -21, -20, -20, -18, -16, -13, -11, -6, -2, 2, 6,
329 10, 13, 14, 14, 14, 12, 9, 5, 1, -3, -6, -9, -10, -11, -10, -9, -7, -5, -3, -1,
330 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 4, 1, -1, -4, -8, -13, -19, -23, -28, -35, -38,
331 -39, -42, -45, -41, -37, -35, -29, -19, -14, -7, 3, 9, 14, 21, 24, 24, 24, 23,
332 20, 14, 8, 2, -6, -13, -18, -22, -26, -29, -28, -25, -24, -21, -15, -13, -10,
333 -5, -2, 0, 3, 5, 5, 8, 10, 11, 12, 13, 13, 13, 12, 9, 7, 2, -3, -7, -11, -16,
334 -20, -23, -25, -25, -24, -22, -19, -15, -10, -6, -1, 3, 6, 9, 10, 12, 12, 12,
335 11, 10, 9, 6, 4, 1, -2, -6, -9, -13, -18, -22, -26, -32, -36, -37, -42, -46,
336 -44, -42, -41, -35, -28, -22, -14, -4, 4, 10, 16, 20, 19, 19, 17, 11, 4, -2, -9,
337 -15, -18, -21, -23, -19, -16, -14, -7, -1, 1, 3, 7, 7, 6, 7, 5, 3, 3, 4, 4, 4,
338 7, 9, 9, 10, 11, 9, 5, 2, -2, -7, -11, -16, -19, -20, -20, -19, -16, -12, -7,
339 -1, 4, 9, 13, 16, 17, 18, 17, 14, 11, 8, 4, 1, -2, -5, -8, -10, -11, -15, -16,
340 -18, -23, -24, -27, -31, -34, -36, -36, -37, -37, -33, -30, -25, -17, -10, -3,
341 4, 11, 15, 19, 21, 19, 17, 13, 6, -1, -7, -15, -20, -22, -26, -27, -24, -21,
342 -17, -12, -6, -3, 0, 4, 5, 5, 6, 4, 3, 4, 4, 4, 5, 7, 9, 10, 12, 12, 11, 9, 7,
343 3, 0, -5, -9, -12, -14, -14, -13, -11, -7, -3, 2, 7, 10, 14, 17, 17, 17, 16, 14,
344 11, 7, 5, 2, 0, -2, -4, -4, -5, -6, -7, -8, -11, -14, -16, -21, -26, -29, -34,
345 -35, -36, -38, -35, -30, -24, -17, -9, -2, 6, 14, 19, 20, 22, 21, 15, 11, 5, -3,
346 -9, -14, -19, -22, -21, -19, -17, -13, -8, -5, 0, 3, 4, 6, 5, 4, 4, 2, 1, 0, 0,
347 2, 3, 4, 6, 7, 8, 9, 8, 5, 3, 0, -4, -7, -10, -12, -13, -13, -11, -9, -5, -1, 4,
348 8, 12, 15, 17, 18, 18, 16, 14, 11, 7, 5, 2, 0, 0, 0, 0, 2, 4, 5, 6, 6, 5, 3, 2,
349 -2, -6, -11, -16, -21, -26, -27, -32, -35, -32, -33, -29, -23, -21, -14, -7, -1,
350 6, 10, 14, 17, 18, 18, 17, 14, 11, 7, 4, 2, 0, -2, -3, -3, -3, -2, -1, -2, -2,
351 -1, -3, -3, -4, -6, -7, -6, -6, -5, -3, -1, 2, 5, 9, 11, 12, 14, 13, 12, 11, 8,
352 5, 2, -1, -3, -4, -4, -4, -2, 0, 3, 6, 9, 11, 13, 14, 15, 14, 12, 10, 8, 5, 2,
353 1, 0, -1, 1, 1, 3, 5, 5, 6, 6, 5, 2, 0, -3, -6, -9, -13, -15, -18, -20, -21,
354 -24, -22, -22, -21, -18, -14, -11, -7, -2, 1, 5, 8, 10, 12, 12, 11, 10, 8, 6, 4,
355 2, -1, -1, -3, -4, -3, -4, -3, -2, -2, -1, 0, 0, 1, 3, 4, 6, 8, 10, 12, 13, 14,
356 14, 13, 12, 9, 7, 4, 0, -3, -7, -9, -11, -13, -13, -13, -11, -8, -5, -2, 2, 6,
357 10, 13, 15, 17, 18, 18, 17, 16, 14, 12, 10, 7, 5, 3, 2, 1, 1, 1, 2, 2, 3, 4, 4,
358 4, 4, 4, 3, 1, 0, -1, -3, -5, -6, -10, -12, -16, -21, -24, -29, -33, -36, -38,
359 -36, -34, -28, -20, -11, 1, 12, 24, 33, 41, 45, 45, 44, 36, 29, 19, 6, -4, -15,
360 -24, -30, -34, -35, -33, -28, -22, -15, -7, 1, 7, 13, 17, 20, 21, 21, 20, 18,
361 16, 15, 12, 11, 9, 7, 6, 4, 2, -1, -4, -7, -10, -13, -15, -16, -16, -14, -11,
362 -7, -2, 4, 9, 15, 19, 22, 24, 23, 21, 17, 12, 6, -1, -7, -13, -17, -20, -21,
363 -20, -18, -14, -9, -3, 2, 7, 12, 15, 17, 18, 17, 15, 13, 11, 9, 8, 8, 9, 11, 14,
364 17, 20, 23, 24, 23, 21, 18, 11, 4, -3, -12, -20, -27, -33, -37, -38, -38, -35,
365 -32, -28, -23, -18, -10, -3, 2, 11, 16, 22, 28, 31, 34, 34, 32, 28, 24, 17, 9,
366 1, -7, -14, -20, -25, -27, -28, -26, -22, -17, -10, -2, 5, 12, 19, 24, 28, 30,
367 30, 30, 27, 24, 19, 14, 9, 4, 0, -5, -8, -10, -12, -13, -13, -12, -10, -8, -5,
368 -3, 1, 4, 7, 10, 13, 15, 16, 17, 17, 17, 16, 14, 11, 8, 4, 1, -3, -5, -8, -10,
369 -11, -11, -11, -9, -7, -4, -1, 3, 6, 9, 12, 14, 16, 17, 17, 17, 15, 13, 12, 9,
370 7, 4, 2, 1, -1, 0, 1, 4, 8, 12, 18, 23, 27, 31, 32, 31, 27, 21, 13, 4, -6, -16,
371 -24, -31, -35, -37, -36, -32, -27, -19, -11, -4, 4, 10, 15, 18, 19, 19, 18, 15,
372 12, 9, 5, 2, -1, -3, -6, -7, -8, -11, -12, -13, -14, -15, -14, -13, -10, -6, -2,
373 4, 9, 16, 21, 26, 30, 31, 32, 30, 26, 20, 14, 7, -1, -7, -14, -19, -22, -24,
374 -23, -22, -18, -14, -9, -3, 2, 7, 12, 16, 19, 21, 22, 22, 21, 20, 19, 16, 14,
375 11, 8, 5, 2, -2, -5, -8, -11, -13, -15, -15, -15, -14, -11, -8, -3, 1, 7, 13,
376 21, 30, 34, 41, 43, 42, 42, 35, 26, 15, 3, -10, -22, -32, -40, -46, -48, -47,
377 -43, -37, -29, -20, -11, 0, 9, 17, 24, 28, 32, 33, 33, 31, 26, 23, 17, 12, 7, 1,
378 -3, -7, -9, -11, -11, -11, -9, -7, -4, -1, 3, 6, 8, 11, 11, 12, 12, 10, 9, 5, 2,
379 -2, -6, -8, -10, -12, -12, -12, -10, -7, -5, -2, 1, 3, 6, 7, 8, 8, 8, 7, 7, 6,
380 6, 6, 5, 6, 6, 6, 7, 6, 6, 6, 4, 3, 1, 0, -2, -4, -5, -6, -6, -6, -4, -3, 2, 5,
381 9, 16, 18, 23, 27, 28, 29, 27, 25, 20, 15, 8, 1, -6, -12, -16, -20, -20, -20,
382 -18, -14, -11, -6, -2, 1, 3, 4, 3, 3, 0, -3, -5, -7, -9, -8, -7, -5, -1, 2, 8,
383 12, 16, 18, 19, 19, 17, 13, 8, 2, -4, -10, -14, -17, -18, -18, -16, -11, -6, 1,
384 8, 14, 20, 24, 26, 27, 26, 22, 18, 13, 8, 3, -2, -5, -7, -9, -8, -7, -6, -4, -2,
385 0, 3, 3, 4, 4, 3, 2, 1, 1, 0, 1, 1, 2, 4, 6, 9, 11, 13, 14, 14, 14, 13, 11, 8,
386 5, 2, -2, -5, -8, -4, -4, 1, 7, 9, 18, 22, 26, 29, 28, 25, 20, 14, 6, -2, -11,
387 -19, -25, -30, -31, -31, -29, -23, -17, -10, -2, 5, 12, 17, 22, 24, 24, 23, 21,
388 18, 14, 11, 8, 5, 4, 3, 3, 4, 5, 6, 7, 8, 8, 7, 6, 4, 2, 0, -1, -3, -3, -4, -3,
389 -3, -2, -1, -1, -1, 0, 0, -1, -1, -3, -2, -2, -2, -2, -2, -1, 0, 1, 3, 4, 5, 7,
390 9, 9, 11, 11, 11, 12, 11, 11, 10, 9, 8, 7, 7, 7, 6, 6, 7, 8, 9, 10, 11, 12, 13,
391 13, 13, 13, 12, 11, 9, 8, 7, 5, 4, 3, 2, 1, 1, 1, 1, 0, 0, 0, 0, -1, -1, -3, -3,
392 -5, -6, -7, -9, -9, -10, -10, -10, -10, -10, -9, -8, -6, -5, -4, -2, 1, 4, 5, 8,
393 9, 11, 13, 13, 13, 12, 11, 9, 7, 6, 4, 2, 1, 1, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3,
394 3, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 9, 8, 6, 5, 3, 2, 0,
395 -1, -1, -2, -2, -1, 0, 1, 3, 4, 6, 7, 8, 9, 9, 9, 9, 8, 7, 6, 4, 3, 2, 1, 0, 1,
396 2, 5, 9, 12, 17, 19, 21, 22, 20, 17, 12, 6, 0, -7, -13, -18, -22, -23, -23, -21,
397 -18, -13, -8, -2, 4, 9, 12, 14, 16, 16, 14, 12, 9, 6, 3, 1, 0, -1, 0, 1, 3, 6,
398 8, 11, 13, 13, 14, 13, 11, 8, 4, -1, -6, -11, -16, -22, -24, -26, -26, -24, -22,
399 -17, -12, -5, 2, 7, 12, 17, 20, 22, 23, 21, 20, 17, 14, 12, 8, 5, 3, 1, 1, 0, 0,
400 2, 2, 3, 4, 4, 4, 5, 4, 3, 3, 2, 2, 2, 2, 3, 4, 6, 8, 10, 12, 14, 15, 16, 15,
401 14, 13, 11, 8, 5, 2, -1, -4, -6, -8, -9, -10, -10, -10, -9, -8, -8, -7, -7, -7,
402 -6, -7, -6, -7, -8, -8, -8, -7, -6, -5, -4, -2, 0, 1, 4, 5, 6, 9, 9, 10, 10, 9,
403 10, 9, 8, 7, 5, 4, 3, 2, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4,
404 5, 6, 7, 8, 9, 9, 9, 10, 9, 8, 7, 6, 4, 2, 1, -1, -2, -3, -3, -3, -3, -2, -1, 1,
405 2, 4, 5, 6, 7, 7, 7, 7, 7, 6, 5, 5, 3, 7, 9, 10, 17, 15, 19, 22, 19, 20, 16, 10,
406 5, -3, -9, -15, -22, -25, -27, -28, -24, -21, -16, -9, -3, 4, 10, 15, 19, 21,
407 22, 22, 21, 18, 15, 12, 9, 7, 5, 4, 3, 4, 5, 6, 7, 9, 9, 9, 8, 6, 5, 0, -3, -8,
408 -13, -18, -24, -26, -28, -27, -24, -22, -16, -9, 0, 8, 16, 22, 28, 31, 33, 33,
409 30, 25, 19, 12, 5, -2, -9, -13, -17, -19, -19, -18, -15, -11, -7, -2, 3, 7, 11,
410 14, 16, 17, 18, 17, 17, 16, 14, 14, 12, 11, 10, 9, 9, 8, 7, 7, 5, 4, 2, 0, -2,
411 -4, -7, -9, -12, -14, -15, -17, -17, -17, -16, -14, -13, -9, -7, -5, 0, 2, 5, 8,
412 9, 10, 11, 10, 8, 6, 3, 0, -1, -5, -5, -6, -6, -3, -2, 0, 3, 5, 7, 8, 9, 8, 8,
413 5, 3, 2, -2, -3, -4, -5, -5, -4, -3, -1, 1, 3, 5, 6, 7, 8, 7, 7, 5, 3, 2, 0, -2,
414 -3, -4, -4, -3, -2, -1, 1, 2, 4, 6, 6, 7, 7, 6, 6, 4, 3, 1, -1, -1, -2, -2, -2,
415 1, 5, 6, 15, 17, 21, 29, 28, 31, 32, 25, 22, 16, 5, -1, -12, -22, -27, -35, -37,
416 -37, -38, -32, -27, -20, -11, -3, 5, 13, 18, 23, 25, 26, 26, 23, 20, 16, 12, 9,
417 5, 2, 1, -1, -1, 0, 0, 2, 3, 3, 4, 3, 1, -1, -5, -9, -15, -23, -29, -32, -34,
418 -35, -33, -30, -23, -12, -3, 9, 19, 27, 35, 41, 45, 44, 41, 34, 27, 18, 7, -2,
419 -12, -19, -24, -27, -27, -25, -21, -16, -9, -2, 4, 10, 14, 17, 19, 18, 17, 15,
420 13, 11, 9, 8, 7, 7, 8, 9, 10, 12, 12, 13, 12, 11, 8, 4, 0, -5, -10, -16, -20,
421 -24, -27, -28, -28, -26, -23, -17, -12, -6, 1, 6, 12, 16, 19, 21, 21, 20, 18,
422 15, 11, 7, 3, -1, -5, -10, -13, -16, -18, -17, -18, -18, -15, -13, -10, -5, -2,
423 1, 4, 6, 8, 10, 11, 11, 11, 10, 10, 9, 8, 7, 5, 5, 3, 2, 2, 0, -1, -1, -2, -3,
424 -3, -4, -4, -4, -4, -4, -4, -3, -2, -1, 0, 1, 3, 4, 5, 6, 6, 6, 6, 6, 5, 4, 2,
425 2, 1, 0, 1, 2, 3, 6, 8, 10, 13, 14, 16, 17, 16, 15, 12, 8, 4, -2, -7, -13, -18,
426 -22, -26, -28, -29, -29, -27, -23, -19, -14, -8, -2, 4, 9, 13, 17, 20, 21, 22,
427 21, 21, 19, 17, 15, 12, 10, 8, 6, 4, 3, 2, 1, -1, -2, -3, -4, -6, -8, -10, -13,
428 -16, -20, -26, -29, -28, -29, -28, -26, -23, -14, -5, 3, 13, 20, 27, 32, 37, 40,
429 38, 35, 30, 24, 17, 10, 2, -5, -11, -16, -19, -20, -20, -19, -17, -14, -10, -6,
430 -4, -1, 0, 1, 2, 2, 1, 0, 0, 1, 2, 4, 8, 10, 15, 21, 25, 29, 31, 32, 31, 28, 24,
431 18, 10, 1, -7, -16, -23, -30, -35, -38, -39, -37, -33, -29, -22, -16, -9, -1, 5,
432 10, 15, 17, 19, 20, 19, 19, 17, 16, 14, 13, 11, 10, 10, 9, 9, 8, 8, 7, 6, 4, 1,
433 -1, -5, -10, -14, -21, -28, -32, -34, -36, -37, -36, -31, -24, -15, -5, 5, 14,
434 23, 31, 38, 42, 42, 40, 36, 31, 24, 16, 7, -1, -9, -15, -20, -22, -24, -25, -23,
435 -20, -17, -13, -9, -6, -4, -1, 0, 2, 2, 1, 1, 1, 1, 2, 3, 4, 5, 8, 12, 14, 17,
436 20, 21, 24, 25, 25, 24, 20, 17, 12, 7, 1, -5, -11, -17, -21, -24, -27, -28, -27,
437 -26, -23, -19, -15, -10, -7, -3, 0, 3, 6, 8, 8, 9, 10, 11, 11, 11, 12, 12, 12,
438 13, 14, 14, 13, 12, 11, 9, 7, 5, 2, -1, -4, -7, -9, -11, -13, -15, -15, -16,
439 -18, -21, -23, -22, -21, -22, -20, -18, -13, -8, -3, 4, 8, 14, 19, 23, 27, 27,
440 26, 26, 22, 20, 15, 10, 6, -1, -5, -8, -12, -14, -16, -16, -16, -15, -12, -10,
441 -9, -7, -4, -2, 0, 1, 2, 4, 7, 8, 12, 14, 16, 20, 23, 26, 28, 27, 28, 25, 22,
442 19, 13, 7, 0, -7, -13, -20, -25, -29, -32, -33, -33, -30, -27, -23, -17, -11,
443 -5, 2, 7, 12, 15, 18, 20, 20, 20, 19, 17, 15, 13, 11, 9, 7, 6, 5, 4, 3, 2, 1,
444 -1, -3, -5, -10, -14, -18, -21, -24, -27, -28, -28, -25, -22, -16, -10, -4, 3,
445 11, 17, 23, 27, 30, 31, 31, 29, 26, 21, 16, 10, 5, 1, -4, -8, -11, -12, -13,
446 -12, -11, -9, -9, -7, -5, -4, -3, -3, -3, -3, -4, -4, -4, -4, -3, -1, 1, 4, 7,
447 9, 13, 17, 19, 22, 24, 25, 25, 25, 24, 21, 17, 13, 8, 2, -3, -8, -13, -17, -21,
448 -23, -24, -25, -24, -23, -21, -18, -15, -11, -9, -6, -2, 0, 2, 4, 5, 6, 7, 8, 9,
449 9, 10, 11, 12, 13, 13, 13, 13, 12, 12, 10, 9, 7, 4, 2, -1, -3, -5, -8, -9, -11,
450 -12, -12, -13, -14, -16, -18, -19, -19, -18, -19, -19, -18, -14, -11, -7, -3, 1,
451 6, 10, 15, 19, 21, 22, 23, 23, 22, 19, 16, 12, 7, 3, 0, -3, -7, -11, -13, -13,
452 -13, -13, -13, -11, -10, -9, -7, -4, -4, -4, -3, -2, 2, 4, 4, 8, 11, 14, 17, 20,
453 22, 19, 20, 20, 17, 15, 10, 5, 2, -5, -9, -12, -17, -20, -23, -22, -21, -21,
454 -19, -17, -14, -10, -7, -3, 0, 2, 4, 6, 8, 8, 7, 7, 7, 6, 7, 5, 5, 5, 4, 4, 4,
455 3, 2, -1, -3, -4, -6, -8, -12, -13, -14, -15, -14, -13, -12, -11, -8, -4, -1, 2,
456 5, 8, 11, 13, 14, 16, 15, 14, 12, 11, 10, 7, 4, 2, 0, -1, -3, -4, -4, -5, -5,
457 -4, -3, -3, -3, -2, -2, -2, -2, -2, -3, -3, -4, -3, -3, -3, -2, -1, 0, 2, 3, 5,
458 7, 8, 11, 14, 15, 17, 18, 20, 20, 20, 20, 17, 13, 12, 8, 4, 1, -5, -8, -11, -15,
459 -16, -18, -19, -20, -20, -18, -17, -16, -14, -13, -11, -8, -6, -4, -2, -1, 1, 3,
460 5, 7, 8, 10, 11, 13, 14, 15, 15, 16, 16, 16, 15, 14, 13, 11, 10, 8, 6, 3, 0, -3,
461 -6, -9, -12, -15, -17, -20, -23, -25, -27, -27, -26, -26, -25, -22, -18, -14,
462 -9, -3, 2, 6, 11, 16, 20, 22, 22, 23, 23, 23, 20, 17, 15, 12, 8, 5, 2, 0, -4,
463 -6, -8, -8, -10, -12, -12, -12, -13, -13, -12, -10, -8, -7, -4, 1, 5, 8, 11, 16,
464 18, 19, 20, 21, 20, 18, 15, 12, 9, 4, 0, -4, -7, -11, -13, -15, -17, -17, -17,
465 -17, -16, -15, -13, -12, -10, -9, -7, -5, -4, -4, -2, -2, -1, 0, 0, 1, 1, 1, 0,
466 -1, -2, -1, -2, -4, -5, -4, -4, -4, -3, -3, -3, -2, -1, 0, 1, 0, 0, 1, 1, 1, 0,
467 0, -1, -2, -2, -1, -1, -2, -2, -1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, -1, -2,
468 -2, -3, -3, -4, -4, -3, -3, -3, -2, -1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 3,
469 3, 5, 7, 9, 11, 13, 15, 16, 16, 15, 14, 13, 10, 6, 2, -2, -7, -11, -14, -19,
470 -22, -24, -25, -26, -26, -25, -24, -21, -18, -15, -12, -9, -5, -2, 1, 4, 6, 8,
471 9, 11, 12, 13, 14, 14, 14, 15, 15, 15, 14, 14, 13, 12, 11, 9, 7, 5, 2, -1, -5,
472 -9, -13, -17, -22, -26, -30, -31, -32, -34, -34, -31, -28, -24, -19, -13, -6,
473 -1, 5, 12, 18, 21, 24, 27, 29, 29, 27, 25, 23, 19, 15, 11, 8, 4, 0, -4, -5, -7,
474 -9, -11, -11, -11, -11, -11, -11, -11, -11, -11, -9, -7, -6, -5, -2, 2, 4, 7,
475 11, 13, 15, 17, 19, 20, 19, 19, 17, 15, 12, 9, 5, 1, -4, -8, -11, -15, -19, -21,
476 -23, -24, -24, -23, -22, -21, -19, -16, -13, -10, -7, -5, -2, 0, 2, 3, 3, 3, 3,
477 2, 1, 1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 6, 4, 4, 2, -1, -3, -4, -6,
478 -8, -9, -9, -9, -9, -9, -7, -5, -4, -2, 0, 3, 4, 6, 7, 8, 9, 8, 8, 8, 6, 5, 3,
479 2, 0, -1, -2, -2, -3, -3, -2, -2, -1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2,
480 4, 6, 8, 10, 11, 13, 14, 15, 15, 14, 12, 10, 8, 4, 0, -4, -8, -12, -16, -20,
481 -22, -24, -26, -26, -25, -24, -22, -20, -16, -13, -9, -5, -1, 3, 6, 9, 11, 14,
482 16, 16, 17, 17, 17, 17, 16, 15, 14, 13, 12, 10, 9, 7, 4, 2, -1, -5, -9, -13,
483 -17, -20, -24, -28, -30, -31, -32, -32, -30, -27, -23, -19, -14, -7, -1, 5, 10,
484 15, 21, 24, 26, 28, 29, 28, 26, 24, 21, 18, 13, 9, 5, 2, -1, -4, -7, -8, -9,
485 -10, -11, -11, -11, -11, -11, -11, -11, -11, -11, -9, -7, -8, -5, 0, 1, 4, 10,
486 13, 14, 18, 22, 23, 23, 24, 22, 20, 19, 14, 9, 5, -2, -7, -11, -16, -21, -24,
487 -26, -29, -29, -28, -27, -26, -23, -21, -18, -14, -12, -9, -7, -6, -4, -2, -2,
488 -3, -2, 0, 0, 0, 2, 3, 5, 7, 8, 11, 13, 13, 13, 14, 15, 13, 11, 9, 7, 4, 1, -3,
489 -6, -9, -12, -15, -16, -17, -18, -18, -17, -16, -14, -12, -10, -7, -4, -2, 1, 3,
490 5, 7, 8, 8, 9, 9, 8, 7, 7, 6, 5, 3, 2, 1, 0, -1, -2, -2, -3, -4, -4, -4, -5, -5,
491 -5, -4, -4, -4, -2, -1, 0, 2, 4, 5, 6, 8, 9, 10, 10, 10, 9, 8, 7, 5, 2, -1, -4,
492 -7, -10, -14, -17, -19, -22, -24, -24, -24, -24, -23, -21, -19, -16, -13, -10,
493 -7, -3, 0, 3, 6, 8, 10, 12, 13, 14, 14, 14, 13, 13, 11, 9, 7, 4, 0, -3, -6, -9,
494 -12, -15, -17, -18, -19, -19, -20, -19, -17, -16, -13, -11, -8, -5, -3, 0, 3, 6,
495 7, 9, 11, 12, 12, 12, 12, 12, 11, 10, 9, 9, 7, 6, 4, 4, 2, 1, 0, -1, -2, -3, -4,
496 -5, -6, -7, -8, -9, -9, -10, -10, -10, -10, -9, -8, -7, -4, -1, 2, 4, 9, 13, 15,
497 19, 22, 24, 24, 25, 25, 23, 21, 17, 13, 10, 5, -1, -5, -10, -15, -19, -22, -25,
498 -27, -28, -29, -28, -26, -24, -22, -19, -15, -13, -9, -6, -4, -1, 1, 1, 3, 4, 3,
499 3, 3, 2, 3, 3, 2, 3, 4, 5, 6, 8, 10, 11, 11, 12, 13, 13, 12, 10, 9, 7, 4, 1, -2,
500 -5, -9, -11, -14, -15, -16, -17, -16, -15, -13, -11, -8, -5, -2, 1, 4, 7, 9, 11,
501 12, 12, 12, 12, 11, 9, 7, 5, 3, 1, -1, -2, -3, -5, -5, -6, -6, -6, -5, -5, -3,
502 -1, 0, 2, 4, 7, 7, 9, 11, 11, 11, 12, 12, 11, 10, 8, 6, 4, 2, -1, -4, -7, -10,
503 -12, -14, -16, -18, -19, -20, -20, -19, -19, -18, -17, -15, -13, -11, -9, -7,
504 -4, -2, 0, 3, 6, 7, 9, 11, 12, 13, 14, 14, 13, 13, 12, 10, 8, 5, 1, -2, -5, -8,
505 -12, -14, -17, -19, -19, -20, -21, -20, -19, -17, -15, -12, -10, -7, -4, -1, 2,
506 4, 6, 7, 9, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -3,
507 -4, -5, -6, -8, -8, -9, -10, -10, -9, -8, -7, -5, -3, 0, 2, 6, 9, 11, 14, 16,
508 18, 19, 19, 19, 18, 16, 14, 11, 8, 4, -1, -5, -9, -14, -18, -22, -25, -27, -29,
509 -30, -30, -30, -28, -26, -23, -20, -16, -12, -9, -5, -1, 1, 4, 6, 7, 8, 8, 9, 9,
510 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 8, 8, 7, 5, 4, 2, -1, -3, -6, -8, -10,
511 -12, -14, -14, -15, -14, -14, -12, -10, -8, -6, -3, 0, 3, 5, 8, 10, 11, 13, 13,
512 13, 13, 13, 12, 10, 9, 7, 6, 4, 2, 0, -1, -2, -2, -2, -3, -1, 1, 2, 4, 7, 9, 10,
513 12, 14, 14, 15, 14, 13, 12, 10, 6, 3, 0, -6, -10, -14, -18, -22, -25, -27, -29,
514 -29, -29, -28, -26, -23, -20, -16, -11, -7, -2, 3, 6, 10, 14, 16, 18, 20, 20,
515 19, 19, 16, 14, 11, 7, 4, 1, -2, -6, -9, -11, -12, -13, -14, -14, -13, -11, -11,
516 -9, -7, -5, -4, -3, -1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 5, 6, 7,
517 7, 8, 9, 9, 9, 8, 8, 6, 5, 3, 1, -1, -3, -5, -7, -9, -10, -11, -13, -13, -10,
518 -9, -9, -4, 0, 2, 6, 11, 14, 18, 20, 23, 25, 25, 25, 23, 21, 19, 13, 8, 5, -2,
519 -8, -13, -19, -25, -28, -32, -35, -36, -36, -36, -35, -31, -28, -24, -20, -15,
520 -10, -5, -2, 3, 7, 10, 11, 13, 14, 14, 13, 13, 12, 10, 10, 9, 7, 7, 7, 6, 6, 7,
521 7, 8, 8, 8, 8, 8, 7, 6, 5, 3, 0, -2, -4, -7, -10, -12, -15, -16, -17, -18, -19,
522 -18, -17, -15, -13, -9, -6, -3, 1, 5, 9, 12, 15, 17, 19, 20, 20, 20, 19, 18, 16,
523 13, 10, 8, 5, 2, 1, -2, -3, -2, -2, -2, 0, 2, 3, 5, 7, 9, 10, 11, 11, 10, 9, 8,
524 4, 1, -2, -7, -11, -14, -19, -22, -24, -28, -29, -29, -29, -28, -25, -23, -19,
525 -15, -10, -5, 0, 5, 9, 13, 16, 19, 20, 21, 21, 19, 18, 15, 12, 9, 6, 2, 0, -2,
526 -4, -6, -7, -7, -6, -6, -4, -3, -1, 0, 2, 3, 5, 5, 5, 5, 4, 3, 2, 0, -2, -3, -5,
527 -7, -8, -8, -9, -9, -8, -7, -5, -2, 0, 2, 5, 8, 10, 12, 14, 15, 15, 16, 15, 14,
528 13, 10, 8, 6, 3, 0, -2, -3, -3, -6, -6, -3, -3, -1, 3, 5, 8, 10, 13, 16, 17, 17,
529 18, 15, 15, 13, 8, 5, 1, -6, -9, -14, -21, -24, -27, -31, -33, -33, -33, -32,
530 -31, -28, -25, -21, -17, -12, -8, -3, 1, 4, 8, 10, 12, 14, 16, 15, 15, 15, 14,
531 13, 13, 11, 11, 10, 9, 9, 9, 9, 8, 7, 8, 7, 7, 6, 5, 4, 3, 1, -2, -3, -5, -8,
532 -11, -13, -14, -16, -17, -18, -18, -17, -16, -15, -12, -9, -7, -4, 0, 4, 7, 10,
533 13, 16, 18, 19, 20, 21, 21, 20, 19, 17, 15, 14, 12, 10, 8, 8, 7, 5, 6, 6, 6, 6,
534 6, 7, 7, 6, 5, 3, 1, 0, -4, -7, -9, -14, -17, -20, -24, -25, -27, -29, -30, -28,
535 -28, -26, -24, -21, -16, -13, -10, -5, -1, 3, 6, 9, 12, 15, 16, 17, 18, 18, 18,
536 18, 17, 16, 15, 13, 11, 10, 9, 8, 6, 5, 4, 3, 3, 3, 2, 1, 1, 0, -1, -1, -2, -3,
537 -4, -6, -6, -7, -8, -9, -10, -10, -10, -10, -10, -8, -7, -6, -4, -2, 1, 4, 6, 9,
538 11, 13, 15, 16, 17, 18, 18, 17, 17, 16, 14, 13, 14, 12, 9, 11, 11, 9, 11, 11,
539 10, 11, 10, 10, 11, 9, 8, 6, 2, 2, -2, -7, -9, -14, -18, -20, -26, -27, -28,
540 -32, -33, -32, -32, -30, -29, -27, -23, -19, -16, -11, -6, -1, 3, 7, 11, 16, 18,
541 20, 22, 24, 25, 25, 24, 24, 23, 20, 18, 16, 15, 12, 9, 7, 6, 4, 2, 0, -1, -2,
542 -3, -5, -5, -5, -7, -8, -9, -9, -10, -11, -12, -12, -12, -12, -12, -11, -10, -9,
543 -8, -6, -3, -1, 1, 3, 6, 8, 10, 12, 13, 15, 16, 16, 16, 16, 16, 15, 16, 16, 13,
544 14, 15, 13, 14, 14, 13, 13, 13, 12, 12, 10, 9, 6, 2, 1, -1, -7, -10, -13, -18,
545 -21, -26, -29, -30, -34, -36, -37, -37, -36, -36, -35, -31, -28, -26, -20, -15,
546 -10, -5, -1, 5, 10, 15, 18, 23, 26, 28, 29, 31, 32, 31, 30, 29, 27, 25, 22, 18,
547 15, 13, 8, 5, 2, -1, -4, -7, -9, -11, -13, -15, -16, -17, -17, -18, -18, -18,
548 -17, -17, -16, -15, -14, -12, -11, -9, -7, -5, -3, 0, 2, 5, 7, 9, 12, 14, 16,
549 17, 18, 20, 21, 21, 21, 22, 23, 22, 22, 22, 22, 22, 21, 19, 18, 17, 15, 12, 10,
550 6, 3, -1, -5, -9, -14, -18, -23, -27, -31, -34, -38, -40, -41, -42, -42, -42,
551 -40, -37, -35, -31, -26, -21, -16, -10, -4, 2, 7, 12, 18, 23, 27, 30, 33, 36,
552 38, 39, 39, 40, 39, 37, 35, 33, 30, 27, 22, 19, 15, 10, 6, 1, -3, -7, -11, -14,
553 -17, -19, -22, -24, -25, -25, -26, -26, -25, -24, -23, -21, -19, -16, -14, -11,
554 -8, -4, -1, 3, 6, 10, 13, 16, 19, 22, 25, 27, 29, 31, 33, 34, 36, 36, 36, 36,
555 35, 34, 32, 29, 26, 22, 18, 13, 8, 3, -3, -9, -14, -20, -26, -30, -35, -39, -43,
556 -45, -47, -48, -49, -48, -46, -44, -41, -37, -32, -27, -22, -16, -9, -3, 2, 7,
557 14, 18, 22, 26, 30, 34, 36, 37, 39, 40, 40, 39, 38, 37, 35, 33, 30, 27, 24, 20,
558 16, 12, 9, 4, 0, -4, -7, -11, -15, -18, -21, -23, -25, -27, -28, -28, -29, -29,
559 -28, -26, -25, -23, -20, -17, -14, -11, -7, -3, 1, 4, 9, 13, 17, 21, 26, 30, 34,
560 37, 41, 44, 45, 46, 47, 46, 45, 42, 39, 34, 29, 22, 15, 8, 1, -7, -15, -22, -29,
561 -35, -41, -46, -50, -53, -55, -55, -55, -54, -51, -47, -43, -38, -32, -26, -20,
562 -14, -9, -2, 4, 9, 13, 18, 22, 25, 28, 31, 33, 35, 35, 36, 37, 38, 37, 37, 36,
563 35, 33, 31, 29, 27, 24, 20, 17, 13, 9, 5, 0, -4, -8, -12, -16, -19, -22, -25,
564 -28, -29, -30, -30, -30, -29, -28, -26, -23, -20, -17, -13, -9, -6, -2, 4, 8,
565 11, 17, 21, 24, 29, 32, 35, 37, 38, 38, 38, 37, 35, 32, 27, 25, 19, 13, 8, 2,
566 -3, -10, -16, -20, -24, -29, -33, -36, -38, -40, -41, -40, -39, -38, -36, -33,
567 -29, -26, -23, -19, -14, -11, -8, -3, 0, 3, 6, 9, 13, 16, 18, 21, 23, 26, 27,
568 29, 31, 32, 33, 33, 34, 33, 32, 31, 29, 27, 24, 20, 17, 13, 9, 4, 0, -4, -8,
569 -12, -15, -18, -21, -23, -24, -25, -25, -25, -24, -23, -21, -19, -17, -15, -10,
570 -7, -3, 2, 7, 11, 16, 20, 24, 27, 29, 30, 31, 30, 29, 27, 23, 20, 16, 10, 5, 0,
571 -5, -10, -16, -20, -23, -26, -29, -31, -31, -30, -30, -29, -26, -24, -22, -20,
572 -17, -13, -10, -8, -6, -4, -2, 0, 1, 3, 5, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19,
573 20, 21, 22, 22, 21, 21, 21, 20, 18, 15, 13, 11, 9, 6, 4, 1, -1, -4, -6, -7, -8,
574 -9, -11, -11, -11, -11, -11, -10, -10, -9, -7, -6, -3, 0, 2, 5, 8, 11, 14, 15,
575 17, 18, 19, 18, 17, 16, 14, 12, 9, 5, 2, -2, -6, -10, -13, -17, -19, -22, -23,
576 -25, -26, -26, -26, -25, -24, -23, -21, -19, -18, -16, -14, -11, -10, -8, -6,
577 -4, -2, 0, 3, 5, 7, 9, 11, 14, 16, 17, 18, 21, 22, 22, 23, 23, 23, 22, 21, 20,
578 19, 17, 14, 12, 9, 7, 4, 2, 0, -2, -4, -6, -7, -8, -8, -8, -9, -8, -8, -7, -6,
579 -5, -3, 0, 1, 3, 7, 10, 12, 14, 17, 18, 19, 18, 18, 18, 17, 13, 10, 8, 5, 1, -3,
580 -7, -10, -14, -18, -20, -23, -24, -26, -28, -28, -28, -28, -27, -26, -24, -23,
581 -22, -20, -17, -15, -13, -12, -9, -6, -5, -2, 0, 3, 5, 6, 9, 11, 13, 15, 17, 18,
582 19, 20, 21, 21, 21, 21, 20, 18, 17, 16, 14, 11, 9, 7, 5, 3, 1, -1, -2, -3, -4,
583 -5, -5, -5, -5, -5, -4, -3, -2, -1, 2, 4, 5, 8, 10, 11, 13, 13, 13, 13, 12, 10,
584 9, 7, 4, 1, -2, -4, -7, -10, -13, -15, -17, -20, -22, -22, -23, -24, -24, -24,
585 -24, -23, -22, -21, -20, -19, -18, -16, -14, -12, -11, -10, -8, -7, -6, -4, -3,
586 -1, -1, 0, 2, 3, 5, 7, 8, 9, 10, 10, 12, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7,
587 7, 7, 7, 7, 7, 6, 6, 7, 7, 7, 8, 8, 8, 9, 10, 10, 11, 11, 11, 11, 11, 9, 8, 7,
588 5, 2, 0, -2, -5, -7, -10, -13, -15, -18, -20, -21, -22, -24, -25, -24, -25, -25,
589 -24, -24, -23, -21, -21, -19, -17, -15, -13, -12, -9, -7, -6, -4, -2, -1, 0, 0,
590 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 3, 3, 3, 4, 5, 6, 6,
591 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, 18, 16, 16, 15, 12, 10,
592 8, 5, 2, -1, -4, -7, -10, -13, -16, -18, -21, -23, -25, -26, -27, -29, -29, -29,
593 -29, -29, -29, -28, -26, -25, -24, -22, -19, -16, -14, -11, -9, -6, -4, -3, -2,
594 0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 7,
595 6, 7, 7, 7, 7, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 15, 14, 12,
596 11, 9, 6, 4, 1, -1, -3, -6, -8, -11, -13, -15, -17, -19, -20, -22, -23, -24,
597 -25, -26, -27, -27, -27, -26, -26, -25, -22, -20, -18, -16, -14, -12, -10, -10,
598 -10, -9, -8, -7, -6, -4, -3, -2, -1, -1, 0, 0, 1, 1, 1, 2, 3, 4, 4, 5, 7, 8, 9,
599 10, 12, 13, 13, 14, 15, 16, 17, 17, 18, 19, 19, 19, 20, 20, 21, 20, 20, 19, 18,
600 17, 15, 13, 11, 8, 5, 2, -1, -3, -7, -10, -12, -15, -17, -20, -22, -24, -25,
601 -27, -28, -29, -29, -30, -30, -29, -28, -27, -25, -23, -20, -16, -14, -11, -9,
602 -8, -8, -7, -7, -7, -5, -4, -4, -4, -3, -3, -3, -3, -4, -4, -4, -5, -5, -4, -4,
603 -4, -3, -2, -1, 1, 2, 3, 5, 7, 8, 10, 11, 13, 14, 15, 17, 19, 20, 21, 22, 24,
604 24, 25, 25, 24, 24, 22, 21, 19, 17, 15, 13, 10, 8, 5, 2, 0, -2, -5, -8, -11,
605 -14, -16, -18, -20, -23, -25, -27, -29, -30, -30, -31, -30, -29, -28, -26, -23,
606 -21, -18, -16, -17, -16, -18, -16, -11, -11, -12, -13, -10, -6, -5, -5, -7, -6,
607 -4, -2, -2, -2, -2, 0, 2, 3, 4, 5, 7, 8, 10, 10, 11, 12, 13, 14, 15, 16, 16, 17,
608 19, 20, 20, 21, 21, 21, 21, 20, 20, 19, 17, 16, 14, 12, 11, 9, 7, 5, 3, 1, -1,
609 -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -22, -23, -24, -25, -25, -24, -23,
610 -22, -20, -19, -17, -16, -16, -16, -16, -16, -16, -15, -14, -13, -13, -13, -12,
611 -11, -10, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 2, 4, 5, 6, 8, 10, 11, 13, 14,
612 16, 18, 20, 21, 23, 24, 25, 26, 26, 26, 26, 25, 24, 23, 22, 20, 17, 15, 13, 11,
613 8, 6, 4, 1, -1, -4, -6, -9, -11, -13, -16, -18, -20, -22, -24, -25, -26, -27,
614 -26, -26, -24, -23, -21, -20, -19, -19, -19, -19, -18, -18, -18, -17, -16, -15,
615 -14, -13, -12, -11, -10, -9, -7, -6, -5, -3, -1, 0, 2, 4, 5, 7, 8, 10, 11, 12,
616 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 22, 22, 21, 20, 20, 19, 17, 16, 15,
617 13, 12, 10, 8, 6, 4, 2, 0, -2, -4, -5, -8, -10, -12, -14, -16, -18, -19, -21,
618 -22, -23, -23, -22, -21, -21, -20, -19, -18, -18, -19, -20, -21, -21, -21, -20,
619 -19, -18, -18, -17, -16, -14, -12, -11, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10,
620 12, 14, 15, 17, 19, 20, 22, 23, 25, 26, 26, 27, 28, 28, 27, 27, 26, 25, 23, 21,
621 19, 17, 15, 12, 10, 8, 5, 2, 0, -3, -5, -8, -11, -13, -16, -18, -20, -22, -24,
622 -26, -27, -27, -28, -28, -27, -25, -23, -21, -20, -19, -18, -18, -20, -19, -18,
623 -18, -17, -16, -15, -14, -13, -11, -9, -8, -6, -5, -3, -1, 0, 2, 4, 6, 8, 9, 11,
624 13, 14, 15, 16, 18, 19, 20, 21, 21, 22, 22, 23, 23, 22, 22, 22, 21, 19, 18, 17,
625 16, 14, 12, 11, 9, 7, 5, 3, 1, -2, -5, -7, -10, -13, -15, -18, -20, -23, -25,
626 -26, -27, -28, -27, -26, -25, -23, -22, -20, -20, -21, -22, -24, -24, -24, -24,
627 -23, -22, -21, -20, -18, -15, -13, -11, -9, -7, -5, -3, -1, 2, 4, 6, 8, 10, 12,
628 14, 16, 18, 19, 20, 22, 23, 25, 26, 26, 27, 27, 27, 27, 27, 25, 24, 23, 21, 19,
629 17, 14, 12, 10, 7, 4, 2, 0, -3, -5, -8, -10, -13, -16, -18, -20, -23, -25, -27,
630 -28, -30, -31, -31, -30, -29, -27, -25, -23, -21, -21, -21, -22, -22, -22, -22,
631 -21, -20, -18, -17, -15, -13, -10, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13,
632 15, 17, 18, 20, 21, 22, 24, 25, 26, 27, 27, 27, 27, 27, 26, 25, 23, 22, 20, 18,
633 16, 14, 12, 9, 6, 4, 1, -1, -4, -7, -9, -13, -15, -18, -20, -22, -26, -27, -29,
634 -30, -31, -31, -30, -29, -27, -25, -23, -20, -19, -19, -18, -18, -18, -19, -20,
635 -19, -19, -18, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 4, 5, 7, 9, 11, 13,
636 16, 17, 19, 21, 23, 25, 26, 28, 29, 30, 30, 30, 30, 30, 28, 27, 26, 23, 22, 19,
637 16, 15, 12, 8, 5, 3, 0, -3, -6, -9, -12, -15, -19, -22, -24, -27, -30, -32, -33,
638 -34, -35, -35, -34, -33, -31, -29, -26, -23, -21, -20, -20, -19, -19, -19, -18,
639 -17, -17, -16, -15, -12, -10, -7, -5, -3, 0, 2, 4, 7, 9, 10, 12, 14, 15, 17, 19,
640 21, 22, 24, 25, 26, 28, 28, 29, 29, 28, 28, 27, 26, 25, 22, 20, 18, 16, 13, 10,
641 8, 5, 3, -1, -3, -5, -7, -10, -12, -15, -17, -20, -22, -24, -26, -29, -31, -33,
642 -34, -35, -35, -34, -33, -32, -30, -27, -23, -21, -20, -20, -19, -19, -19, -19,
643 -18, -17, -16, -15, -13, -10, -8, -5, -4, -1, 1, 3, 5, 7, 9, 11, 12, 14, 16, 18,
644 20, 21, 23, 24, 26, 28, 29, 30, 30, 30, 30, 29, 29, 27, 26, 23, 21, 18, 15, 12,
645 9, 5, 2, -1, -4, -7, -10, -13, -16, -19, -22, -25, -26, -28, -31, -33, -35, -36,
646 -37, -38, -37, -37, -36, -34, -32, -28, -25, -23, -21, -20, -19, -18, -17, -17,
647 -16, -16, -15, -14, -11, -9, -6, -4, -2, 1, 3, 5, 8, 10, 12, 14, 15, 17, 19, 21,
648 23, 25, 26, 27, 29, 30, 31, 32, 32, 32, 31, 30, 29, 28, 25, 22, 19, 16, 13, 10,
649 7, 4, 0, -3, -6, -8, -11, -14, -16, -19, -21, -23, -26, -27, -29, -31, -34, -35,
650 -35, -36, -36, -36, -36, -34, -32, -29, -26, -23, -22, -20, -19, -18, -17, -17,
651 -16, -16, -15, -14, -13, -11, -8, -6, -3, -1, 1, 4, 6, 9, 11, 12, 14, 15, 17,
652 19, 21, 23, 24, 26, 27, 29, 31, 32, 33, 33, 34, 32, 32, 30, 28, 27, 24, 20, 18,
653 15, 11, 9, 4, 1, -2, -6, -9, -11, -15, -18, -20, -23, -26, -28, -31, -33, -35,
654 -38, -39, -39, -40, -40, -40, -40, -37, -34, -32, -28, -25, -23, -21, -21, -19,
655 -18, -17, -17, -16, -14, -14, -12, -9, -7, -4, -2, 1, 4, 6, 9, 11, 12, 14, 15,
656 17, 19, 20, 22, 23, 24, 26, 27, 29, 30, 31, 32, 32, 32, 31, 30, 29, 27, 24, 21,
657 18, 15, 12, 9, 6, 2, -1, -4, -6, -9, -12, -13, -16, -19, -21, -23, -25, -28,
658 -30, -33, -35, -36, -38, -39, -39, -38, -38, -37, -35, -32, -29, -27, -24, -23,
659 -21, -20, -20, -19, -18, -18, -17, -16, -15, -12, -10, -8, -5, -2, 1, 3, 6, 8,
660 10, 12, 14, 15, 17, 19, 21, 22, 24, 26, 27, 29, 31, 32, 32, 33, 33, 32, 32, 30,
661 28, 27, 23, 20, 17, 13, 10, 7, 3, 0, -4, -6, -8, -11, -13, -15, -17, -19, -22,
662 -24, -27, -29, -32, -34, -36, -37, -38, -39, -39, -39, -38, -37, -34, -32, -29,
663 -26, -25, -22, -21, -20, -19, -19, -18, -17, -16, -14, -12, -9, -7, -4, -1, 2,
664 4, 7, 9, 11, 13, 14, 16, 18, 20, 22, 24, 25, 27, 28, 29, 31, 32, 33, 33, 34, 32,
665 31, 30, 28, 25, 23, 20, 16, 14, 10, 6, 4, 0, -3, -5, -8, -10, -12, -14, -16,
666 -19, -21, -23, -25, -27, -30, -32, -34, -35, -36, -37, -37, -37, -36, -35, -34,
667 -31, -28, -27, -25, -23, -22, -20, -20, -19, -18, -17, -16, -15, -12, -9, -6,
668 -3, 0, 3, 6, 7, 10, 12, 14, 16, 17, 19, 21, 23, 24, 26, 28, 29, 31, 32, 32, 33,
669 33, 32, 32, 30, 29, 26, 23, 22, 17, 14, 12, 8, 6, 3, -1, -2, -6, -9, -10, -13,
670 -15, -17, -20, -22, -24, -26, -28, -30, -32, -33, -34, -35, -36, -36, -36, -35,
671 -34, -32, -30, -28, -27, -25, -24, -23, -22, -22, -22, -20, -19, -17, -15, -12,
672 -9, -7, -4, -1, 2, 5, 7, 9, 12, 14, 16, 18, 21, 23, 25, 27, 29, 31, 32, 34, 35,
673 36, 36, 35, 34, 33, 32, 30, 26, 24, 20, 16, 14, 11, 7, 6, 3, -1, -2, -5, -8, -9,
674 -12, -15, -16, -20, -22, -23, -26, -28, -28, -31, -32, -33, -35, -34, -34, -35,
675 -34, -33, -32, -30, -28, -27, -25, -23, -22, -21, -20, -20, -19, -18, -17, -15,
676 -12, -10, -6, -4, -1, 2, 4, 7, 9, 11, 14, 15, 17, 19, 22, 23, 26, 28, 30, 31,
677 33, 34, 35, 35, 35, 35, 34, 32, 31, 28, 25, 23, 19, 17, 15, 12, 9, 8, 5, 3, 1,
678 -2, -5, -7, -11, -14, -15, -19, -21, -22, -25, -27, -28, -31, -31, -32, -34,
679 -34, -34, -35, -34, -33, -32, -30, -29, -28, -27, -25, -25, -24, -23, -23, -21,
680 -20, -18, -15, -13, -11, -7, -5, -2, 1, 3, 6, 8, 10, 13, 15, 17, 20, 23, 24, 27,
681 30, 32, 34, 35, 36, 38, 38, 37, 37, 35, 35, 32, 29, 27, 24, 20, 19, 16, 13, 13,
682 10, 7, 6, 2, -1, -3, -7, -10, -12, -16, -18, -19, -22, -24, -25, -28, -29, -30,
683 -31, -32, -33, -34, -34, -34, -34, -33, -32, -31, -29, -28, -28, -26, -26, -26,
684 -24, -24, -22, -20, -18, -16, -13, -11, -8, -5, -3, 0, 2, 4, 6, 9, 10, 13, 15,
685 18, 21, 23, 26, 29, 31, 33, 35, 36, 37, 37, 37, 37, 35, 33, 31, 28, 25, 23, 19,
686 18, 17, 14, 13, 12, 8, 7, 4, 0, -3, -6, -9, -11, -14, -17, -19, -21, -24, -25,
687 -27, -29, -30, -31, -33, -34, -35, -36, -36, -36, -36, -35, -34, -34, -33, -32,
688 -31, -30, -29, -29, -27, -25, -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 3, 4,
689 7, 9, 11, 14, 17, 19, 22, 25, 26, 31, 32, 35, 36, 36, 37, 37, 36, 35, 34, 32,
690 29, 26, 23, 22, 20, 18, 17, 16, 14, 12, 10, 7, 4, 1, -3, -5, -8, -11, -14, -16,
691 -18, -20, -22, -23, -25, -26, -27, -28, -30, -31, -32, -33, -34, -34, -34, -34,
692 -34, -33, -32, -31, -30, -29, -28, -27, -25, -23, -21, -18, -16, -13, -10, -8,
693 -6, -3, -1, 1, 3, 5, 8, 10, 12, 15, 17, 20, 23, 26, 29, 31, 33, 35, 37, 37, 38,
694 38, 37, 36, 35, 33, 30, 28, 26, 23, 22, 21, 20, 19, 17, 15, 14, 10, 7, 4, 0, -3,
695 -6, -9, -12, -14, -17, -19, -20, -22, -24, -25, -26, -27, -28, -30, -31, -32,
696 -34, -35, -35, -35, -35, -34, -34, -32, -30, -29, -27, -25, -24, -22, -20, -18,
697 -16, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 10, 12, 14, 17, 20, 23, 25, 28,
698 31, 33, 35, 36, 37, 38, 37, 37, 35, 34, 32, 30, 27, 25, 24, 22, 21, 20, 20, 17,
699 16, 14, 10, 7, 3, -2, -5, -7, -11, -13, -15, -18, -20, -22, -24, -24, -26, -27,
700 -28, -29, -30, -31, -33, -34, -35, -36, -36, -36, -36, -35, -34, -32, -30, -28,
701 -26, -23, -21, -20, -18, -16, -14, -12, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 10,
702 12, 15, 18, 21, 23, 26, 29, 31, 34, 35, 36, 37, 38, 36, 36, 35, 32, 30, 29, 26,
703 23, 22, 20, 20, 19, 18, 16, 14, 11, 8, 4, 0, -5, -8, -12, -16, -17, -20, -22,
704 -23, -25, -26, -27, -27, -28, -29, -29, -31, -31, -33, -34, -35, -37, -37, -38,
705 -38, -37, -35, -34, -31, -28, -25, -22, -19, -17, -15, -14, -13, -12, -10, -9,
706 -7, -6, -4, -1, 0, 3, 5, 7, 10, 12, 15, 18, 22, 25, 27, 31, 33, 34, 36, 37, 38,
707 38, 37, 36, 36, 33, 30, 29, 26, 23, 22, 21, 19, 19, 18, 16, 14, 11, 8, 3, -1,
708 -6, -10, -13, -16, -19, -20, -21, -23, -23, -24, -24, -24, -25, -26, -26, -27,
709 -29, -30, -32, -34, -35, -37, -37, -37, -37, -36, -34, -32, -29, -25, -21, -17,
710 -14, -13, -11, -10, -10, -10, -9, -8, -7, -5, -3, 0, 3, 6, 8, 11, 14, 17, 19,
711 23, 26, 28, 31, 34, 35, 37, 38, 38, 39, 39, 38, 37, 36, 34, 31, 29, 26, 24, 21,
712 19, 17, 16, 14, 12, 10, 7, 3, -1, -5, -9, -12, -16, -18, -19, -20, -20, -21,
713 -21, -21, -22, -22, -23, -24, -25, -26, -28, -29, -30, -33, -34, -35, -36, -36,
714 -36, -35, -34, -32, -30, -27, -24, -20, -17, -15, -12, -10, -10, -9, -8, -8, -7,
715 -6, -5, -2, 1, 4, 8, 12, 15, 18, 20, 23, 26, 28, 30, 32, 34, 36, 37, 38, 39, 40,
716 40, 39, 38, 37, 35, 33, 30, 28, 24, 20, 17, 14, 12, 10, 8, 7, 5, 2, -1, -5, -9,
717 -12, -16, -19, -19, -21, -21, -21, -22, -21, -23, -24, -24, -26, -26, -28, -29,
718 -31, -32, -34, -35, -36, -38, -38, -37, -37, -35, -32, -30, -28, -25, -23, -19,
719 -17, -14, -11, -10, -7, -6, -5, -3, -2, -1, 1, 4, 7, 11, 14, 18, 21, 23, 26, 28,
720 30, 32, 34, 36, 37, 38, 39, 41, 40, 41, 40, 39, 39, 37, 36, 33, 30, 27, 22, 17,
721 14, 9, 6, 4, 3, 2, 1, -2, -5, -7, -11, -16, -19, -22, -23, -25, -25, -25, -25,
722 -26, -27, -27, -28, -29, -31, -32, -32, -34, -35, -35, -37, -38, -39, -40, -39,
723 -37, -35, -33, -29, -27, -24, -21, -18, -16, -13, -11, -8, -5, -3, 0, 2, 4, 6,
724 8, 10, 14, 17, 20, 24, 27, 29, 32, 34, 36, 38, 39, 40, 42, 43, 44, 45, 45, 45,
725 44, 43, 42, 38, 39, 36, 28, 29, 21, 16, 14, 5, 0, -2, -6, -9, -7, -10, -12, -11,
726 -15, -19, -21, -26, -30, -30, -32, -33, -30, -30, -30, -29, -30, -32, -32, -34,
727 -35, -35, -36, -36, -35, -37, -38, -37, -38, -37, -35, -33, -29, -25, -22, -18,
728 -15, -13, -10, -8, -6, -3, -1, 2, 6, 8, 10, 13, 15, 18, 22, 24, 27, 31, 33, 37,
729 40, 41, 43, 45, 45, 46, 48, 49, 49, 50, 50, 49, 48, 46, 43, 40, 36, 32, 27, 22,
730 17, 11, 5, -1, -7, -11, -16, -19, -19, -21, -21, -22, -24, -27, -28, -32, -36,
731 -36, -38, -38, -36, -35, -34, -33, -34, -35, -35, -36, -38, -38, -38, -37, -37,
732 -37, -36, -36, -34, -34, -33, -29, -25, -22, -18, -14, -11, -7, -5, -3, 0, 2, 4,
733 7, 10, 13, 17, 21, 24, 27, 30, 32, 35, 38, 40, 43, 45, 47, 49, 50, 50, 51, 52,
734 52, 52, 52, 51, 50, 48, 44, 40, 37, 31, 26, 21, 14, 8, 2, -5, -11, -15, -23,
735 -25, -26, -28, -29, -29, -30, -31, -32, -38, -39, -41, -46, -45, -44, -43, -40,
736 -38, -39, -37, -37, -40, -38, -40, -40, -37, -38, -36, -34, -33, -33, -30, -29,
737 -27, -22, -20, -15, -10, -5, -1, 2, 4, 7, 9, 11, 14, 17, 20, 24, 27, 30, 34, 36,
738 38, 41, 43, 45, 48, 50, 51, 54, 55, 55, 55, 55, 54, 53, 52, 50, 49, 47, 43, 39,
739 36, 30, 24, 21, 14, 7, 3, -4, -11, -14, -21, -28, -29, -35, -41, -41, -44, -47,
740 -45, -48, -48, -46, -48, -48, -47, -47, -47, -46, -46, -44, -43, -43, -41, -39,
741 -39, -37, -36, -34, -32, -30, -28, -25, -23, -19, -15, -12, -7, -4, 0, 4, 8, 10,
742 14, 17, 19, 22, 25, 27, 31, 34, 35, 38, 41, 42, 45, 47, 48, 50, 51, 52, 52, 53,
743 54, 52, 52, 52, 50, 49, 48, 44, 42, 40, 34, 31, 27, 20, 15, 10, 4, -3, -8, -16,
744 -21, -27, -35, -39, -44, -48, -51, -54, -56, -56, -58, -59, -58, -57, -56, -54,
745 -54, -54, -51, -50, -48, -44, -42, -39, -36, -35, -32, -30, -29, -27, -24, -22,
746 -17, -14, -11, -4, 0, 2, 7, 9, 12, 16, 18, 20, 25, 27, 29, 33, 35, 36, 38, 40,
747 41, 43, 45, 47, 49, 50, 51, 52, 51, 51, 51, 50, 48, 47, 47, 45, 44, 42, 39, 37,
748 33, 27, 23, 19, 12, 7, 3, -5, -11, -15, -24, -28, -33, -43, -46, -49, -56, -58,
749 -59, -64, -62, -62, -66, -63, -61, -62, -59, -55, -55, -51, -47, -47, -41, -39,
750 -38, -33, -30, -29, -25, -21, -19, -14, -11, -8, -3, 1, 5, 8, 13, 17, 19, 23,
751 26, 28, 32, 33, 35, 38, 40, 41, 44, 46, 47, 49, 51, 51, 53, 53, 52, 53, 53, 51,
752 51, 50, 48, 46, 45, 43, 41, 39, 36, 33, 29, 25, 20, 15, 11, 4, -2, -7, -13, -22,
753 -26, -32, -40, -44, -50, -55, -56, -60, -65, -64, -66, -70, -68, -67, -68, -65,
754 -63, -61, -57, -53, -51, -47, -42, -40, -35, -32, -27, -23, -20, -16, -12, -8,
755 -4, 1, 6, 12, 17, 21, 26, 29, 32, 35, 37, 40, 42, 43, 46, 49, 49, 52, 54, 54,
756 55, 56, 55, 56, 56, 54, 54, 54, 51, 50, 49, 45, 43, 42, 38, 35, 34, 30, 26, 25,
757 19, 14, 10, 4, -2, -7, -14, -20, -24, -31, -37, -41, -47, -52, -58, -60, -64,
758 -68, -69, -71, -71, -73, -72, -72, -71, -69, -68, -64, -61, -57, -53, -48, -43,
759 -38, -33, -29, -23, -18, -15, -9, -4, 2, 6, 13, 19, 24, 29, 33, 38, 41, 44, 47,
760 49, 51, 53, 55, 56, 58, 59, 60, 60, 60, 60, 59, 59, 58, 56, 55, 53, 51, 49, 46,
761 43, 40, 37, 33, 30, 26, 22, 18, 14, 9, 4, -2, -8, -12, -19, -25, -30, -36, -43,
762 -46, -53, -57, -59, -66, -70, -70, -74, -78, -76, -77, -77, -75, -74, -73, -68,
763 -66, -65, -59, -54, -51, -46, -40, -36, -30, -25, -20, -13, -8, -2, 4, 10, 17,
764 23, 28, 34, 40, 43, 46, 51, 53, 54, 57, 59, 59, 62, 63, 63, 66, 65, 64, 65, 65,
765 62, 61, 60, 57, 54, 52, 49, 46, 43, 39, 35, 32, 28, 23, 19, 16, 10, 4, 0, -7,
766 -14, -19, -26, -33, -37, -44, -50, -54, -58, -63, -68, -70, -74, -77, -79, -80,
767 -81, -81, -80, -80, -78, -75, -72, -69, -64, -59, -56, -50, -44, -39, -34, -29,
768 -21, -15, -9, -2, 4, 11, 19, 25, 30, 37, 43, 47, 52, 56, 59, 62, 64, 65, 67, 68,
769 69, 70, 71, 71, 70, 71, 70, 68, 66, 64, 61, 58, 55, 51, 48, 45, 40, 36, 33, 28,
770 23, 18, 13, 9, 2, -3, -9, -16, -21, -29, -37, -41, -45, -55, -60, -62, -67, -73,
771 -76, -77, -80, -81, -84, -85, -83, -82, -84, -82, -76, -75, -73, -67, -62, -58,
772 -52, -47, -42, -34, -29, -23, -15, -8, 0, 6, 14, 23, 29, 35, 44, 49, 52, 59, 62,
773 65, 69, 71, 72, 75, 78, 77, 78, 81, 79, 78, 78, 77, 74, 72, 69, 64, 62, 57, 52,
774 49, 44, 38, 34, 30, 24, 19, 14, 9, 3, -4, -10, -17, -24, -30, -37, -46, -50,
775 -55, -66, -66, -72, -78, -80, -84, -88, -89, -89, -91, -91, -90, -88, -88, -86,
776 -78, -78, -73, -66, -64, -55, -50, -44, -38, -29, -23, -17, -9, -2, 7, 15, 22,
777 31, 37, 44, 52, 57, 61, 68, 70, 73, 77, 77, 79, 82, 82, 82, 82, 83, 82, 80, 79,
778 77, 73, 70, 67, 61, 58, 53, 47, 44, 38, 32, 28, 23, 17, 11, 5, -1, -8, -15, -21,
779 -27, -35, -39, -48, -54, -56, -65, -69, -72, -77, -81, -85, -88, -89, -90, -91,
780 -91, -93, -87, -87, -87, -79, -76, -73, -66, -62, -55, -48, -42, -36, -29, -21,
781 -15, -9, 1, 9, 16, 25, 32, 41, 47, 54, 61, 65, 70, 72, 74, 78, 79, 80, 82, 82,
782 82, 83, 82, 82, 80, 78, 76, 72, 69, 65, 59, 56, 51, 45, 41, 36, 32, 26, 22, 18,
783 12, 6, 0, -5, -11, -19, -24, -31, -38, -42, -49, -56, -58, -62, -70, -72, -73,
784 -80, -81, -83, -87, -86, -86, -88, -87, -84, -82, -80, -78, -69, -67, -65, -54,
785 -51, -46, -35, -33, -27, -18, -13, -6, 1, 10, 18, 24, 34, 41, 47, 56, 61, 65,
786 69, 72, 74, 75, 78, 78, 77, 80, 78, 77, 79, 77, 76, 74, 71, 68, 65, 61, 57, 52,
787 48, 42, 37, 34, 29, 24, 21, 17, 13, 7, 2, -2, -9, -15, -21, -28, -34, -39, -47,
788 -52, -54, -61, -66, -68, -72, -75, -79, -80, -82, -85, -83, -86, -87, -83, -82,
789 -82, -76, -72, -68, -63, -57, -51, -46, -38, -32, -29, -20, -15, -10, -1, 4, 12,
790 19, 27, 35, 41, 51, 57, 60, 67, 70, 72, 75, 76, 76, 76, 76, 76, 74, 75, 75, 72,
791 72, 70, 66, 65, 60, 56, 53, 47, 42, 37, 33, 30, 25, 21, 18, 14, 10, 5, 1, -3,
792 -9, -15, -21, -26, -32, -38, -43, -50, -53, -56, -64, -65, -69, -72, -74, -79,
793 -81, -79, -83, -85, -81, -83, -79, -79, -76, -70, -68, -62, -58, -51, -44, -40,
794 -33, -28, -20, -17, -11, -2, 3, 8, 17, 24, 30, 40, 45, 52, 59, 62, 66, 68, 72,
795 73, 71, 73, 73, 72, 71, 71, 70, 69, 67, 65, 62, 61, 58, 53, 51, 46, 41, 38, 33,
796 30, 27, 23, 21, 18, 15, 12, 8, 4, -2, -7, -12, -18, -24, -29, -33, -39, -44,
797 -48, -52, -56, -60, -65, -66, -72, -75, -77, -80, -80, -83, -83, -80, -79, -78,
798 -72, -69, -63, -58, -56, -47, -43, -38, -32, -27, -20, -16, -11, -4, 3, 10, 16,
799 24, 33, 39, 46, 53, 58, 65, 66, 68, 71, 70, 71, 70, 69, 70, 68, 67, 67, 66, 65,
800 64, 61, 58, 55, 51, 46, 42, 38, 32, 30, 26, 24, 21, 20, 19, 17, 16, 13, 10, 7,
801 1, -5, -9, -15, -21, -26, -30, -33, -39, -42, -42, -51, -53, -53, -62, -65, -67,
802 -72, -76, -78, -78, -80, -79, -77, -74, -71, -66, -61, -58, -51, -45, -43, -39,
803 -30, -27, -24, -17, -14, -8, 0, 3, 11, 20, 27, 35, 41, 49, 55, 58, 62, 64, 64,
804 64, 65, 64, 62, 63, 62, 61, 63, 61, 60, 61, 59, 55, 52, 48, 45, 39, 33, 30, 25,
805 22, 20, 18, 18, 19, 18, 16, 15, 13, 9, 5, -1, -8, -11, -18, -24, -27, -31, -35,
806 -38, -41, -43, -45, -51, -54, -56, -64, -68, -72, -77, -77, -82, -81, -79, -77,
807 -73, -70, -64, -58, -53, -49, -44, -38, -34, -30, -26, -21, -18, -12, -9, -2, 5,
808 11, 20, 25, 34, 42, 47, 53, 57, 59, 61, 61, 59, 59, 59, 58, 56, 56, 56, 56, 57,
809 56, 56, 55, 52, 49, 44, 40, 35, 29, 24, 20, 18, 17, 17, 17, 18, 19, 19, 18, 16,
810 14, 9, 3, -4, -8, -15, -21, -24, -28, -31, -33, -36, -38, -40, -41, -47, -53,
811 -55, -63, -70, -71, -77, -81, -79, -79, -79, -75, -67, -64, -59, -50, -48, -43,
812 -37, -35, -32, -28, -24, -22, -18, -13, -7, 0, 8, 15, 24, 33, 40, 47, 52, 57,
813 58, 58, 58, 56, 57, 56, 54, 54, 55, 55, 56, 57, 57, 57, 56, 53, 48, 44, 38, 31,
814 26, 20, 16, 14, 13, 14, 16, 17, 19, 21, 20, 19, 16, 13, 7, 0, -7, -12, -17, -22,
815 -24, -27, -28, -28, -29, -33, -33, -36, -44, -49, -57, -62, -68, -74, -77, -80,
816 -78, -76, -74, -69, -61, -56, -52, -47, -42, -38, -36, -33, -32, -29, -25, -22,
817 -19, -12, -4, 2, 10, 19, 27, 34, 41, 46, 49, 52, 53, 52, 50, 51, 50, 49, 50, 50,
818 51, 53, 55, 55, 55, 55, 52, 49, 44, 39, 33, 28, 24, 19, 17, 19, 20, 21, 24, 26,
819 28, 28, 28, 25, 20, 16, 9, 0, -5, -10, -15, -17, -19, -21, -22, -22, -26, -31,
820 -30, -38, -46, -53, -62, -66, -75, -81, -80, -81, -81, -76, -74, -67, -59, -58,
821 -52, -47, -44, -42, -41, -37, -34, -31, -29, -23, -15, -10, -2, 6, 15, 24, 29,
822 35, 42, 46, 48, 49, 50, 51, 50, 50, 49, 52, 54, 53, 55, 56, 57, 56, 54, 52, 49,
823 44, 39, 33, 28, 24, 20, 19, 18, 19, 21, 22, 25, 26, 26, 27, 24, 21, 16, 11, 6,
824 -1, -6, -9, -12, -15, -16, -16, -18, -20, -25, -28, -31, -40, -47, -54, -62,
825 -68, -74, -79, -78, -79, -78, -74, -70, -65, -61, -56, -53, -49, -46, -45, -41,
826 -38, -35, -31, -27, -20, -13, -8, 0, 9, 16, 22, 28, 34, 38, 42, 44, 45, 48, 48,
827 48, 49, 50, 52, 52, 53, 54, 54, 54, 53, 50, 48, 44, 41, 36, 32, 29, 23, 21, 20,
828 19, 19, 20, 22, 23, 24, 25, 24, 23, 21, 18, 14, 10, 6, 0, -4, -5, -9, -10, -11,
829 -13, -15, -19, -24, -27, -33, -41, -48, -56, -60, -67, -73, -73, -74, -75, -72,
830 -70, -67, -61, -59, -56, -52, -48, -46, -44, -40, -37, -33, -28, -23, -15, -10,
831 -3, 3, 9, 17, 20, 25, 32, 34, 37, 40, 42, 45, 46, 48, 50, 51, 52, 52, 53, 53,
832 52, 51, 49, 47, 44, 40, 38, 34, 31, 29, 25, 24, 22, 21, 21, 21, 23, 23, 23, 25,
833 23, 22, 21, 18, 15, 11, 8, 3, 0, -2, -6, -8, -10, -14, -17, -20, -25, -31, -36,
834 -42, -49, -56, -62, -65, -70, -74, -73, -74, -72, -70, -68, -63, -60, -56, -53,
835 -50, -45, -43, -39, -35, -30, -24, -20, -13, -7, -2, 5, 9, 15, 20, 25, 30, 32,
836 37, 40, 41, 46, 46, 48, 50, 49, 51, 50, 50, 50, 48, 48, 45, 42, 40, 37, 36, 33,
837 30, 28, 25, 24, 22, 20, 21, 20, 22, 22, 23, 23, 23, 23, 23, 21, 19, 16, 13, 8,
838 5, 2, -2, -4, -7, -10, -13, -16, -21, -28, -30, -36, -45, -48, -56, -62, -64,
839 -71, -71, -72, -73, -70, -70, -66, -61, -59, -55, -51, -47, -44, -39, -35, -32,
840 -25, -21, -17, -8, -5, 2, 8, 12, 18, 22, 28, 31, 34, 39, 40, 44, 46, 46, 49, 48,
841 49, 50, 47, 49, 47, 45, 44, 42, 40, 37, 35, 33, 30, 29, 26, 23, 21, 19, 19, 18,
842 18, 19, 19, 21, 22, 23, 24, 23, 23, 21, 19, 17, 13, 10, 6, 4, 0, -3, -4, -8,
843 -12, -15, -21, -25, -30, -38, -44, -50, -56, -60, -65, -68, -69, -70, -70, -67,
844 -65, -62, -59, -57, -53, -49, -46, -42, -38, -33, -28, -22, -17, -12, -6, -1, 4,
845 8, 13, 18, 21, 26, 29, 32, 36, 39, 42, 45, 46, 48, 48, 49, 48, 46, 46, 45, 43,
846 41, 39, 37, 35, 34, 32, 29, 28, 26, 23, 21, 20, 19, 18, 18, 19, 20, 21, 22, 23,
847 24, 25, 25, 24, 23, 20, 17, 14, 10, 7, 3, 0, -3, -8, -10, -14, -21, -24, -29,
848 -36, -42, -47, -55, -60, -63, -69, -71, -72, -72, -72, -69, -66, -63, -60, -54,
849 -52, -48, -43, -39, -35, -30, -24, -20, -15, -9, -4, 1, 6, 11, 15, 19, 25, 28,
850 32, 36, 38, 41, 44, 46, 47, 47, 47, 47, 45, 45, 44, 43, 40, 40, 37, 34, 33, 31,
851 28, 27, 24, 22, 20, 18, 17, 16, 17, 17, 19, 21, 22, 24, 25, 26, 27, 26, 25, 24,
852 21, 18, 14, 11, 9, 5, 2, -1, -5, -8, -14, -18, -24, -30, -35, -45, -50, -55,
853 -64, -68, -72, -75, -75, -76, -74, -72, -69, -65, -63, -57, -54, -49, -45, -42,
854 -36, -33, -27, -21, -17, -8, -3, 2, 10, 13, 19, 24, 28, 33, 35, 39, 42, 43, 48,
855 48, 50, 51, 52, 52, 50, 49, 48, 45, 44, 40, 38, 35, 31, 29, 25, 24, 21, 18, 18,
856 15, 14, 13, 13, 14, 14, 17, 19, 20, 23, 24, 25, 26, 26, 27, 25, 25, 22, 18, 17,
857 13, 11, 7, 4, 1, -5, -9, -14, -21, -28, -34, -43, -50, -55, -61, -68, -71, -73,
858 -76, -76, -74, -74, -71, -68, -65, -63, -59, -54, -52, -46, -40, -34, -28, -20,
859 -13, -7, 0, 7, 11, 17, 23, 26, 29, 34, 36, 38, 41, 45, 48, 50, 53, 53, 54, 53,
860 51, 48, 46, 43, 39, 35, 32, 29, 25, 23, 21, 20, 19, 18, 16, 14, 14, 11, 10, 11,
861 11, 12, 14, 17, 19, 21, 25, 27, 29, 31, 32, 31, 29, 27, 23, 19, 17, 13, 11, 7,
862 3, -1, -6, -11, -19, -25, -30, -41, -48, -56, -64, -70, -77, -78, -80, -82, -79,
863 -79, -77, -73, -69, -66, -62, -55, -51, -47, -40, -36, -28, -21, -14, -5, 1, 9,
864 14, 20, 27, 29, 34, 37, 39, 41, 41, 43, 44, 46, 48, 48, 49, 48, 47, 45, 42, 40,
865 36, 31, 28, 23, 20, 15, 12, 10, 8, 8, 6, 6, 5, 4, 3, 3, 3, 6, 8, 11, 14, 17, 20,
866 24, 28, 31, 34, 37, 38, 38, 36, 34, 32, 28, 26, 23, 19, 15, 9, 5, -3, -10, -16,
867 -25, -33, -41, -51, -59, -66, -74, -79, -81, -83, -84, -82, -81, -79, -75, -73,
868 -68, -64, -58, -53, -50, -42, -35, -30, -22, -13, -4, 4, 11, 17, 22, 27, 29, 32,
869 35, 35, 36, 37, 37, 40, 41, 44, 47, 48, 49, 47, 45, 41, 38, 33, 27, 23, 17, 12,
870 9, 5, 4, 3, 4, 4, 4, 5, 3, 2, 1, 0, 2, 4, 7, 11, 15, 20, 25, 31, 38, 44, 48, 51,
871 53, 52, 49, 47, 43, 39, 36, 32, 29, 24, 20, 14, 6, 2, -5, -16, -22, -34, -46,
872 -55, -66, -74, -80, -85, -88, -89, -88, -89, -86, -82, -79, -74, -70, -65, -61,
873 -58, -52, -47, -41, -32, -25, -15, -6, 2, 10, 15, 22, 28, 31, 36, 37, 37, 36,
874 36, 37, 38, 42, 45, 47, 50, 49, 48, 46, 43, 40, 35, 30, 24, 17, 12, 6, 2, 2, 1,
875 2, 4, 4, 5, 4, 3, 2, 2, 5, 8, 10, 14, 19, 23, 28, 35, 42, 48, 54, 57, 59, 59,
876 57, 54, 51, 50, 47, 42, 38, 33, 28, 21, 15, 7, -1, -9, -20, -32, -43, -54, -65,
877 -75, -82, -87, -91, -95, -97, -97, -97, -96, -93, -89, -85, -81, -76, -72, -66,
878 -60, -53, -44, -35, -25, -15, -6, 3, 11, 19, 24, 30, 36, 38, 41, 42, 41, 42, 41,
879 41, 44, 47, 50, 51, 52, 51, 49, 46, 41, 38, 32, 25, 18, 11, 6, 1, -3, -4, -3,
880 -3, -3, -3, -5, -7, -8, -8, -8, -6, -2, 4, 9, 16, 25, 31, 38, 46, 53, 59, 62,
881 61, 62, 63, 61, 59, 58, 59, 58, 54, 52, 48, 42, 35, 26, 15, 5, -8, -24, -38,
882 -49, -62, -73, -80, -87, -91, -96, -99, -100, -102, -102, -103, -102, -98, -99,
883 -96, -91, -86, -78, -71, -59, -49, -37, -24, -16, -4, 6, 14, 22, 28, 35, 39, 41,
884 44, 46, 48, 49, 51, 52, 52, 57, 56, 56, 58, 54, 52, 48, 43, 37, 30, 24, 16, 11,
885 6, 2, -1, -4, -4, -4, -5, -4, -6, -6, -6, -8, -9, -9, -9, -8, -5, 1, 7, 14, 22,
886 29, 36, 42, 47, 50, 52, 54, 54, 54, 54, 52, 52, 52, 51, 51, 48, 43, 37, 30, 19,
887 10, 1, -14, -23, -33, -47, -52, -60, -69, -72, -77, -81, -84, -88, -92, -94,
888 -95, -97, -97, -93, -89, -83, -78, -70, -60, -53, -43, -33, -24, -14, -7, 0, 7,
889 13, 20, 24, 30, 35, 38, 42, 45, 47, 48, 49, 50, 48, 48, 48, 46, 45, 43, 40, 38,
890 34, 30, 25, 21, 18, 12, 8, 5, 1, -2, -4, -6, -7, -8, -9, -11, -10, -10, -12,
891 -12, -11, -9, -7, -1, 4, 9, 16, 20, 24, 30, 33, 37, 39, 41, 43, 45, 46, 47, 49,
892 52, 53, 54, 53, 51, 46, 38, 31, 22, 14, 6, -4, -12, -20, -30, -37, -42, -50,
893 -56, -57, -65, -72, -75, -83, -89, -90, -92, -92, -88, -87, -84, -75, -70, -64,
894 -55, -49, -40, -34, -28, -21, -18, -12, -8, -2, 4, 11, 17, 20, 26, 30, 32, 35,
895 35, 35, 32, 28, 27, 24, 25, 25, 25, 27, 27, 25, 24, 22, 20, 16, 13, 9, 4, 1, -5,
896 -7, -8, -9, -6, -5, -1, 3, 5, 8, 10, 12, 14, 16, 17, 21, 24, 27, 31, 37, 41, 46,
897 52, 57, 61, 64, 66, 67, 68, 68, 66, 64, 62, 58, 54, 48, 40, 31, 24, 14, 4, -4,
898 -14, -26, -36, -45, -54, -62, -68, -75, -80, -83, -90, -95, -96, -100, -100,
899 -100, -99, -94, -91, -86, -80, -72, -63, -58, -49, -40, -33, -26, -20, -14, -8,
900 -2, 4, 8, 16, 19, 20, 23, 24, 26, 25, 24, 24, 29, 35, 36, 41, 44, 43, 43, 39,
901 38, 35, 30, 26, 21, 17, 12, 7, 5, 5, 7, 6, 6, 6, 1, -1, -5, -10, -14, -18, -22,
902 -24, -23, -20, -16, -5, 6, 17, 29, 39, 45, 48, 51, 53, 54, 57, 57, 60, 66, 69,
903 72, 78, 87, 93, 96, 98, 94, 86, 73, 54, 37, 22, 6, -9, -20, -27, -37, -44, -51,
904 -57, -61, -65, -72, -80, -89, -100, -110, -121, -125, -127, -128, -121, -115,
905 -106, -94, -87, -75, -64, -56, -46, -40, -36, -33, -31, -28, -22, -15, -8, 4,
906 15, 23, 33, 37, 41, 45, 41, 42, 48, 47, 48, 49, 47, 46, 46, 44, 46, 49, 48, 46,
907 43, 38, 32, 24, 17, 14, 9, 4, 0, -7, -11, -14, -20, -22, -23, -24, -27, -28,
908 -30, -33, -33, -32, -28, -21, -11, -2, 6, 16, 24, 31, 40, 47, 53, 61, 67, 70,
909 73, 77, 81, 85, 91, 96, 100, 101, 99, 92, 84, 73, 59, 46, 35, 21, 8, -6, -19,
910 -31, -42, -51, -58, -65, -73, -81, -90, -100, -107, -116, -122, -122, -124,
911 -123, -119, -116, -108, -101, -98, -84, -74, -69, -58, -50, -45, -38, -34, -31,
912 -22, -14, -9, 0, 7, 12, 18, 20, 24, 28, 28, 34, 39, 43, 48, 49, 49, 49, 49, 47,
913 45, 45, 41, 38, 34, 28, 25, 19, 17, 16, 13, 12, 7, 4, 1, -6, -9, -13, -13, -13,
914 -13, -9, -6, -2, 2, 7, 14, 20, 27, 30, 35, 40, 41, 45, 49, 52, 59, 64, 70, 75,
915 79, 82, 83, 84, 82, 79, 75, 67, 58, 47, 36, 24, 12, 2, -7, -14, -23, -32, -40,
916 -49, -57, -65, -74, -81, -88, -96, -103, -107, -112, -114, -112, -110, -103,
917 -97, -91, -83, -77, -69, -61, -53, -43, -37, -30, -23, -18, -12, -7, 0, 8, 15,
918 22, 23, 28, 31, 29, 29, 27, 25, 20, 13, 10, 10, 13, 15, 17, 23, 26, 26, 25, 23,
919 23, 19, 14, 11, 8, 4, 0, -2, 0, 3, 7, 9, 14, 16, 16, 15, 9, 5, 2, -4, -7, -8,
920 -8, -8, -5, 1, 9, 18, 27, 35, 41, 44, 46, 46, 44, 44, 43, 45, 49, 51, 55, 60,
921 65, 70, 73, 76, 76, 72, 64, 54, 42, 28, 14, 3, -5, -12, -20, -25, -30, -35, -41,
922 -47, -53, -60, -68, -75, -84, -92, -100, -105, -106, -104, -102, -96, -86, -80,
923 -73, -67, -61, -53, -50, -44, -37, -35, -31, -29, -27, -20, -15, -10, -1, 7, 11,
924 15, 16, 15, 16, 12, 6, 3, -2, -3, 0, 3, 8, 14, 19, 24, 28, 29, 31, 30, 26, 23,
925 19, 14, 13, 11, 12, 16, 20, 25, 30, 34, 37, 38, 35, 31, 27, 22, 17, 12, 9, 8, 7,
926 8, 12, 17, 23, 28, 30, 33, 34, 33, 31, 28, 27, 27, 27, 28, 32, 36, 41, 46, 50,
927 54, 55, 53, 48, 41, 33, 23, 13, 5, -1, -5, -8, -12, -15, -16, -20, -24, -28,
928 -35, -42, -50, -59, -68, -74, -80, -85, -83, -82, -79, -72, -68, -64, -58, -56,
929 -53, -51, -47, -47, -45, -41, -41, -37, -33, -29, -21, -17, -11, -7, -2, 2, -1,
930 0, -2, -5, -9, -17, -19, -19, -17, -7, 0, 10, 20, 24, 27, 29, 30, 27, 25, 22,
931 17, 16, 11, 8, 11, 15, 22, 29, 35, 41, 43, 41, 38, 31, 23, 16, 11, 7, 6, 7, 8,
932 14, 20, 28, 39, 46, 51, 52, 51, 49, 45, 40, 37, 37, 41, 43, 47, 54, 60, 65, 68,
933 71, 71, 67, 58, 45, 33, 19, 5, -7, -15, -18, -21, -23, -26, -29, -32, -38, -44,
934 -52, -60, -69, -79, -86, -94, -99, -101, -100, -93, -89, -82, -73, -70, -64,
935 -58, -56, -50, -47, -45, -39, -36, -35, -31, -25, -23, -16, -8, -4, 3, 6, 8, 9,
936 6, 5, 1, -3, -6, -14, -17, -15, -14, -6, 3, 11, 19, 23, 25, 24, 24, 20, 16, 12,
937 8, 7, 3, 3, 9, 13, 21, 30, 36, 44, 47, 46, 43, 38, 32, 26, 23, 21, 22, 24, 27,
938 34, 40, 48, 57, 61, 64, 64, 60, 56, 50, 44, 40, 40, 41, 42, 45, 49, 53, 55, 56,
939 54, 50, 43, 31, 18, 5, -9, -21, -30, -35, -37, -38, -39, -40, -42, -45, -49,
940 -55, -63, -69, -77, -85, -90, -96, -98, -96, -93, -88, -79, -70, -63, -55, -50,
941 -48, -42, -39, -37, -33, -31, -28, -23, -20, -13, -6, 1, 7, 14, 17, 19, 21, 16,
942 15, 13, 6, 2, -3, -10, -13, -14, -9, 0, 8, 18, 26, 28, 28, 25, 20, 19, 16, 9, 7,
943 8, 4, 4, 8, 14, 23, 32, 38, 43, 44, 41, 34, 25, 20, 14, 10, 11, 14, 17, 23, 30,
944 37, 47, 56, 60, 62, 60, 54, 47, 41, 36, 33, 36, 41, 46, 53, 59, 64, 67, 68, 66,
945 61, 52, 39, 23, 8, -6, -20, -29, -32, -33, -33, -33, -35, -40, -43, -48, -57,
946 -62, -70, -80, -86, -93, -97, -97, -95, -89, -81, -70, -64, -58, -50, -47, -42,
947 -39, -34, -29, -29, -25, -23, -19, -13, -8, 0, 9, 18, 19, 21, 24, 18, 16, 13, 7,
948 5, -2, -10, -18, -22, -21, -18, -8, 4, 13, 19, 20, 20, 16, 12, 10, 6, 4, 2, -1,
949 -2, 0, 5, 13, 24, 36, 44, 50, 51, 47, 41, 33, 26, 22, 19, 19, 19, 22, 27, 32,
950 41, 51, 60, 65, 65, 61, 53, 46, 38, 32, 31, 32, 36, 40, 46, 51, 56, 61, 63, 63,
951 60, 51, 39, 23, 9, -5, -17, -22, -26, -26, -25, -26, -28, -31, -34, -39, -47,
952 -55, -64, -75, -84, -90, -95, -95, -91, -86, -78, -71, -65, -58, -54, -50, -46,
953 -43, -40, -39, -37, -34, -31, -23, -16, -7, 4, 11, 15, 18, 18, 17, 14, 11, 7, 3,
954 -1, -5, -9, -13, -15, -18, -23, -22, -18, -17, -11, -4, -3, 0, 2, 0, 2, 6, 6, 8,
955 11, 14, 16, 20, 26, 35, 42, 48, 55, 56, 58, 58, 53, 49, 47, 42, 39, 40, 40, 40,
956 43, 44, 46, 50, 51, 51, 47, 42, 35, 28, 24, 20, 18, 20, 24, 27, 30, 35, 39, 41,
957 44, 42, 40, 36, 27, 17, 7, -2, -12, -18, -21, -24, -24, -26, -28, -31, -35, -39,
958 -44, -51, -57, -65, -74, -78, -84, -88, -85, -84, -81, -75, -69, -64, -58, -52,
959 -48, -40, -34, -31, -24, -21, -14, -11, -9, -1, 4, 7, 14, 18, 21, 25, 26, 25,
960 28, 27, 21, 20, 15, 12, 9, 3, -2, -7, -11, -16, -16, -11, -10, -8, -4, -4, -3,
961 -1, 3, 12, 19, 22, 24, 21, 19, 18, 17, 24, 34, 37, 40, 46, 47, 49, 51, 50, 56,
962 60, 57, 54, 49, 45, 40, 36, 37, 41, 41, 40, 36, 32, 28, 24, 20, 21, 23, 22, 19,
963 16, 14, 15, 17, 20, 23, 25, 21, 14, 5, -4, -13, -20, -24, -25, -27, -30, -31,
964 -34, -35, -34, -32, -31, -32, -39, -46, -54, -65, -71, -73, -73, -68, -64, -60,
965 -54, -50, -43, -32, -25, -19, -10, -8, -10, -9, -8, -9, -7, -4, 0, 6, 8, 11, 13,
966 13, 17, 15, 9, 8, 2, -12, -20, -30, -43, -46, -47, -46, -35, -26, -16, -4, 4,
967 12, 17, 18, 20, 19, 13, 13, 13, 11, 17, 28, 37, 51, 63, 70, 76, 78, 75, 69, 62,
968 54, 45, 36, 29, 25, 23, 24, 29, 34, 40, 43, 40, 37, 32, 23, 15, 10, 5, 3, 5, 7,
969 13, 21, 29, 35, 42, 45, 42, 35, 28, 15, 3, -6, -16, -22, -22, -22, -20, -13, -9,
970 -3, 1, 0, -5, -16, -30, -43, -56, -64, -65, -68, -66, -59, -53, -40, -35, -33,
971 -22, -22, -30, -36, -30, -25, -39, -40, -29, -26, -26, -21, -7, 1, 2, -5, -3, 3,
972 -5, -8, -15, -14, -12, -32, -35, -30, -36, -37, -42, -43, -31, -25, -20, -2, 15,
973 21, 28, 32, 41, 51, 44, 45, 52, 50, 51, 52, 56, 63, 66, 69, 72, 74, 69, 58, 49,
974 39, 27, 13, 1, -2, -4, -5, -3, 3, 11, 18, 22, 26, 29, 28, 23, 22, 23, 25, 29,
975 32, 41, 55, 67, 78, 87, 95, 98, 95, 90, 80, 66, 50, 35, 21, 9, -1, -11, -17,
976 -20, -25, -29, -33, -38, -43, -49, -57, -63, -68, -71, -71, -70, -68, -63, -58,
977 -52, -42, -35, -33, -28, -27, -23, -16, -9, -1, 5, 1, 8, 15, 4, 0, 2, -2, -8,
978 -13, -12, -17, -28, -31, -33, -34, -35, -41, -46, -45, -51, -65, -66, -72, -76,
979 -65, -58, -39, -13, 5, 27, 47, 60, 73, 78, 79, 84, 82, 70, 65, 60, 54, 61, 67,
980 70, 76, 72, 61, 55, 43, 25, 6, -14, -35, -52, -67, -75, -73, -67, -55, -38, -24,
981 -7, 3, 9, 18, 22, 23, 26, 29, 35, 43, 53, 65, 82, 98, 112, 120, 121, 115, 102,
982 84, 67, 47, 25, 3, -17, -32, -43, -51, -55, -57, -59, -63, -67, -73, -81, -88,
983 -93, -94, -94, -90, -82, -73, -60, -46, -33, -24, -16, -10, -12, -12, -13, -13,
984 -14, -16, -13, -16, -20, -16, -15, -12, -8, -15, -26, -34, -48, -61, -65, -68,
985 -69, -71, -73, -67, -64, -60, -49, -44, -43, -41, -50, -61, -59, -54, -41, -16,
986 11, 36, 54, 69, 83, 91, 99, 102, 95, 82, 66, 44, 27, 23, 24, 27, 32, 32, 27, 18,
987 9, -1, -14, -28, -47, -68, -85, -95, -96, -84, -62, -38, -12, 13, 31, 42, 54,
988 62, 66, 67, 65, 61, 58, 59, 65, 77, 93, 106, 113, 114, 107, 93, 74, 54, 30, 3,
989 -23, -49, -68, -80, -84, -81, -76, -70, -67, -68, -69, -73, -76, -77, -79, -78,
990 -73, -70, -64, -50, -34, -15, 6, 19, 22, 19, 8, 1, -4, -10, -12, -17, -26, -35,
991 -37, -37, -36, -30, -30, -33, -43, -56, -64, -70, -71, -72, -73, -71, -68, -67,
992 -60, -44, -27, -17, -16, -16, -29, -39, -37, -38, -22, 7, 23, 38, 56, 67, 75,
993 88, 95, 93, 82, 57, 33, 11, 1, 3, 0, 5, 10, 4, 3, 4, -1, -5, -13, -26, -47, -66,
994 -78, -86, -82, -67, -43, -16, 9, 37, 60, 77, 91, 97, 97, 94, 84, 71, 66, 65, 66,
995 78, 90, 99, 103, 100, 95, 85, 71, 52, 26, -1, -28, -52, -67, -71, -71, -68, -61,
996 -55, -50, -45, -43, -43, -45, -48, -52, -56, -54, -47, -35, -21, -8, 3, 9, 11,
997 8, 3, -3, -15, -24, -36, -48, -52, -56, -59, -55, -50, -49, -46, -46, -53, -55,
998 -56, -59, -62, -61, -58, -57, -51, -40, -32, -24, -15, -12, -10, -8, -12, -18,
999 -21, -27, -36, -37, -27, -12, 11, 35, 47, 56, 62, 61, 60, 59, 52, 40, 25, 11, 6,
1000 6, 12, 23, 30, 35, 36, 28, 22, 17, 5, -10, -25, -41, -52, -53, -39, -16, 1, 19,
1001 34, 42, 49, 54, 54, 54, 49, 39, 36, 41, 45, 55, 72, 89, 101, 106, 106, 102, 93,
1002 80, 63, 44, 26, 7, -9, -14, -14, -14, -11, -8, -9, -12, -18, -27, -35, -41, -47,
1003 -52, -52, -49, -41, -29, -15, -1, 5, 7, 6, 1, -8, -16, -25, -38, -44, -44, -42,
1004 -36, -26, -19, -14, -11, -14, -21, -29, -40, -53, -63, -68, -71, -70, -59, -44,
1005 -32, -21, -8, -1, 1, 1, -8, -19, -26, -37, -44, -44, -43, -43, -40, -30, -16, 3,
1006 23, 42, 54, 53, 52, 46, 39, 40, 35, 27, 22, 18, 17, 26, 41, 50, 57, 56, 47, 38,
1007 26, 15, 4, -10, -21, -31, -37, -31, -21, -6, 11, 25, 34, 41, 47, 49, 50, 49, 46,
1008 46, 47, 52, 59, 68, 80, 89, 94, 97, 93, 85, 74, 62, 47, 34, 21, 9, -1, -7, -10,
1009 -9, -9, -10, -15, -20, -27, -34, -38, -40, -42, -41, -38, -31, -22, -11, 1, 9,
1010 14, 16, 10, 4, -4, -16, -26, -36, -46, -48, -46, -43, -35, -28, -26, -27, -32,
1011 -37, -40, -48, -56, -65, -72, -76, -74, -63, -48, -33, -23, -13, -9, -7, -7,
1012 -12, -17, -26, -37, -46, -52, -50, -47, -45, -43, -43, -34, -19, -3, 17, 29, 30,
1013 28, 28, 29, 33, 37, 36, 32, 30, 29, 35, 43, 51, 55, 49, 41, 30, 18, 10, 1, -10,
1014 -23, -36, -44, -46, -40, -30, -11, 4, 14, 27, 36, 41, 47, 49, 51, 53, 50, 48,
1015 54, 61, 69, 79, 86, 91, 89, 81, 76, 68, 56, 43, 25, 7, -9, -22, -29, -31, -33,
1016 -37, -40, -43, -45, -46, -47, -47, -49, -48, -45, -40, -31, -21, -11, -3, 0, 1,
1017 0, -5, -13, -21, -33, -42, -48, -52, -47, -41, -36, -33, -35, -35, -38, -47,
1018 -53, -62, -72, -78, -81, -79, -67, -55, -45, -27, -9, 1, 9, 16, 16, 9, 2, -6,
1019 -16, -17, -16, -22, -16, -7, -11, -12, -13, -7, 2, 6, 11, 8, 1, -2, 1, 4, 12,
1020 21, 14, 13, 18, 17, 25, 32, 34, 34, 30, 23, 15, 17, 19, 16, 12, 3, -2, -5, -1,
1021 9, 11, 16, 19, 17, 23, 33, 38, 39, 42, 43, 43, 47, 51, 54, 59, 62, 64, 64, 67,
1022 68, 65, 65, 63, 56, 49, 43, 34, 27, 22, 13, 5, 0, -6, -11, -15, -18, -20, -22,
1023 -22, -25, -26, -25, -26, -24, -21, -21, -24, -25, -25, -27, -27, -27, -31, -33,
1024 -34, -36, -40, -42, -44, -47, -46, -44, -43, -41, -36, -34, -31, -27, -28, -33,
1025 -35, -34, -35, -36, -35, -37, -33, -30, -27, -21, -16, -14, -17, -18, -18, -22,
1026 -30, -36, -41, -49, -55, -61, -58, -36, -14, 7, 24, 33, 40, 43, 47, 52, 50, 42,
1027 30, 22, 21, 25, 34, 42, 52, 55, 52, 47, 39, 33, 20, 3, -15, -37, -51, -55, -52,
1028 -42, -29, -14, -1, 14, 29, 38, 44, 44, 39, 36, 35, 35, 40, 48, 60, 72, 83, 91,
1029 97, 97, 94, 87, 74, 59, 41, 23, 9, 0, -7, -11, -13, -15, -16, -17, -20, -23,
1030 -29, -37, -46, -52, -53, -51, -45, -35, -24, -16, -9, -2, 2, 3, -1, -9, -17,
1031 -25, -35, -41, -41, -41, -39, -35, -29, -24, -24, -24, -30, -37, -44, -57, -65,
1032 -64, -65, -62, -52, -41, -29, -16, -7, 0, 6, 0, -6, -11, -21, -25, -30, -32,
1033 -28, -26, -22, -17, -15, -13, -18, -21, -13, -7, 0, 4, 7, 12, 20, 31, 41, 49,
1034 51, 48, 46, 44, 46, 46, 42, 41, 37, 33, 29, 24, 23, 19, 11, 1, -12, -19, -24,
1035 -27, -25, -19, -13, -7, 3, 14, 24, 31, 35, 40, 45, 47, 50, 56, 62, 68, 76, 83,
1036 88, 90, 89, 88, 84, 75, 63, 47, 31, 17, 4, -5, -12, -19, -25, -28, -30, -33,
1037 -34, -36, -40, -44, -47, -49, -47, -40, -33, -25, -17, -9, -4, 3, 7, 7, 4, -4,
1038 -10, -18, -25, -29, -32, -36, -40, -40, -36, -34, -32, -30, -33, -40, -48, -52,
1039 -54, -53, -54, -54, -48, -45, -39, -27, -15, -6, -4, -3, -2, -7, -9, -11, -12,
1040 -16, -19, -22, -27, -24, -24, -30, -24, -18, -10, 5, 12, 14, 21, 24, 26, 31, 35,
1041 34, 31, 27, 28, 33, 36, 41, 46, 43, 42, 37, 29, 27, 21, 8, -2, -14, -24, -26,
1042 -25, -22, -13, -4, 3, 11, 20, 26, 29, 31, 33, 35, 36, 39, 45, 53, 63, 71, 77,
1043 82, 85, 81, 78, 72, 61, 50, 36, 23, 12, 3, -2, -7, -9, -13, -16, -19, -22, -25,
1044 -29, -33, -38, -42, -41, -38, -31, -21, -14, -6, 0, 3, 7, 7, 4, -1, -9, -17,
1045 -23, -30, -34, -37, -40, -40, -41, -43, -41, -41, -41, -40, -40, -43, -46, -45,
1046 -46, -42, -37, -35, -31, -25, -22, -18, -9, -2, -1, 2, 1, -3, -7, -9, -10, -13,
1047 -14, -19, -28, -31, -34, -41, -42, -31, -23, -13, 3, 8, 13, 25, 28, 34, 41, 39,
1048 32, 29, 28, 30, 36, 40, 44, 45, 43, 43, 39, 34, 31, 19, 4, -7, -20, -27, -26,
1049 -23, -15, -7, -1, 7, 16, 24, 29, 32, 32, 31, 30, 32, 39, 46, 54, 63, 69, 74, 77,
1050 76, 74, 70, 60, 48, 36, 22, 12, 5, 0, -2, -5, -8, -10, -12, -14, -16, -19, -24,
1051 -29, -32, -34, -31, -27, -22, -15, -10, -6, -2, -1, -1, -2, -9, -15, -19, -25,
1052 -28, -29, -31, -32, -34, -33, -31, -31, -33, -36, -37, -37, -41, -42, -42, -41,
1053 -42, -35, -30, -29, -22, -16, -14, -8, -7, -8, -11, -13, -15, -17, -18, -19,
1054 -19, -20, -20, -23, -26, -27, -32, -39, -42, -38, -32, -20, -1, 9, 17, 26, 32,
1055 40, 48, 49, 44, 37, 30, 26, 28, 32, 36, 36, 35, 35, 32, 28, 26, 17, 4, -9, -23,
1056 -33, -35, -31, -23, -15, -8, -1, 7, 16, 24, 29, 29, 27, 25, 26, 32, 40, 47, 57,
1057 65, 70, 74, 76, 75, 72, 65, 54, 42, 29, 19, 12, 8, 6, 2, -2, -4, -8, -11, -14,
1058 -18, -25, -31, -35, -37, -35, -29, -25, -18, -11, -6, -1, 3, 3, 0, -5, -12, -21,
1059 -26, -29, -28, -28, -26, -26, -30, -28, -26, -26, -27, -29, -36, -45, -50, -52,
1060 -50, -48, -48, -42, -36, -31, -25, -17, -8, -5, -8, -7, -8, -12, -15, -13, -12,
1061 -13, -16, -18, -18, -19, -22, -24, -29, -39, -44, -40, -32, -18, -4, 2, 11, 19,
1062 25, 33, 39, 39, 33, 28, 22, 20, 24, 27, 33, 37, 35, 35, 31, 30, 28, 18, 8, -5,
1063 -19, -25, -23, -16, -10, -3, 3, 8, 16, 22, 28, 31, 30, 27, 26, 30, 35, 43, 53,
1064 64, 70, 73, 77, 78, 76, 72, 62, 50, 37, 24, 15, 9, 6, 2, -3, -7, -10, -14, -17,
1065 -19, -24, -30, -35, -38, -38, -33, -27, -22, -17, -11, -6, -3, 0, 0, -4, -10,
1066 -17, -21, -24, -26, -27, -28, -28, -29, -30, -31, -30, -29, -33, -37, -40, -44,
1067 -46, -46, -43, -41, -38, -33, -29, -22, -16, -12, -7, -4, -3, -5, -7, -10, -11,
1068 -12, -15, -15, -18, -21, -24, -27, -29, -34, -44, -47, -41, -35, -24, -7, 0, 7,
1069 16, 22, 31, 38, 37, 34, 31, 26, 24, 28, 32, 36, 38, 35, 34, 31, 26, 24, 15, 2,
1070 -12, -26, -32, -32, -27, -19, -12, -5, 2, 11, 19, 27, 31, 30, 30, 29, 32, 41,
1071 49, 60, 70, 77, 81, 85, 86, 84, 79, 69, 55, 41, 27, 18, 10, 6, 3, -2, -5, -7,
1072 -9, -11, -13, -18, -25, -30, -34, -35, -31, -27, -20, -13, -8, -3, 2, 5, 5, 3,
1073 -2, -9, -16, -23, -27, -31, -33, -34, -36, -36, -36, -38, -41, -41, -43, -48,
1074 -50, -51, -50, -48, -44, -35, -30, -27, -21, -15, -10, -8, -4, -3, -4, -4, -6,
1075 -7, -7, -8, -8, -10, -13, -17, -24, -29, -34, -40, -51, -61, -56, -46, -35, -16,
1076 0, 7, 16, 26, 34, 42, 42, 34, 30, 25, 21, 26, 33, 41, 47, 48, 49, 49, 45, 40,
1077 32, 17, 1, -16, -29, -32, -27, -23, -16, -7, 0, 8, 16, 23, 27, 26, 23, 21, 22,
1078 27, 35, 45, 57, 68, 73, 79, 84, 82, 79, 72, 59, 45, 32, 21, 15, 12, 10, 8, 6, 4,
1079 1, -3, -6, -12, -22, -30, -37, -41, -40, -36, -30, -23, -17, -12, -7, -3, -2,
1080 -3, -7, -12, -20, -28, -29, -29, -29, -28, -28, -28, -27, -23, -20, -19, -22,
1081 -30, -35, -39, -40, -40, -39, -38, -37, -34, -30, -23, -18, -13, -10, -13, -15,
1082 -15, -16, -16, -16, -17, -19, -22, -22, -22, -21, -20, -25, -29, -33, -42, -50,
1083 -47, -34, -23, -6, 9, 16, 28, 38, 47, 57, 57, 51, 42, 34, 31, 30, 33, 38, 41,
1084 39, 37, 38, 36, 35, 28, 13, -1, -16, -27, -29, -26, -24, -22, -17, -11, -4, 6,
1085 13, 17, 17, 16, 17, 18, 26, 34, 43, 53, 61, 68, 73, 79, 80, 77, 71, 60, 48, 37,
1086 28, 22, 16, 13, 9, 5, 3, 1, -1, -4, -9, -17, -24, -30, -34, -34, -32, -29, -26,
1087 -22, -16, -11, -7, -5, -7, -11, -15, -19, -21, -22, -24, -25, -24, -23, -21,
1088 -19, -22, -25, -28, -32, -33, -38, -41, -40, -42, -41, -38, -32, -27, -22, -18,
1089 -15, -11, -14, -14, -11, -12, -12, -13, -12, -11, -14, -14, -12, -13, -16, -21,
1090 -25, -31, -37, -48, -56, -58, -52, -42, -27, -4, 12, 22, 37, 47, 54, 57, 56, 51,
1091 44, 38, 34, 38, 45, 49, 54, 56, 57, 56, 51, 45, 34, 19, 4, -11, -21, -25, -25,
1092 -23, -17, -11, -7, 0, 5, 8, 9, 9, 9, 9, 13, 20, 31, 44, 56, 67, 74, 80, 82, 79,
1093 76, 68, 56, 45, 33, 24, 17, 13, 9, 5, 1, -4, -8, -12, -18, -25, -32, -38, -43,
1094 -45, -44, -39, -34, -28, -22, -18, -14, -10, -8, -7, -7, -8, -10, -11, -10, -9,
1095 -8, -9, -10, -12, -16, -19, -23, -27, -32, -35, -36, -36, -35, -33, -30, -25,
1096 -20, -16, -17, -19, -21, -20, -20, -20, -18, -17, -15, -12, -7, -3, -1, 1, -1,
1097 -5, -8, -14, -23, -28, -30, -37, -43, -45, -47, -46, -37, -23, -9, 9, 18, 24,
1098 33, 38, 40, 44, 43, 39, 34, 32, 34, 40, 46, 50, 53, 50, 47, 43, 36, 32, 21, 7,
1099 -5, -15, -21, -21, -18, -15, -11, -7, -4, 2, 6, 10, 12, 13, 14, 17, 22, 31, 41,
1100 52, 60, 67, 70, 72, 71, 67, 63, 54, 43, 33, 22, 16, 11, 7, 4, -2, -6, -10, -15,
1101 -19, -23, -29, -36, -40, -42, -43, -38, -34, -29, -23, -19, -15, -12, -9, -9,
1102 -12, -15, -16, -15, -14, -10, -8, -8, -9, -12, -13, -16, -22, -25, -30, -38,
1103 -42, -41, -41, -42, -38, -35, -33, -30, -25, -19, -16, -13, -12, -12, -11, -10,
1104 -9, -7, -8, -8, -8, -7, -5, -3, -2, -5, -8, -11, -18, -23, -27, -32, -41, -48,
1105 -48, -43, -35, -25, -7, 7, 15, 24, 31, 35, 37, 36, 34, 31, 28, 26, 31, 40, 45,
1106 50, 54, 54, 52, 47, 42, 36, 24, 13, 2, -4, -6, -6, -2, 3, 8, 9, 11, 14, 14, 14,
1107 14, 13, 13, 15, 21, 30, 41, 50, 58, 62, 63, 63, 59, 54, 47, 37, 28, 20, 13, 10,
1108 7, 5, 2, -2, -7, -14, -19, -25, -32, -38, -44, -46, -48, -46, -41, -35, -29,
1109 -21, -17, -13, -10, -9, -11, -13, -15, -15, -11, -9, -7, -3, -2, -5, -4, -2, -5,
1110 -10, -14, -19, -21, -22, -24, -25, -25, -27, -29, -24, -19, -19, -18, -17, -19,
1111 -18, -16, -13, -9, -7, -8, -8, -4, -1, 1, -1, -2, -7, -15, -18, -17, -19, -23,
1112 -25, -25, -29, -30, -27, -24, -23, -25, -23, -22, -22, -13, 0, 10, 17, 23, 29,
1113 34, 40, 45, 49, 48, 42, 40, 37, 35, 38, 40, 39, 38, 36, 33, 32, 31, 26, 21, 14,
1114 6, 1, -3, -2, 1, 2, 5, 8, 11, 15, 21, 26, 31, 35, 35, 36, 39, 41, 45, 47, 47,
1115 45, 42, 39, 36, 32, 26, 18, 10, 2, -6, -12, -16, -21, -26, -31, -35, -38, -39,
1116 -40, -41, -41, -41, -42, -37, -32, -29, -24, -17, -14, -11, -6, 0, 1, 0, 1, 0,
1117 -3, -6, -6, -5, -7, -11, -12, -11, -12, -14, -13, -14, -17, -22, -27, -29, -30,
1118 -33, -33, -29, -29, -29, -24, -20, -17, -14, -12, -12, -12, -12, -16, -15, -11,
1119 -15, -17, -17, -17, -20, -22, -23, -26, -27, -31, -34, -31, -30, -27, -25, -20,
1120 -15, -12, -1, 12, 20, 26, 33, 38, 38, 42, 46, 45, 46, 42, 39, 40, 39, 39, 40,
1121 40, 36, 31, 29, 25, 22, 17, 13, 7, 1, -1, -3, -2, 1, 3, 5, 9, 13, 17, 22, 28,
1122 32, 35, 37, 39, 43, 46, 48, 49, 48, 47, 43, 39, 35, 29, 22, 15, 6, -2, -8, -14,
1123 -19, -23, -27, -32, -35, -37, -39, -40, -40, -40, -39, -38, -34, -29, -24, -18,
1124 -13, -9, -6, -4, -3, -3, -4, -2, -3, -4, -5, -5, -3, -2, -3, -4, -6, -11, -17,
1125 -19, -23, -28, -31, -34, -33, -32, -31, -24, -21, -19, -18, -16, -16, -14, -13,
1126 -15, -12, -10, -12, -6, -1, 1, 2, 2, -2, -7, -10, -14, -18, -20, -22, -25, -26,
1127 -25, -22, -21, -20, -21, -27, -30, -32, -30, -25, -17, -9, -4, 6, 14, 21, 31,
1128 34, 33, 31, 28, 24, 21, 27, 31, 30, 37, 41, 44, 47, 50, 52, 47, 40, 30, 21, 18,
1129 13, 13, 17, 19, 21, 26, 33, 35, 38, 38, 34, 29, 25, 24, 22, 25, 28, 28, 32, 34,
1130 35, 35, 33, 28, 18, 9, 0, -10, -15, -20, -23, -24, -24, -22, -21, -19, -18, -19,
1131 -22, -29, -34, -38, -39, -41, -40, -34, -30, -24, -17, -11, -7, -8, -11, -14,
1132 -17, -19, -20, -20, -22, -22, -18, -16, -11, -10, -12, -13, -17, -21, -24, -24,
1133 -26, -29, -27, -26, -22, -17, -13, -9, -9, -11, -11, -13, -14, -15, -14, -14,
1134 -15, -14, -15, -12, -13, -15, -13, -17, -22, -23, -25, -26, -25, -22, -21, -22,
1135 -22, -21, -16, -13, -7, 0, 4, 7, 10, 15, 20, 23, 25, 26, 27, 26, 26, 27, 28, 31,
1136 31, 32, 34, 34, 36, 37, 37, 36, 31, 28, 25, 23, 21, 21, 23, 23, 25, 27, 30, 33,
1137 35, 36, 34, 32, 32, 30, 29, 29, 29, 29, 28, 27, 26, 25, 23, 18, 14, 7, 0, -5,
1138 -10, -14, -17, -20, -21, -21, -21, -22, -21, -22, -24, -27, -29, -31, -32, -32,
1139 -32, -33, -31, -29, -27, -23, -20, -18, -20, -21, -21, -20, -19, -20, -17, -16,
1140 -16, -15, -14, -11, -12, -13, -13, -14, -16, -17, -16, -15, -16, -15, -15, -15,
1141 -16, -17, -15, -13, -15, -16, -16, -15, -15, -13, -12, -13, -14, -16, -16, -17,
1142 -18, -17, -18, -19, -21, -20, -19, -19, -18, -18, -17, -18, -19, -16, -14, -12,
1143 -8, -4, 2, 5, 10, 16, 20, 22, 23, 25, 25, 24, 25, 28, 32, 33, 36, 40, 41, 42,
1144 44, 44, 43, 39, 36, 33, 30, 28, 27, 27, 26, 28, 27, 26, 27, 25, 24, 22, 19, 17,
1145 16, 15, 16, 18, 19, 19, 21, 21, 19, 18, 15, 11, 6, 1, -3, -7, -10, -12, -13,
1146 -14, -15, -16, -17, -18, -23, -27, -28, -31, -35, -37, -38, -37, -38, -37, -35,
1147 -31, -30, -30, -27, -24, -23, -22, -20, -18, -15, -15, -15, -10, -8, -9, -8, -4,
1148 -3, -6, -8, -7, -10, -13, -13, -14, -16, -19, -18, -16, -15, -15, -14, -13, -17,
1149 -18, -18, -21, -21, -21, -22, -22, -24, -22, -22, -24, -22, -22, -22, -23, -23,
1150 -20, -20, -20, -18, -20, -20, -15, -12, -11, -4, 1, 6, 10, 12, 18, 22, 23, 26,
1151 27, 27, 28, 30, 32, 33, 37, 39, 40, 42, 42, 43, 43, 41, 40, 36, 32, 30, 28, 26,
1152 26, 26, 26, 26, 25, 26, 26, 24, 24, 22, 21, 22, 20, 22, 23, 23, 24, 24, 24, 23,
1153 20, 18, 15, 10, 6, 3, -1, -5, -7, -8, -9, -11, -13, -16, -17, -20, -23, -26,
1154 -29, -32, -34, -37, -37, -36, -37, -36, -34, -32, -30, -27, -25, -22, -21, -20,
1155 -18, -17, -15, -15, -15, -12, -12, -13, -10, -9, -10, -8, -5, -5, -5, -5, -5,
1156 -7, -12, -11, -10, -14, -14, -13, -16, -17, -16, -18, -19, -19, -21, -22, -23,
1157 -25, -25, -26, -25, -24, -27, -27, -26, -29, -30, -29, -27, -24, -24, -19, -12,
1158 -8, -3, 7, 14, 15, 19, 26, 27, 26, 29, 35, 37, 39, 43, 46, 48, 49, 50, 52, 51,
1159 48, 45, 42, 38, 34, 32, 30, 28, 25, 23, 22, 21, 19, 18, 17, 15, 11, 9, 9, 9, 10,
1160 12, 15, 16, 18, 20, 22, 24, 25, 25, 24, 22, 20, 17, 15, 13, 10, 7, 4, 1, -3, -5,
1161 -8, -10, -14, -19, -23, -28, -33, -36, -39, -41, -44, -46, -46, -46, -44, -43,
1162 -41, -40, -38, -37, -36, -31, -26, -23, -20, -17, -13, -12, -12, -8, -4, -4, -3,
1163 -1, 0, -2, -2, 0, 3, 0, -2, -2, -3, -7, -11, -12, -13, -19, -24, -24, -28, -33,
1164 -33, -33, -36, -38, -39, -41, -44, -46, -46, -46, -45, -44, -44, -39, -33, -28,
1165 -20, -11, -2, 4, 10, 17, 22, 25, 31, 35, 37, 39, 42, 46, 50, 54, 57, 61, 63, 62,
1166 61, 60, 58, 53, 48, 44, 39, 34, 29, 27, 24, 22, 20, 17, 14, 10, 7, 6, 5, 3, 2,
1167 2, 2, 3, 5, 8, 10, 12, 13, 15, 15, 15, 15, 15, 14, 13, 12, 11, 9, 9, 8, 6, 4, 1,
1168 -3, -6, -10, -13, -16, -19, -22, -26, -28, -29, -31, -32, -32, -32, -33, -34,
1169 -34, -34, -33, -33, -31, -30, -28, -27, -24, -21, -20, -17, -15, -13, -11, -9,
1170 -10, -9, -6, -7, -7, -5, -4, -6, -6, -4, -4, -7, -7, -7, -10, -12, -14, -15,
1171 -18, -20, -22, -23, -25, -27, -28, -29, -31, -34, -33, -31, -33, -34, -30, -27,
1172 -25, -21, -17, -13, -9, -6, -3, 0, 2, 4, 7, 11, 13, 15, 20, 23, 25, 29, 34, 35,
1173 37, 40, 41, 41, 43, 44, 42, 42, 43, 42, 41, 41, 40, 38, 37, 35, 32, 30, 29, 27,
1174 25, 25, 23, 23, 22, 22, 21, 22, 21, 19, 19, 18, 17, 16, 15, 13, 12, 11, 10, 8,
1175 7, 5, 3, 2, 0, -3, -4, -5, -8, -11, -12, -14, -17, -20, -22, -25, -29, -32, -33,
1176 -35, -37, -38, -38, -38, -39, -40, -38, -37, -38, -37, -36, -36, -36, -35, -33,
1177 -31, -31, -28, -25, -23, -22, -20, -16, -14, -13, -11, -8, -9, -10, -8, -7, -7,
1178 -8, -7, -6, -7, -8, -7, -7, -9, -10, -11, -12, -15, -17, -16, -15, -17, -16,
1179 -10, -7, -8, -5, 1, 2, 2, 3, 6, 6, 6, 8, 11, 14, 17, 21, 25, 29, 31, 34, 37, 39,
1180 38, 40, 41, 41, 40, 40, 41, 42, 42, 42, 42, 40, 38, 35, 32, 31, 27, 24, 23, 22,
1181 22, 23, 23, 24, 24, 24, 23, 21, 19, 18, 16, 16, 14, 13, 13, 13, 12, 13, 13, 12,
1182 10, 7, 4, 1, -2, -5, -8, -11, -13, -15, -17, -19, -20, -22, -26, -30, -33, -36,
1183 -40, -43, -44, -44, -45, -43, -40, -38, -37, -34, -30, -29, -28, -27, -26, -25,
1184 -23, -20, -18, -15, -13, -12, -9, -7, -7, -4, -3, -3, -4, -4, -5, -7, -7, -8,
1185 -9, -12, -16, -19, -24, -27, -31, -36, -39, -41, -41, -39, -35, -30, -24, -13,
1186 -4, 1, 8, 14, 19, 25, 29, 33, 36, 40, 45, 49, 55, 60, 64, 67, 67, 66, 63, 60,
1187 55, 47, 42, 35, 27, 20, 15, 12, 8, 5, 2, -2, -5, -8, -10, -12, -11, -9, -6, -1,
1188 5, 12, 21, 29, 38, 44, 49, 52, 53, 54, 54, 54, 53, 51, 48, 44, 40, 35, 28, 22,
1189 13, 5, -5, -16, -25, -33, -40, -47, -51, -54, -57, -59, -58, -55, -52, -49, -48,
1190 -47, -44, -42, -37, -30, -24, -19, -13, -9, -5, 1, 4, 8, 12, 10, 9, 6, 1, -4,
1191 -9, -14, -18, -25, -31, -36, -39, -41, -41, -42, -42, -42, -44, -44, -44, -42,
1192 -37, -37, -35, -34, -34, -31, -28, -24, -19, -19, -22, -22, -14, -7, 1, 15, 31,
1193 39, 42, 52, 54, 50, 53, 49, 43, 37, 29, 27, 24, 27, 29, 28, 29, 24, 19, 14, 11,
1194 6, 0, -3, -8, -9, -7, -6, 2, 10, 16, 17, 17, 19, 17, 19, 24, 28, 35, 37, 43, 51,
1195 57, 64, 67, 67, 61, 54, 45, 37, 32, 27, 23, 20, 14, 10, 5, 1, -3, -8, -14, -20,
1196 -26, -30, -32, -29, -25, -21, -19, -17, -14, -14, -15, -14, -15, -18, -21, -22,
1197 -23, -21, -18, -16, -14, -17, -20, -23, -27, -30, -32, -34, -37, -37, -37, -36,
1198 -33, -29, -28, -30, -29, -29, -28, -26, -27, -23, -21, -24, -18, -11, -10, -6,
1199 -1, -3, -8, -13, -17, -20, -27, -27, -26, -33, -35, -35, -38, -42, -43, -35,
1200 -30, -26, -14, -1, 14, 27, 40, 54, 55, 56, 58, 55, 54, 51, 50, 50, 47, 47, 46,
1201 44, 41, 36, 32, 22, 12, 1, -8, -16, -19, -18, -21, -18, -14, -11, -4, -1, 4, 9,
1202 11, 16, 22, 28, 36, 45, 55, 62, 68, 72, 72, 70, 66, 60, 52, 43, 34, 27, 20, 14,
1203 9, 3, -4, -9, -16, -21, -25, -28, -29, -30, -29, -27, -23, -21, -16, -10, -8,
1204 -7, -7, -8, -10, -12, -11, -10, -11, -10, -11, -16, -18, -21, -26, -30, -33,
1205 -37, -40, -43, -47, -47, -47, -48, -39, -34, -36, -30, -27, -31, -27, -22, -16,
1206 -14, -11, -2, -3, -1, 6, 2, 1, 1, -8, -16, -18, -22, -26, -25, -26, -28, -36,
1207 -38, -40, -52, -49, -48, -55, -45, -36, -26, -5, 16, 28, 40, 51, 50, 51, 51, 50,
1208 48, 46, 46, 46, 47, 51, 50, 50, 46, 38, 30, 19, 8, 0 };
1209 
1210 #endif /* BLAHBLAH4B_H_ */
#define CONSTTABLE_STORAGE(X)
Declare a variable such that it will be stored in flash memory, instead of RAM, on platforms where th...
@@ -110,13 +110,6 @@ More...

Go to the source code of this file.

- - - - -

-Functions

-def char2mozzi.char2mozzi (infile, outfile, tablename, samplerate)
 

Detailed Description

A script for converting raw 8 bit sound data files to wavetables for Mozzi.

Usage: >>>char2mozzi.py <infile outfile="" tablename="" samplerate>="">

Parameters
@@ -134,7 +127,7 @@ length. For a recorded audio sample, set the project rate to the -Mozzi AUDIO_RATE (16384 in the current version). +MOZZI_AUDIO_RATE (16384 in the current version). Samples can be any length, as long as they fit in your Arduino. Save by exporting with the format set to "Other uncompressed formats", @@ -148,13 +141,20 @@

Definition in file char2mozzi.py.

-
+ + + + +

+Functions

+def char2mozzi.char2mozzi (infile, outfile, tablename, samplerate)
 
+
-Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 
35 
36 import sys, array, os, textwrap, random
37 
38 if len(sys.argv) != 5:
39  print ('Usage: char2mozzi.py <infile outfile tablename samplerate>')
40  sys.exit(1)
41 
42 [infile, outfile, tablename, samplerate] = sys.argv[1:]
43 
44 def char2mozzi(infile, outfile, tablename, samplerate):
45  fin = open(os.path.expanduser(infile), "rb")
46  print ("opened " + infile)
47  uint8_tstoread = os.path.getsize(os.path.expanduser(infile))
48 
49  valuesfromfile = array.array('b') # array of signed int8_t ints
50  try:
51  valuesfromfile.fromfile(fin, uint8_tstoread)
52  finally:
53  fin.close()
54 
55  values=valuesfromfile.tolist()
56  fout = open(os.path.expanduser(outfile), "w")
57  fout.write('#ifndef ' + tablename + '_H_' + '\n')
58  fout.write('#define ' + tablename + '_H_' + '\n \n')
59  fout.write('#if ARDUINO >= 100'+'\n')
60  fout.write('#include "Arduino.h"'+'\n')
61  fout.write('#else'+'\n')
62  fout.write('#include "WProgram.h"'+'\n')
63  fout.write('#endif'+'\n')
64  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
65  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
66  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
67  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
68  try:
69  for i in range(len(values)):
70 
71  if (values[i] == 33) and (values[i+1] == 33) and (values[i+2] == 33):
72  values[i+2] = random.choice([32, 34])
73  outstring += str(values[i]) + ", "
74  finally:
75  outstring += "};"
76  outstring = textwrap.fill(outstring, 80)
77  fout.write(outstring)
78  fout.write('\n\n#endif /* ' + tablename + '_H_ */\n')
79  fout.close()
80  print ("wrote " + outfile)
81 
82 char2mozzi(infile, outfile, tablename, samplerate)
+Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 
35 
36 import sys, array, os, textwrap, random
37 
38 if len(sys.argv) != 5:
39  print ('Usage: char2mozzi.py <infile outfile tablename samplerate>')
40  sys.exit(1)
41 
42 [infile, outfile, tablename, samplerate] = sys.argv[1:]
43 
44 def char2mozzi(infile, outfile, tablename, samplerate):
45  fin = open(os.path.expanduser(infile), "rb")
46  print ("opened " + infile)
47  uint8_tstoread = os.path.getsize(os.path.expanduser(infile))
48 
49  valuesfromfile = array.array('b') # array of signed int8_t ints
50  try:
51  valuesfromfile.fromfile(fin, uint8_tstoread)
52  finally:
53  fin.close()
54 
55  values=valuesfromfile.tolist()
56  fout = open(os.path.expanduser(outfile), "w")
57  fout.write('#ifndef ' + tablename + '_H_' + '\n')
58  fout.write('#define ' + tablename + '_H_' + '\n \n')
59  fout.write('#include <Arduino.h>'+'\n')
60  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
61  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
62  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
63  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
64  try:
65  for i in range(len(values)):
66 
67  if (values[i] == 33) and (values[i+1] == 33) and (values[i+2] == 33):
68  values[i+2] = random.choice([32, 34])
69  outstring += str(values[i]) + ", "
70  finally:
71  outstring += "};"
72  outstring = textwrap.fill(outstring, 80)
73  fout.write(outstring)
74  fout.write('\n\n#endif /* ' + tablename + '_H_ */\n')
75  fout.close()
76  print ("wrote " + outfile)
77 
78 char2mozzi(infile, outfile, tablename, samplerate)
-
1 
2 
3 import array,os,textwrap,math
4 
5 
6 def chebyTable(outfile, tablename, tablelength, curvenum):
7 
8  """
9  Generates chebyshev polynomial curve tables for WaveShaper.
10 
11  Args:
12  outfile: The file to save as output.
13  tablename: The name to give the table of converted data in the new file.
14  tablelength: Use a power of two.
15  curvenum: The chebyshev polynomial curve number to chebyTable.
16 
17  Examples:
18  chebyTable("~/Desktop/waveshaper_chebyshev_3rd_256_int8.h", "CHEBYSHEV_3RD_256", 256, 3)
19  chebyTable("~/Desktop/waveshaper_chebyshev_4th_256_int8.h", "CHEBYSHEV_4TH_256", 256, 4)
20  chebyTable("~/Desktop/waveshaper_chebyshev_5th_256_int8.h", "CHEBYSHEV_5TH_256", 256, 5)
21  chebyTable("~/Desktop/waveshaper_chebyshev_6th_256_int8.h", "CHEBYSHEV_6TH_256", 256, 6)
22 
23  Resources:
24  http://www.obiwannabe.co.uk/html/music/6SS/six-waveshaper.html
25  http://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html
26  The first few Chebyshev polynomials of the first kind are
27  T_0(x) = 1
28  T_1(x) = x
29  T_2(x) = 2x^2-1
30  T_3(x) = 4x^3-3x
31  T_4(x) = 8x^4-8x^2+1
32  T_5(x) = 16x^5-20x^3+5x
33  T_6(x) = 32x^6-48x^4+18x^2-1
34 
35  """
36 
37  fout = open(os.path.expanduser(outfile), "w")
38  fout.write('#ifndef ' + tablename + '_H_' + '\n')
39  fout.write('#define ' + tablename + '_H_' + '\n \n')
40  fout.write('#if ARDUINO >= 100'+'\n')
41  fout.write('#include "Arduino.h"'+'\n')
42  fout.write('#else'+'\n')
43  fout.write('#include "WProgram.h"'+'\n')
44  fout.write('#endif'+'\n')
45  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
46  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength) +'\n')
47  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
48  try:
49  for num in range(tablelength):
50 
51  x = 2*(float(num-(tablelength/2)))/tablelength
52 
53  if curvenum == 3:
54  t_x = 4*pow(x,3)-3*x
55  elif curvenum == 4:
56  t_x = 8*pow(x,4)-8*pow(x,2)+1
57  elif curvenum == 5:
58  t_x = 16*pow(x,5)-20*pow(x,3)+5*x
59  elif curvenum == 6:
60  t_x = 32*pow(x,6)-48*pow(x,4)+18*pow(x,2)-1
61 
62  scaled = int16_t(math.floor(t_x*127.999))
63 
64  outstring += str(scaled) + ", "
65  finally:
66  outstring += "};"
67  outstring = textwrap.fill(outstring, 80)
68  fout.write(outstring)
69  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
70  fout.close()
71  print "wrote " + outfile
72 
+
1 
2 
3 import array,os,textwrap,math
4 
5 
6 def chebyTable(outfile, tablename, tablelength, curvenum):
7 
8  """
9  Generates chebyshev polynomial curve tables for WaveShaper.
10 
11  Args:
12  outfile: The file to save as output.
13  tablename: The name to give the table of converted data in the new file.
14  tablelength: Use a power of two.
15  curvenum: The chebyshev polynomial curve number to chebyTable.
16 
17  Examples:
18  chebyTable("~/Desktop/waveshaper_chebyshev_3rd_256_int8.h", "CHEBYSHEV_3RD_256", 256, 3)
19  chebyTable("~/Desktop/waveshaper_chebyshev_4th_256_int8.h", "CHEBYSHEV_4TH_256", 256, 4)
20  chebyTable("~/Desktop/waveshaper_chebyshev_5th_256_int8.h", "CHEBYSHEV_5TH_256", 256, 5)
21  chebyTable("~/Desktop/waveshaper_chebyshev_6th_256_int8.h", "CHEBYSHEV_6TH_256", 256, 6)
22 
23  Resources:
24  http://www.obiwannabe.co.uk/html/music/6SS/six-waveshaper.html
25  http://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html
26  The first few Chebyshev polynomials of the first kind are
27  T_0(x) = 1
28  T_1(x) = x
29  T_2(x) = 2x^2-1
30  T_3(x) = 4x^3-3x
31  T_4(x) = 8x^4-8x^2+1
32  T_5(x) = 16x^5-20x^3+5x
33  T_6(x) = 32x^6-48x^4+18x^2-1
34 
35  """
36 
37  fout = open(os.path.expanduser(outfile), "w")
38  fout.write('#ifndef ' + tablename + '_H_' + '\n')
39  fout.write('#define ' + tablename + '_H_' + '\n \n')
40  fout.write('#include <Arduino.h>'+'\n')
41  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
42  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength) +'\n')
43  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
44  try:
45  for num in range(tablelength):
46 
47  x = 2*(float(num-(tablelength/2)))/tablelength
48 
49  if curvenum == 3:
50  t_x = 4*pow(x,3)-3*x
51  elif curvenum == 4:
52  t_x = 8*pow(x,4)-8*pow(x,2)+1
53  elif curvenum == 5:
54  t_x = 16*pow(x,5)-20*pow(x,3)+5*x
55  elif curvenum == 6:
56  t_x = 32*pow(x,6)-48*pow(x,4)+18*pow(x,2)-1
57 
58  scaled = int16_t(math.floor(t_x*127.999))
59 
60  outstring += str(scaled) + ", "
61  finally:
62  outstring += "};"
63  outstring = textwrap.fill(outstring, 80)
64  fout.write(outstring)
65  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
66  fout.close()
67  print "wrote " + outfile
68 
@@ -273,7 +273,7 @@

ADSR.

-

Definition at line 192 of file ADSR.h.

+

Definition at line 188 of file ADSR.h.

@@ -311,7 +311,7 @@

Definition at line 180 of file ADSR.h.

+

Definition at line 176 of file ADSR.h.

@@ -343,7 +343,7 @@

Returns
true if playing, false if in IDLE state
-

Definition at line 431 of file ADSR.h.

+

Definition at line 427 of file ADSR.h.

@@ -392,7 +392,7 @@

Definition at line 253 of file ADSR.h.

+

Definition at line 249 of file ADSR.h.

@@ -455,7 +455,7 @@

Definition at line 415 of file ADSR.h.

+

Definition at line 411 of file ADSR.h.

@@ -493,7 +493,7 @@

Definition at line 202 of file ADSR.h.

+

Definition at line 198 of file ADSR.h.

@@ -524,7 +524,7 @@

Set the attack time of the ADSR in milliseconds.

-

The actual time taken will be resolved within the resolution of CONTROL_RATE.

Parameters
+

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.

Parameters
msecthe unsigned int attack time in milliseconds.
@@ -532,7 +532,7 @@

Note
Beware of low values (less than 20 or so, depending on how many steps are being taken), in case internal step size gets calculated as 0, which would mean nothing happens.

-

Definition at line 287 of file ADSR.h.

+

Definition at line 283 of file ADSR.h.

@@ -570,7 +570,7 @@

Definition at line 366 of file ADSR.h.

+

Definition at line 362 of file ADSR.h.

@@ -608,7 +608,7 @@

Definition at line 213 of file ADSR.h.

+

Definition at line 209 of file ADSR.h.

@@ -639,7 +639,7 @@

Set the decay time of the ADSR in milliseconds.

-

The actual time taken will be resolved within the resolution of CONTROL_RATE.

Parameters
+

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.

Parameters
msecthe unsigned int decay time in milliseconds.
@@ -647,7 +647,7 @@

Note
Beware of low values (less than 20 or so, depending on how many steps are being taken), in case internal step size gets calculated as 0, which would mean nothing happens.

-

Definition at line 300 of file ADSR.h.

+

Definition at line 296 of file ADSR.h.

@@ -685,7 +685,7 @@

Definition at line 376 of file ADSR.h.

+

Definition at line 372 of file ADSR.h.

@@ -748,7 +748,7 @@

Definition at line 270 of file ADSR.h.

+

Definition at line 266 of file ADSR.h.

@@ -786,7 +786,7 @@

Definition at line 234 of file ADSR.h.

+

Definition at line 230 of file ADSR.h.

@@ -817,7 +817,7 @@

Set the release time of the ADSR in milliseconds.

-

The actual time taken will be resolved within the resolution of CONTROL_RATE.

Parameters
+

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.

Parameters
msecthe unsigned int release time in milliseconds.
@@ -825,7 +825,7 @@

Note
Beware of low values (less than 20 or so, depending on how many steps are being taken), in case internal step size gets calculated as 0, which would mean nothing happens.

-

Definition at line 328 of file ADSR.h.

+

Definition at line 324 of file ADSR.h.

@@ -863,7 +863,7 @@

Definition at line 396 of file ADSR.h.

+

Definition at line 392 of file ADSR.h.

@@ -901,7 +901,7 @@

Definition at line 224 of file ADSR.h.

+

Definition at line 220 of file ADSR.h.

@@ -932,7 +932,7 @@

Set the sustain time of the ADSR in milliseconds.

-

The actual time taken will be resolved within the resolution of CONTROL_RATE. The sustain phase will finish if the ADSR recieves a noteOff().

Parameters
+

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE. The sustain phase will finish if the ADSR recieves a noteOff().

Parameters
msecthe unsigned int sustain time in milliseconds.
@@ -940,7 +940,7 @@

Note
Beware of low values (less than 20 or so, depending on how many steps are being taken), in case internal step size gets calculated as 0, which would mean nothing happens.

-

Definition at line 314 of file ADSR.h.

+

Definition at line 310 of file ADSR.h.

@@ -978,7 +978,7 @@

Definition at line 386 of file ADSR.h.

+

Definition at line 382 of file ADSR.h.

@@ -1031,7 +1031,7 @@

Set the attack, decay and release times of the ADSR in milliseconds.

-

The actual times will be resolved within the resolution of CONTROL_RATE.

Parameters
+

The actual times will be resolved within the resolution of MOZZI_CONTROL_RATE.

Parameters
@@ -1042,7 +1042,7 @@

Note
Beware of low values (less than 20 or so, depending on how many steps are being taken), in case internal step size gets calculated as 0, which would mean nothing happens.
-

Definition at line 351 of file ADSR.h.

+

Definition at line 347 of file ADSR.h.

@@ -1074,7 +1074,7 @@

ADSR.

Call this in updateControl().

-

Definition at line 132 of file ADSR.h.

+

Definition at line 128 of file ADSR.h.

@@ -1084,7 +1084,7 @@

    -
diff --git a/extras/doc/html/class_audio_delay-members.html b/extras/doc/html/class_audio_delay-members.html index 12a0accf8..ea7859c90 100644 --- a/extras/doc/html/class_audio_delay-members.html +++ b/extras/doc/html/class_audio_delay-members.html @@ -37,7 +37,7 @@

@@ -117,7 +117,7 @@ @@ -122,7 +122,21 @@ ControlDelay< NUM_BUFFER_SAMPLES, T > -
attack_msthe new attack time in milliseconds.
decay_msthe new decay time in milliseconds.
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
+

Detailed Description

+

template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
+class AudioDelay< NUM_BUFFER_SAMPLES, T >

+ +

Audio delay line for comb filter, flange, chorus and short echo effects.

+
Template Parameters
+
+ + +
NUM_BUFFER_SAMPLESis the length of the delay buffer in samples. This should be a power of two. The largest delay you'll fit in an atmega328 will be 512 cells, which at 16384 Hz sample rate is 31 milliseconds. More of a flanger or a doubler than an echo. The amount of memory available for delays on other chips will vary. AudioDelay() doesn't have feedback. If you want feedback, use AudioDelayFeedback().
thetype of numbers to use for the signal in the delay. The default is int8_t, but int could be useful when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
+
+
+ +

Definition at line 27 of file AudioDelay.h.

+

Public Member Functions

@@ -145,21 +159,7 @@
 Retrieve the signal in the delay line at the position delaytime_cells. More...
 
-

Detailed Description

-

template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
-class AudioDelay< NUM_BUFFER_SAMPLES, T >

- -

Audio delay line for comb filter, flange, chorus and short echo effects.

-
Template Parameters
- - - -
NUM_BUFFER_SAMPLESis the length of the delay buffer in samples. This should be a power of two. The largest delay you'll fit in an atmega328 will be 512 cells, which at 16384 Hz sample rate is 31 milliseconds. More of a flanger or a doubler than an echo. The amount of memory available for delays on other chips will vary. AudioDelay() doesn't have feedback. If you want feedback, use AudioDelayFeedback().
thetype of numbers to use for the signal in the delay. The default is int8_t, but int could be useful when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
-
-
- -

Definition at line 27 of file AudioDelay.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ AudioDelay()

@@ -190,7 +190,7 @@

Parameters
+For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
delaytime_cellsdelay time expressed in cells.
-For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * AUDIO_RATE.

@@ -369,7 +369,7 @@

    -
diff --git a/extras/doc/html/class_audio_delay_feedback-members.html b/extras/doc/html/class_audio_delay_feedback-members.html index cbd448652..173d8c647 100644 --- a/extras/doc/html/class_audio_delay_feedback-members.html +++ b/extras/doc/html/class_audio_delay_feedback-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -126,7 +126,7 @@

+
+ +

Definition at line 36 of file AudioDelayFeedback.h.

+

Public Member Functions

@@ -161,21 +175,7 @@
 Set the feedback gain. More...
 
-

Detailed Description

-

template<uint16_t NUM_BUFFER_SAMPLES, int8_t INTERP_TYPE = LINEAR>
-class AudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >

- -

Audio delay line with feedback for comb filter, flange, chorus and short echo effects.

-
Template Parameters
- - - -
NUM_BUFFER_SAMPLESis the length of the delay buffer in samples, and should be a power of two. The maximum delay length which will fit in an atmega328 is half that of a plain AudioDelay object, in this case 256 cells, or about 15 milliseconds. AudioDelayFeedback uses int16_t sized cells to accomodate the higher amplitude of direct input to the delay as well as the feedback, without losing precision. Output is only the delay line signal. If you want to mix the delay with the input, do it in your sketch. AudioDelayFeedback uses more processing and memory than a plain AudioDelay, but allows for more dramatic effects with feedback.
INTERP_TYPEa choice of LINEAR (default) or ALLPASS interpolation. LINEAR is better for sweeping delay times, ALLPASS may be better for reverb-like effects.
-
-
- -

Definition at line 40 of file AudioDelayFeedback.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ AudioDelayFeedback() [1/2]

@@ -205,12 +205,12 @@

Parameters
- +
delaytime_cellsdelay time expressed in cells. For example, 128 cells delay at AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * AUDIO_RATE.
delaytime_cellsdelay time expressed in cells. For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.

-

Definition at line 55 of file AudioDelayFeedback.h.

+

Definition at line 51 of file AudioDelayFeedback.h.

@@ -253,13 +253,13 @@

Parameters
- +
delaytime_cellsdelay time expressed in cells. For example, 128 cells delay at AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * AUDIO_RATE.
delaytime_cellsdelay time expressed in cells. For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
feedback_levelis the feedback level from -128 to 127 (representing -1 to 1).

-

Definition at line 65 of file AudioDelayFeedback.h.

+

Definition at line 61 of file AudioDelayFeedback.h.

@@ -299,7 +299,7 @@

Note
slower than next(int8_t input, uint16_t delaytime_cells)

-

Definition at line 75 of file AudioDelayFeedback.h.

+

Definition at line 71 of file AudioDelayFeedback.h.

@@ -349,7 +349,7 @@

Note
Timing: 4us
-

Definition at line 92 of file AudioDelayFeedback.h.

+

Definition at line 88 of file AudioDelayFeedback.h.

@@ -398,7 +398,7 @@

Definition at line 117 of file AudioDelayFeedback.h.

+

Definition at line 113 of file AudioDelayFeedback.h.

@@ -436,7 +436,7 @@

Definition at line 186 of file AudioDelayFeedback.h.

+

Definition at line 182 of file AudioDelayFeedback.h.

@@ -468,7 +468,7 @@

Definition at line 196 of file AudioDelayFeedback.h.

+

Definition at line 192 of file AudioDelayFeedback.h.

@@ -501,12 +501,12 @@

Parameters
- +
delaytime_cellsdelay time expressed in cells, with each cell played per tick of AUDIO_RATE. For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * AUDIO_RATE.
delaytime_cellsdelay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE. For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
-

Definition at line 208 of file AudioDelayFeedback.h.

+

Definition at line 204 of file AudioDelayFeedback.h.

@@ -539,12 +539,12 @@

Parameters
- +
delaytime_cellsdelay time expressed in cells, with each cell played per tick of AUDIO_RATE. For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * AUDIO_RATE.
delaytime_cellsdelay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE. For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
-

Definition at line 220 of file AudioDelayFeedback.h.

+

Definition at line 216 of file AudioDelayFeedback.h.

@@ -577,12 +577,12 @@

Parameters
- +
delaytime_cellsdelay time expressed in cells, with each cell played per tick of AUDIO_RATE. For example, 128 cells delay at AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * AUDIO_RATE.
delaytime_cellsdelay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE. For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
-

Definition at line 232 of file AudioDelayFeedback.h.

+

Definition at line 228 of file AudioDelayFeedback.h.

@@ -620,7 +620,7 @@

Definition at line 242 of file AudioDelayFeedback.h.

+

Definition at line 238 of file AudioDelayFeedback.h.

@@ -658,7 +658,7 @@

Definition at line 150 of file AudioDelayFeedback.h.

+

Definition at line 146 of file AudioDelayFeedback.h.

@@ -707,7 +707,7 @@

Definition at line 174 of file AudioDelayFeedback.h.

+

Definition at line 170 of file AudioDelayFeedback.h.

@@ -745,7 +745,7 @@

Definition at line 162 of file AudioDelayFeedback.h.

+

Definition at line 158 of file AudioDelayFeedback.h.

@@ -755,7 +755,7 @@

    -
diff --git a/extras/doc/html/class_cap_poll-members.html b/extras/doc/html/class_cap_poll-members.html index ef37b61b0..0c3fe94de 100644 --- a/extras/doc/html/class_cap_poll-members.html +++ b/extras/doc/html/class_cap_poll-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -113,7 +113,7 @@ + +

Public Member Functions

@@ -133,27 +146,17 @@
unsigned long count ()
 
+ITEM_TYPE * address ()
 
-

Detailed Description

-

template<class ITEM_TYPE>
-class CircularBuffer< ITEM_TYPE >

- -

Circular buffer object.

-

Has a fixed number of cells, set to 256.

Template Parameters
- - -
ITEM_TYPEthe kind of data to store, eg. int, int8_t etc.
-
-
- -

Definition at line 12 of file CircularBuffer.h.

-
+ - - - - - - - - - - - - - - -

-Public Member Functions

next (T in_value, unsigned int delaytime_cells)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
next (T in_value)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
void set (unsigned int delaytime_cells)
 Set the delay time, measured in cells. More...
 
read (unsigned int delaytime_cells)
 Retrieve the signal in the delay line at the position delaytime_cells. More...
 

Detailed Description

template<unsigned int NUM_BUFFER_SAMPLES, class T = int>
class ControlDelay< NUM_BUFFER_SAMPLES, T >

@@ -154,7 +138,23 @@

Definition at line 29 of file ControlDelay.h.

-

Member Function Documentation

+ + + + + + + + + + + + + + +

+Public Member Functions

next (T in_value, unsigned int delaytime_cells)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
next (T in_value)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
void set (unsigned int delaytime_cells)
 Set the delay time, measured in cells. More...
 
read (unsigned int delaytime_cells)
 Retrieve the signal in the delay line at the position delaytime_cells. More...
 
+

Member Function Documentation

◆ next() [1/2]

@@ -324,7 +324,7 @@

    -
diff --git a/extras/doc/html/class_d_cfilter-members.html b/extras/doc/html/class_d_cfilter-members.html index 524f99ea0..737945292 100644 --- a/extras/doc/html/class_d_cfilter-members.html +++ b/extras/doc/html/class_d_cfilter-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -113,7 +113,7 @@ @@ -206,7 +206,7 @@

Returns
the next value.
-

Definition at line 58 of file Line.h.

+

Definition at line 54 of file Line.h.

@@ -244,7 +244,7 @@

Definition at line 73 of file Line.h.

+

Definition at line 69 of file Line.h.

@@ -293,7 +293,7 @@

Definition at line 85 of file Line.h.

+

Definition at line 81 of file Line.h.

@@ -349,7 +349,7 @@

Definition at line 102 of file Line.h.

+

Definition at line 98 of file Line.h.

@@ -359,7 +359,7 @@

    -
diff --git a/extras/doc/html/class_line_3_01unsigned_01char_01_4-members.html b/extras/doc/html/class_line_3_01unsigned_01char_01_4-members.html index f67bb0abf..67da67838 100644 --- a/extras/doc/html/class_line_3_01unsigned_01char_01_4-members.html +++ b/extras/doc/html/class_line_3_01unsigned_01char_01_4-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -116,7 +116,7 @@
- +

Detailed Description

+

template<>
+class Line< unsigned char >

+ + +

Definition at line 108 of file Line.h.

+
@@ -125,13 +131,7 @@

Public Member Functions

 Line ()
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 
-

Detailed Description

-

template<>
-class Line< unsigned char >

- - -

Definition at line 112 of file Line.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Line()

@@ -158,7 +158,7 @@

Line <int> myline; makes a Line which uses ints.

-

Definition at line 122 of file Line.h.

+

Definition at line 118 of file Line.h.

@@ -189,7 +189,7 @@

Returns
the next value.
-

Definition at line 133 of file Line.h.

+

Definition at line 129 of file Line.h.

@@ -225,7 +225,7 @@

Definition at line 147 of file Line.h.

+

Definition at line 143 of file Line.h.

@@ -272,7 +272,7 @@

Definition at line 159 of file Line.h.

+

Definition at line 155 of file Line.h.

@@ -326,7 +326,7 @@

Definition at line 170 of file Line.h.

+

Definition at line 166 of file Line.h.

@@ -336,7 +336,7 @@

    -
diff --git a/extras/doc/html/class_line_3_01unsigned_01int_01_4-members.html b/extras/doc/html/class_line_3_01unsigned_01int_01_4-members.html index 6ffea7da0..5be1d822a 100644 --- a/extras/doc/html/class_line_3_01unsigned_01int_01_4-members.html +++ b/extras/doc/html/class_line_3_01unsigned_01int_01_4-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -116,7 +116,7 @@
- +

Detailed Description

+

template<>
+class Line< unsigned int >

+ + +

Definition at line 177 of file Line.h.

+
@@ -125,13 +131,7 @@

Public Member Functions

 Line ()
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 
-

Detailed Description

-

template<>
-class Line< unsigned int >

- - -

Definition at line 181 of file Line.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Line()

@@ -158,7 +158,7 @@

Line <int> myline; makes a Line which uses ints.

-

Definition at line 191 of file Line.h.

+

Definition at line 187 of file Line.h.

@@ -189,7 +189,7 @@

Returns
the next value.
-

Definition at line 202 of file Line.h.

+

Definition at line 198 of file Line.h.

@@ -225,7 +225,7 @@

Definition at line 216 of file Line.h.

+

Definition at line 212 of file Line.h.

@@ -272,7 +272,7 @@

Definition at line 228 of file Line.h.

+

Definition at line 224 of file Line.h.

@@ -326,7 +326,7 @@

Definition at line 240 of file Line.h.

+

Definition at line 236 of file Line.h.

@@ -336,7 +336,7 @@

    -
diff --git a/extras/doc/html/class_line_3_01unsigned_01long_01_4-members.html b/extras/doc/html/class_line_3_01unsigned_01long_01_4-members.html index 6c60fb8c0..a65c6b434 100644 --- a/extras/doc/html/class_line_3_01unsigned_01long_01_4-members.html +++ b/extras/doc/html/class_line_3_01unsigned_01long_01_4-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -116,7 +116,7 @@
- +

Detailed Description

+

template<>
+class Line< unsigned long >

+ + +

Definition at line 249 of file Line.h.

+
@@ -125,13 +131,7 @@

Public Member Functions

 Line ()
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 
-

Detailed Description

-

template<>
-class Line< unsigned long >

- - -

Definition at line 253 of file Line.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Line()

@@ -158,7 +158,7 @@

Line <int> myline; makes a Line which uses ints.

-

Definition at line 263 of file Line.h.

+

Definition at line 259 of file Line.h.

@@ -189,7 +189,7 @@

Returns
the next value.
-

Definition at line 274 of file Line.h.

+

Definition at line 270 of file Line.h.

@@ -225,7 +225,7 @@

Definition at line 288 of file Line.h.

+

Definition at line 284 of file Line.h.

@@ -272,7 +272,7 @@

Definition at line 300 of file Line.h.

+

Definition at line 296 of file Line.h.

@@ -326,7 +326,7 @@

Definition at line 311 of file Line.h.

+

Definition at line 307 of file Line.h.

@@ -336,7 +336,7 @@

    -
diff --git a/extras/doc/html/class_meta_oscil-members.html b/extras/doc/html/class_meta_oscil-members.html index d7997d96e..760f7bdf7 100644 --- a/extras/doc/html/class_meta_oscil-members.html +++ b/extras/doc/html/class_meta_oscil-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -131,7 +131,7 @@ @@ -270,7 +270,7 @@

Returns
the sample at the given table index.
-

Definition at line 201 of file MetaOscil.h.

+

Definition at line 197 of file MetaOscil.h.

@@ -302,7 +302,7 @@

Oscil in fractional format.

Returns
position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
-

Definition at line 112 of file MetaOscil.h.

+

Definition at line 108 of file MetaOscil.h.

@@ -334,7 +334,7 @@

Returns
the next sample.
-

Definition at line 91 of file MetaOscil.h.

+

Definition at line 87 of file MetaOscil.h.

@@ -373,7 +373,7 @@

Returns
the phase increment value which will produce a given frequency.
-

Definition at line 208 of file MetaOscil.h.

+

Definition at line 204 of file MetaOscil.h.

@@ -412,7 +412,7 @@

Returns
a sample from the table.
-

Definition at line 123 of file MetaOscil.h.

+

Definition at line 119 of file MetaOscil.h.

@@ -461,7 +461,7 @@

Definition at line 82 of file MetaOscil.h.

+

Definition at line 78 of file MetaOscil.h.

@@ -511,7 +511,7 @@

Definition at line 69 of file MetaOscil.h.

+

Definition at line 65 of file MetaOscil.h.

@@ -559,7 +559,7 @@

Definition at line 129 of file MetaOscil.h.

+

Definition at line 125 of file MetaOscil.h.

@@ -597,7 +597,7 @@

Definition at line 168 of file MetaOscil.h.

+

Definition at line 164 of file MetaOscil.h.

@@ -635,7 +635,7 @@

Definition at line 188 of file MetaOscil.h.

+

Definition at line 184 of file MetaOscil.h.

@@ -673,7 +673,7 @@

Definition at line 178 of file MetaOscil.h.

+

Definition at line 174 of file MetaOscil.h.

@@ -723,7 +723,7 @@

Definition at line 55 of file MetaOscil.h.

+

Definition at line 51 of file MetaOscil.h.

@@ -761,7 +761,7 @@

Definition at line 101 of file MetaOscil.h.

+

Definition at line 97 of file MetaOscil.h.

@@ -799,7 +799,7 @@

Definition at line 106 of file MetaOscil.h.

+

Definition at line 102 of file MetaOscil.h.

@@ -837,7 +837,7 @@

Definition at line 214 of file MetaOscil.h.

+

Definition at line 210 of file MetaOscil.h.

@@ -886,7 +886,7 @@

Definition at line 96 of file MetaOscil.h.

+

Definition at line 92 of file MetaOscil.h.

@@ -896,7 +896,7 @@

    -
diff --git a/extras/doc/html/class_metronome-members.html b/extras/doc/html/class_metronome-members.html index a9b89f3be..7f1908783 100644 --- a/extras/doc/html/class_metronome-members.html +++ b/extras/doc/html/class_metronome-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -121,7 +121,7 @@ - +

Detailed Description

+

A metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat.

+

Metronome can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
+Alternatively, start(milliseconds) will call set() and start() together. This is called Metronome to avoid conflict with the Arduino Metro library.

+ +

Definition at line 22 of file Metronome.h.

+
@@ -139,7 +145,7 @@ - + @@ -157,13 +163,7 @@ unsigned long 

Public Member Functions

 Metronome (unsigned int delay_milliseconds=0)
 Set the beats per minute. More...
 
bool ready ()
 Call this in updateControl() or updateAudio() to check if it is time for a beat. More...
 Call this in updateControl() or updateAudio() to check if it is time for a beat. More...
 
void stop ()
ticks
 
-

Detailed Description

-

A metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat.

-

Metronome can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
-Alternatively, start(milliseconds) will call set() and start() together. This is called Metronome to avoid conflict with the Arduino Metro library.

- -

Definition at line 22 of file Metronome.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Metronome()

@@ -224,7 +224,7 @@

-

Call this in updateControl() or updateAudio() to check if it is time for a beat.

+

Call this in updateControl() or updateAudio() to check if it is time for a beat.

Returns
true if the time for one is up.

Definition at line 75 of file Metronome.h.

@@ -375,7 +375,7 @@

    -
diff --git a/extras/doc/html/class_midi_to_freq_private-members.html b/extras/doc/html/class_midi_to_freq_private-members.html new file mode 100644 index 000000000..7caac6932 --- /dev/null +++ b/extras/doc/html/class_midi_to_freq_private-members.html @@ -0,0 +1,123 @@ + + + + + + + +Mozzi: Member List + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
Mozzi +  version v2.0 +
+
sound synthesis library for Arduino
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
MidiToFreqPrivate Member List
+
+
+ +

This is the complete list of members for MidiToFreqPrivate, including all inherited members.

+ + + + +
mtof(uint8_t)MidiToFreqPrivatefriend
mtof(int)MidiToFreqPrivatefriend
Q16n16_mtof(Q16n16)MidiToFreqPrivatefriend
+
+ + + + diff --git a/extras/doc/html/class_midi_to_freq_private.html b/extras/doc/html/class_midi_to_freq_private.html new file mode 100644 index 000000000..1d205e315 --- /dev/null +++ b/extras/doc/html/class_midi_to_freq_private.html @@ -0,0 +1,250 @@ + + + + + + + +Mozzi: MidiToFreqPrivate Class Reference + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
Mozzi +  version v2.0 +
+
sound synthesis library for Arduino
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
MidiToFreqPrivate Class Reference
+
+
+

Detailed Description

+
+

Definition at line 11 of file mozzi_midi.h.

+
+ + + + + + + + + + +

+Friends

int mtof (uint8_t)
 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important. More...
 
int mtof (int)
 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important. More...
 
Q16n16 Q16n16_mtof (Q16n16)
 Converts midi note number to frequency with speed and accuracy. More...
 
+

Friends And Related Function Documentation

+ +

◆ mtof [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
int mtof (uint8_t midi_note)
+
+friend
+
+ +

A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important.

+
Parameters
+ + +
midi_notea midi note number.
+
+
+
Returns
an integer approximation of the midi note's frequency.
+ +

Definition at line 71 of file mozzi_midi.h.

+ +
+
+ +

◆ mtof [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
int mtof (int midi_note)
+
+friend
+
+ +

A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important.

+
Parameters
+ + +
midi_notea midi note number.
+
+
+
Returns
an integer approximation of the midi note's frequency.
+ +

Definition at line 80 of file mozzi_midi.h.

+ +
+
+ +

◆ Q16n16_mtof

+ +
+
+ + + + + +
+ + + + + + + + +
Q16n16 Q16n16_mtof (Q16n16 midival_fractional)
+
+friend
+
+ +

Converts midi note number to frequency with speed and accuracy.

+

Q16n16_mtofLookup() is a fast alternative to (float) mtof(), and more accurate than (uint8_t) mtof(), using Q16n16 fixed-point format instead of floats or uint8_t values. Q16n16_mtof() uses cheap linear interpolation between whole midi-note frequency equivalents stored in a lookup table, so is less accurate than the float version, mtof(), for non-whole midi values.

Note
Timing: ~8 us.
+
Parameters
+ + +
midival_fractionala midi note number in Q16n16 format, for fractional values.
+
+
+
Returns
the frequency represented by the input midi note number, in Q16n16 fixed point fractional integer format, where the lower word is a fractional value.
+ +

Definition at line 97 of file mozzi_midi.h.

+ +
+
+
+
+ + + + diff --git a/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private-members.html b/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private-members.html new file mode 100644 index 000000000..1a1ba1c74 --- /dev/null +++ b/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private-members.html @@ -0,0 +1,125 @@ + + + + + + + +Mozzi: Member List + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
Mozzi +  version v2.0 +
+
sound synthesis library for Arduino
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
MozziPrivate::MozziRandPrivate Member List
+
+
+ +

This is the complete list of members for MozziPrivate::MozziRandPrivate, including all inherited members.

+ + + + + + +
autoSeed() (defined in MozziPrivate::MozziRandPrivate)MozziPrivate::MozziRandPrivatestatic
randSeed()MozziPrivate::MozziRandPrivatefriend
randSeed(uint32_t)MozziPrivate::MozziRandPrivatefriend
xorshift96()MozziPrivate::MozziRandPrivatefriend
xorshift96() (defined in MozziPrivate::MozziRandPrivate)MozziPrivate::MozziRandPrivateinlinestatic
+
+ + + + diff --git a/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private.html b/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private.html new file mode 100644 index 000000000..c0dbef91d --- /dev/null +++ b/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private.html @@ -0,0 +1,245 @@ + + + + + + + +Mozzi: MozziPrivate::MozziRandPrivate Class Reference + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
Mozzi +  version v2.0 +
+
sound synthesis library for Arduino
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
MozziPrivate::MozziRandPrivate Class Reference
+
+
+

Detailed Description

+
+

Definition at line 6 of file mozzi_rand_p.h.

+
+ + + + + +

+Static Public Member Functions

+static uint32_t xorshift96 ()
 
+static void autoSeed ()
 
+ + + + + + + + + + +

+Friends

void randSeed ()
 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function. More...
 
void randSeed (uint32_t)
 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function. More...
 
uint32_t xorshift96 ()
 Random number generator. More...
 
+

Friends And Related Function Documentation

+ +

◆ randSeed [1/2]

+ +
+
+ + + + + +
+ + + + + + + +
void randSeed ()
+
+friend
+
+ +

Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function.

+

This can be useful if you want random sequences to be different on each run of a sketch, by seeding with a fairly random input. randSeed() called without a parameter uses noise from reading the Arduino's internal temperature as the seed, a technique discussed at http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there by Rob Tillaart.

+
Note
Intialization of the random seed is done differently on different MCUs, but is nowhere near perfect for most (and for some it is not even implemented at all). Many implementations (e.g. on AVR, STM32) simply rely on reading a (hopefully noisy) internal temperature sensor. You will often get better results by calling analogRead() - not mozziAnalogRead(0), in this case! - on one or two floating (non-connected) analog pins.
+ +

Definition at line 43 of file mozzi_rand.h.

+ +
+
+ +

◆ randSeed [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
void randSeed (uint32_t seed)
+
+friend
+
+ +

Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function.

+

This can be useful if you want random sequences to be different on each run of a sketch, by seeding with fairly random input, such as analogRead() on an unconnected pin (as explained in the Arduino documentation for randomSeed(). randSeed is the same as xorshift96Seed(), but easier to remember.

Parameters
+ + +
seeda number to use as a seed.
+
+
+ +

Definition at line 32 of file mozzi_rand_p.h.

+ +
+
+ +

◆ xorshift96

+ +
+
+ + + + + +
+ + + + + + + +
uint32_t xorshift96 ()
+
+friend
+
+ +

Random number generator.

+

A faster replacement for Arduino's random function, which is too slow to use with Mozzi. Based on Marsaglia, George. (2003). Xorshift RNGs. http://www.jstatsoft.org/v08/i14/xorshift.pdf

Returns
a random 32 bit integer.
+ +

Definition at line 14 of file mozzi_rand.h.

+ +
+
+
+
+ + + + diff --git a/extras/doc/html/class_multi_resonant_filter-members.html b/extras/doc/html/class_multi_resonant_filter-members.html index adb2f67c2..f2f21ebc2 100644 --- a/extras/doc/html/class_multi_resonant_filter-members.html +++ b/extras/doc/html/class_multi_resonant_filter-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -136,7 +136,7 @@ - +

Detailed Description

+

template<typename su = uint8_t>
+class MultiResonantFilter< su >

+ +

A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime.

+

Behaves like ResonantFilter for setting the resonance and cutoff frequency. Like ResonantFilter, it can be used on different sample sizes: MultiResonantFilter<uint8_t> and MultiResonantFilter<uint16_t> have been tested. For the former, both cutoff and resonance are uint8_t, hence between 0-255. For the later, both cutoff and resonance are uint16_t, hence between 0-65535.

+ +

Definition at line 185 of file ResonantFilter.h.

+
@@ -171,13 +179,13 @@ AudioOutputStorage_t  +IntegerType< sizeof(su)+sizeof(su)>::unsigned_type  +IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type  +IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type 

Public Member Functions

void next (AudioOutputStorage_t in)
current (AudioOutputStorage_t in, Int2Type< NOTCH >)
 
-IntegerType< sizeof(su)+sizeof(su)>::unsigned_type ucfxmul (su a, typename IntegerType< sizeof(su)+sizeof(su)>::unsigned_type b)
ucfxmul (su a, typename IntegerType< sizeof(su)+sizeof(su)>::unsigned_type b)
 
-IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type ifxmul (typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type a, su b)
ifxmul (typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type a, su b)
 
-IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type fxmul (typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type b)
fxmul (typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type b)
 
+IntegerType< sizeof(su)+sizeof(su)>::unsigned_type  @@ -207,15 +215,7 @@ const su 

@@ -189,7 +197,7 @@ su 

f
 
-IntegerType< sizeof(su)+sizeof(su)>::unsigned_type fb
fb
 
AudioOutputStorage_t buf0
SHIFTED_1
 
-

Detailed Description

-

template<typename su = uint8_t>
-class MultiResonantFilter< su >

- -

A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime.

-

Behaves like ResonantFilter for setting the resonance and cutoff frequency. Like ResonantFilter, it can be used on different sample sizes: MultiResonantFilter<uint8_t> and MultiResonantFilter<uint16_t> have been tested. For the former, both cutoff and resonance are uint8_t, hence between 0-255. For the later, both cutoff and resonance are uint16_t, hence between 0-65535.

- -

Definition at line 185 of file ResonantFilter.h.

-

Member Function Documentation

+

Member Function Documentation

◆ band()

@@ -410,7 +410,7 @@

Parameters
- +
cutoffuse the range 0-255 to represent 0-8191 Hz (AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-AUDIO_RATE/2. Be careful of distortion at the lower end, especially with high resonance.
cutoffuse the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2. Be careful of distortion at the lower end, especially with high resonance.
@@ -457,7 +457,7 @@

setCutoffFreq() and setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)

Parameters
- +
cutoffrange 0-255 represents 0-8191 Hz (AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16 Be careful of distortion at the lower end, especially with high resonance.
cutoffrange 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16 Be careful of distortion at the lower end, especially with high resonance.
resonancerange 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
@@ -511,7 +511,7 @@

    -
diff --git a/extras/doc/html/class_oscil-members.html b/extras/doc/html/class_oscil-members.html index b6de2d579..f2b69b3d7 100644 --- a/extras/doc/html/class_oscil-members.html +++ b/extras/doc/html/class_oscil-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -107,26 +107,32 @@

This is the complete list of members for Oscil< NUM_TABLE_CELLS, UPDATE_RATE >, including all inherited members.

- + - + + + + + + + - - + +
atIndex(unsigned int index)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
getPhaseFractional()Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
getPhaseFractional()Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
next()Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
Oscil(const int8_t *TABLE_NAME)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
Oscil()Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
phaseIncFromFreq(int frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
phaseIncFromFreq(int frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
phMod(Q15n16 phmod_proportion)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
phMod(SFix< NI, NF > phmod_proportion)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
phMod(SFix< 15, 16 > phmod_proportion)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setFreq(int frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setFreq(float frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setFreq(UFix< NI, NF > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setFreq(UFix< 24, 8 > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setFreq(UFix< 16, 16 > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setFreq(SFix< NI, NF > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setFreq_Q16n16(Q16n16 frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setFreq_Q24n8(Q24n8 frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setPhase(unsigned int phase)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setPhaseFractional(unsigned long phase)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setPhaseInc(unsigned long phaseinc_fractional)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setPhaseFractional(uint32_t phase)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setPhaseInc(uint32_t phaseinc_fractional)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline
setTable(const int8_t *TABLE_NAME)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline

+
Note
If you #define OSCIL_DITHER_PHASE before you #include <Oscil.h>, the phase increments will be dithered, which reduces spurious frequency spurs in the audio output, at the cost of some extra processing and memory.
+

+int8_t2mozzi

+

Converting soundfiles for Mozzi There is a python script called char2mozzi.py in the Mozzi/python folder. The usage is: char2mozzi.py infilename outfilename tablename samplerate

+ +

Definition at line 59 of file Oscil.h.

+ @@ -130,57 +149,59 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + +

Public Member Functions

 Oscil (const int8_t *TABLE_NAME)
void setPhase (unsigned int phase)
 Set the phase of the Oscil. More...
 
void setPhaseFractional (unsigned long phase)
 Set the phase of the Oscil. More...
 
unsigned long getPhaseFractional ()
 Get the phase of the Oscil in fractional format. More...
 
void setPhaseFractional (uint32_t phase)
 Set the phase of the Oscil. More...
 
uint32_t getPhaseFractional ()
 Get the phase of the Oscil in fractional format. More...
 
int8_t phMod (Q15n16 phmod_proportion)
 Returns the next sample given a phase modulation value. More...
 
template<byte NI, byte NF>
int8_t phMod (SFix< NI, NF > phmod_proportion)
 Returns the next sample given a phase modulation value. More...
 
int8_t phMod (SFix< 15, 16 > phmod_proportion)
 Returns the next sample given a phase modulation value. More...
 
void setFreq (int frequency)
 Set the oscillator frequency with an unsigned int. More...
 
void setFreq (float frequency)
 Set the oscillator frequency with a float. More...
 
template<int8_t NI, int8_t NF>
void setFreq (UFix< NI, NF > frequency)
 Set the frequency using UFix<NI,NF> fixed-point number format. More...
 
void setFreq_Q24n8 (Q24n8 frequency)
 Set the frequency using Q24n8 fixed-point number format. More...
 
void setFreq (UFix< 24, 8 > frequency)
 Set the frequency using UFix<24,8> fixed-point number format. More...
 
void setFreq_Q16n16 (Q16n16 frequency)
 Set the frequency using Q16n16 fixed-point number format. More...
 
void setFreq (UFix< 16, 16 > frequency)
 Set the frequency using UFix<16,16> fixed-point number format. More...
 
template<byte NI, byte NF>
void setFreq (SFix< NI, NF > frequency)
 Set the frequency using SFix<NI,NF> fixed-point number format. More...
 
int8_t atIndex (unsigned int index)
 Returns the sample at the given table index. More...
 
unsigned long phaseIncFromFreq (int frequency)
 phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
 
void setPhaseInc (unsigned long phaseinc_fractional)
 Set a specific phase increment. More...
 
uint32_t phaseIncFromFreq (int frequency)
 phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
 
void setPhaseInc (uint32_t phaseinc_fractional)
 Set a specific phase increment. More...
 
-

Detailed Description

-

template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
-class Oscil< NUM_TABLE_CELLS, UPDATE_RATE >

- -


-Oscil plays a wavetable, cycling through the table to generate an audio or control signal.

-

The frequency of the signal can be set or changed with setFreq(), and the output of an Oscil can be produced with next() for a simple cycling oscillator, or atIndex() for a particular sample in the table.

Template Parameters
- - - -
NUM_TABLE_CELLSThis is defined in the table ".h" file the Oscil will be using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Oscil to run fast enough.
UPDATE_RATEThis will be AUDIO_RATE if the Oscil is updated in updateAudio(), or CONTROL_RATE if it's updated each time updateControl() is called. It could also be a fraction of CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load.
-
-
-
Note
If you #define OSCIL_DITHER_PHASE before you #include <Oscil.h>, the phase increments will be dithered, which reduces spurious frequency spurs in the audio output, at the cost of some extra processing and memory.
-

-int8_t2mozzi

-

Converting soundfiles for Mozzi There is a python script called char2mozzi.py in the Mozzi/python folder. The usage is: char2mozzi.py infilename outfilename tablename samplerate

- -

Definition at line 62 of file Oscil.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Oscil() [1/2]

@@ -215,7 +236,7 @@

Definition at line 72 of file Oscil.h.

+

Definition at line 69 of file Oscil.h.

@@ -247,7 +268,7 @@

Oscil with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play. The table can be set or changed on the fly with setTable(). Any tables used by the Oscil must be the same size.

-

Definition at line 82 of file Oscil.h.

+

Definition at line 79 of file Oscil.h.

@@ -287,12 +308,12 @@

Returns
the sample at the given table index.
-

Definition at line 245 of file Oscil.h.

+

Definition at line 329 of file Oscil.h.

- -

◆ getPhaseFractional()

+ +

◆ getPhaseFractional()

@@ -303,7 +324,7 @@

- + @@ -319,7 +340,7 @@

Oscil in fractional format.

Returns
position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
-

Definition at line 132 of file Oscil.h.

+

Definition at line 129 of file Oscil.h.

@@ -351,12 +372,12 @@

Returns
the next sample.
-

Definition at line 90 of file Oscil.h.

+

Definition at line 87 of file Oscil.h.

- -

◆ phaseIncFromFreq()

+ +

◆ phaseIncFromFreq()

@@ -367,7 +388,7 @@

unsigned long Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::getPhaseFractional uint32_t Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::getPhaseFractional ( )
- + @@ -381,8 +402,8 @@

-

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

-

Instead of recalculating the phase increment for each frequency in between, you can just calculate the phase increment for each end frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and use setPhaseInc() to set the phase increment at each step. (Note: I should really profile this with the oscilloscope to see if it's worth the extra confusion!)

Parameters
+

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

+

Instead of recalculating the phase increment for each frequency in between, you can just calculate the phase increment for each end frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and use setPhaseInc() to set the phase increment at each step. (Note: I should really profile this with the oscilloscope to see if it's worth the extra confusion!)

Parameters

unsigned long Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::phaseIncFromFreq uint32_t Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::phaseIncFromFreq ( int  frequency)
frequencyfor which you want to calculate a phase increment value.
@@ -390,12 +411,12 @@

Returns
the phase increment value which will produce a given frequency.
-

Definition at line 262 of file Oscil.h.

+

Definition at line 346 of file Oscil.h.

-

◆ phMod()

+

◆ phMod() [1/3]

@@ -429,12 +450,92 @@

Returns
a sample from the table.
-

Definition at line 150 of file Oscil.h.

+

Definition at line 147 of file Oscil.h.

+ +

+
+ +

◆ phMod() [2/3]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<byte NI, byte NF>
+ + + + + +
+ + + + + + + + +
int8_t Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::phMod (SFix< NI, NF > phmod_proportion)
+
+inline
+
+ +

Returns the next sample given a phase modulation value.

+
Parameters
+ + +
phmod_proportiona phase modulation value given as a proportion of the wave. The phmod_proportion parameter is a SFix<NI,NF> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in each direction. This fixed point math number is interpreted as a SFix<15,16> internally.
+
+
+
Returns
a sample from the table.
+ +

Definition at line 162 of file Oscil.h.

+ +
+
+ +

◆ phMod() [3/3]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+ + + + + +
+ + + + + + + + +
int8_t Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::phMod (SFix< 15, 16 > phmod_proportion)
+
+inline
+
+ +

Returns the next sample given a phase modulation value.

+
Parameters
+ + +
phmod_proportiona phase modulation value given as a proportion of the wave. The phmod_proportion parameter is a SFix<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in each direction.
+
+
+
Returns
a sample from the table.
+ +

Definition at line 176 of file Oscil.h.

-

◆ setFreq() [1/2]

+

◆ setFreq() [1/6]

@@ -467,12 +568,12 @@

Definition at line 165 of file Oscil.h.

+

Definition at line 190 of file Oscil.h.

-

◆ setFreq() [2/2]

+

◆ setFreq() [2/6]

@@ -505,7 +606,172 @@

Definition at line 180 of file Oscil.h.

+

Definition at line 205 of file Oscil.h.

+ +

+
+ +

◆ setFreq() [3/6]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<int8_t NI, int8_t NF>
+ + + + + +
+ + + + + + + + +
void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq (UFix< NI, NF > frequency)
+
+inline
+
+ +

Set the frequency using UFix<NI,NF> fixed-point number format.

+

This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors.

Note
This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
+
+This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
+
Parameters
+ + +
frequencyin UFix<NI,NF> fixed-point number format.
+
+
+ +

Definition at line 219 of file Oscil.h.

+ +
+
+ +

◆ setFreq() [4/6]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+ + + + + +
+ + + + + + + + +
void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq (UFix< 24, 8 > frequency)
+
+inline
+
+ +

Set the frequency using UFix<24,8> fixed-point number format.

+

This might be faster than the float version for setting low frequencies such as 1.5 Hz, or other values which may not work well with your table size. A UFix<24,8> representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE less than 64 Hz.

Parameters
+ + +
frequencyin UFix<24,8> fixed-point number format.
+
+
+ +

Definition at line 258 of file Oscil.h.

+ +
+
+ +

◆ setFreq() [5/6]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+ + + + + +
+ + + + + + + + +
void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq (UFix< 16, 16 > frequency)
+
+inline
+
+ +

Set the frequency using UFix<16,16> fixed-point number format.

+

This is useful in combination with Q16n16_mtof(), a fast alternative to mtof(), using UFix<16,16> fixed-point format instead of fractional numbers.

Note
This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
+
+This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
+
Parameters
+ + +
frequencyin UFix<16,16> fixed-point number format.
+
+
+ +

Definition at line 297 of file Oscil.h.

+ +
+
+ +

◆ setFreq() [6/6]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<byte NI, byte NF>
+ + + + + +
+ + + + + + + + +
void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq (SFix< NI, NF > frequency)
+
+inline
+
+ +

Set the frequency using SFix<NI,NF> fixed-point number format.

+

This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors.

Note
This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
+
+This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
+
Parameters
+ + +
frequencyin SFix<16,16> fixed-point number format.
+
+
+ +

Definition at line 312 of file Oscil.h.

@@ -546,7 +812,7 @@

Definition at line 220 of file Oscil.h.

+

Definition at line 273 of file Oscil.h.

@@ -584,7 +850,7 @@

Definition at line 194 of file Oscil.h.

+

Definition at line 234 of file Oscil.h.

@@ -622,12 +888,12 @@

Definition at line 112 of file Oscil.h.

+

Definition at line 109 of file Oscil.h.

- -

◆ setPhaseFractional()

+ +

◆ setPhaseFractional()

@@ -640,7 +906,7 @@

void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setPhaseFractional ( - unsigned long  + uint32_t  phase) @@ -653,19 +919,19 @@

Set the phase of the Oscil.

-

Might be useful with getPhaseFractional().

Parameters
+

Might be useful with getPhaseFractional().

Parameters
phasea position in the wavetable.
-

Definition at line 123 of file Oscil.h.

+

Definition at line 120 of file Oscil.h.

- -

◆ setPhaseInc()

+ +

◆ setPhaseInc()

@@ -678,7 +944,7 @@

void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setPhaseInc ( - unsigned long  + uint32_t  phaseinc_fractional) @@ -691,14 +957,14 @@

Set a specific phase increment.

-

See phaseIncFromFreq().

Parameters
+

See phaseIncFromFreq().

Parameters
- +
phaseinc_fractionala phase increment value as calculated by phaseIncFromFreq().
phaseinc_fractionala phase increment value as calculated by phaseIncFromFreq().
-

Definition at line 275 of file Oscil.h.

+

Definition at line 359 of file Oscil.h.

@@ -736,7 +1002,7 @@

Definition at line 100 of file Oscil.h.

+

Definition at line 97 of file Oscil.h.

@@ -746,7 +1012,7 @@

    -
diff --git a/extras/doc/html/class_p_d_resonant-members.html b/extras/doc/html/class_p_d_resonant-members.html index 7c13a10b5..085fa952a 100644 --- a/extras/doc/html/class_p_d_resonant-members.html +++ b/extras/doc/html/class_p_d_resonant-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -117,7 +117,7 @@ @@ -211,7 +211,7 @@

Returns
the next value.
-

Definition at line 50 of file Phasor.h.

+

Definition at line 46 of file Phasor.h.

@@ -250,7 +250,7 @@

Returns
the phase increment value which will produce a given frequency.
-

Definition at line 98 of file Phasor.h.

+

Definition at line 94 of file Phasor.h.

@@ -283,7 +283,7 @@

Phasor will continue incrementing from this value using any previously calculated step size.

-

Definition at line 60 of file Phasor.h.

+

Definition at line 56 of file Phasor.h.

@@ -322,7 +322,7 @@

Note
Timing 8us
-

Definition at line 72 of file Phasor.h.

+

Definition at line 68 of file Phasor.h.

@@ -360,7 +360,7 @@

Definition at line 83 of file Phasor.h.

+

Definition at line 79 of file Phasor.h.

@@ -398,7 +398,7 @@

Definition at line 108 of file Phasor.h.

+

Definition at line 104 of file Phasor.h.

@@ -408,7 +408,7 @@

    -
diff --git a/extras/doc/html/class_portamento-members.html b/extras/doc/html/class_portamento-members.html index 8420e1727..d8c973eae 100644 --- a/extras/doc/html/class_portamento-members.html +++ b/extras/doc/html/class_portamento-members.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -116,7 +116,7 @@ @@ -144,20 +157,7 @@

Public Member Functions

void setTable (const int8_t *TABLE_NAME)
 Calculate the next synthesised sample. More...
 
-

Detailed Description

-

template<int8_t ALGORITHM>
-class WavePacketSample< ALGORITHM >

- -

A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains).

-
Template Parameters
- - -
ALGORITHMoptions are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
-
-
- -

Definition at line 22 of file WavePacketSample.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

@@ -406,7 +406,7 @@

    -
diff --git a/extras/doc/html/class_wave_shaper.html b/extras/doc/html/class_wave_shaper.html index 9fa040f98..afa825193 100644 --- a/extras/doc/html/class_wave_shaper.html +++ b/extras/doc/html/class_wave_shaper.html @@ -37,7 +37,7 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
@@ -127,7 +127,7 @@ @@ -242,9 +276,53 @@

Construct an audio frame from a zero-centered value known to be in the 8 bit range.

-

On AVR, STANDADR or STANDARD_PLUS mode, this is effectively the same as calling the constructor, directly (no scaling gets applied). On platforms/configs using more bits, an appropriate left-shift will be performed.

+

On AVR, if MOZZI_OUTPUT_PWM mode, this is effectively the same as calling the constructor, directly (no scaling gets applied). On platforms/configs using more bits, an appropriate left-shift will be performed.

+ +

Definition at line 125 of file AudioOutput.h.

+ + + + +

◆ fromAlmostNBit()

+ +
+
+
+template<typename A , typename B >
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static MonoOutput MonoOutput::fromAlmostNBit (bits,
l 
)
+
+inlinestatic
+
-

Definition at line 156 of file AudioOutput.h.

+

Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit range, e.g.

+

at N=8 bits and a litte. On most platforms, this is exactly the same as fromNBit(), shifting up or down to the platforms' available resolution.

+

However, on AVR, MOZZI_OUTPUT_PWM mode (where about 8.5 bits are usable), the value will be shifted to the (almost) 9 bit range, instead of to the 8 bit range. allowing to make use of that extra half bit of resolution. In many cases it is useful to follow up this call with clip(). E.g.:

+
return MonoOutput::fromAlmostNBit(10, oscilA.next() + oscilB.next() + oscilC.next()).clip();
+

Definition at line 138 of file AudioOutput.h.

@@ -287,12 +365,12 @@

Definition at line 153 of file AudioOutput.h.

+

Definition at line 122 of file AudioOutput.h.

- -

◆ operator AudioOutput_t()

+ +

◆ operator AudioOutputStorage_t()

@@ -301,7 +379,7 @@

- + @@ -316,7 +394,7 @@

Definition at line 142 of file AudioOutput.h.

+

Definition at line 111 of file AudioOutput.h.

@@ -326,7 +404,7 @@

    -
diff --git a/extras/doc/html/struct_stereo_output-members.html b/extras/doc/html/struct_stereo_output-members.html index 01c8d5d8d..f5e5a6cff 100644 --- a/extras/doc/html/struct_stereo_output-members.html +++ b/extras/doc/html/struct_stereo_output-members.html @@ -37,7 +37,7 @@

@@ -111,10 +111,10 @@ - - - - + + + +
MonoOutput::operator AudioOutput_t MonoOutput::operator AudioOutputStorage_t ( ) const
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
from8Bit(int16_t l, int16_t r)StereoOutputinlinestatic
fromAlmostNBit(A bits, B l, B r)StereoOutputinlinestatic
fromNBit(uint8_t bits, T l, T r)StereoOutputinlinestatic
h (defined in StereoOutput)StereoOutput
l() const (defined in StereoOutput)StereoOutputinline
portable() const __attribute__((deprecated("Sketch generates stereo outputStereoOutputinline
r() const (defined in StereoOutput)StereoOutputinline
l() const (defined in StereoOutput)StereoOutputinline
portable() const __attribute__((deprecated("Sketch generates stereo outputStereoOutputinline
r() const (defined in StereoOutput)StereoOutputinline
setting (defined in StereoOutput)StereoOutput
StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r)StereoOutputinline
StereoOutput()StereoOutputinline

@@ -122,7 +122,7 @@
@@ -103,16 +99,68 @@
01.Basics/Vibrato/Vibrato.ino
-


- This is an example using Oscil::phMod to produce vibrato using phase modulation.

-
/* Example playing a sinewave with vibrato,
using Mozzi sonification library.
Demonstrates simple FM using phase modulation.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h> // for mtof
//#include <mozzi_fixmath.h>
#include <FixMath.h> // Fixed point arithmetics
Oscil<COS2048_NUM_CELLS, MOZZI_AUDIO_RATE> aCos(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_AUDIO_RATE> aVibrato(COS2048_DATA);
//const byte intensity = 255;
const UFix<0,8> intensity = 0.5; // amplitude of the phase modulation
// 0.5 leads to a modulation of half the
// wavetable
void setup(){
startMozzi();
aCos.setFreq(mtof(84.f));
aVibrato.setFreq(15.f);
}
void updateControl(){
}
AudioOutput updateAudio(){
//Q15n16 vibrato = (Q15n16) intensity * aVibrato.next();
auto vibrato = intensity * toSFraction(aVibrato.next()); // Oscils in Mozzi are 8bits: 7bits of signal plus one bit of sign, so what they fit into a SFixMath<0,7> which is a signed fixMath type with 7 bits of value.
return MonoOutput::from8Bit(aCos.phMod(vibrato)); // phase modulation to modulate frequency
}
void loop(){
audioHook();
}
+

This is an example using Oscil::phMod to produce vibrato using phase modulation.

+
/* Example playing a sinewave with vibrato,
+
using Mozzi sonification library.
+
+
Demonstrates simple FM using phase modulation.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
+
#include <Mozzi.h>
+
#include <Oscil.h>
+
#include <tables/cos2048_int8.h> // table for Oscils to play
+
#include <mozzi_midi.h> // for mtof
+
//#include <mozzi_fixmath.h>
+
#include <FixMath.h> // Fixed point arithmetics
+
+
Oscil<COS2048_NUM_CELLS, MOZZI_AUDIO_RATE> aCos(COS2048_DATA);
+
Oscil<COS2048_NUM_CELLS, MOZZI_AUDIO_RATE> aVibrato(COS2048_DATA);
+
+
//const byte intensity = 255;
+
const UFix<0,8> intensity = 0.5; // amplitude of the phase modulation
+
// 0.5 leads to a modulation of half the
+
// wavetable
+
+
void setup(){
+
startMozzi();
+
aCos.setFreq(mtof(84.f));
+
aVibrato.setFreq(15.f);
+
}
+
+
+
void updateControl(){
+
}
+
+
AudioOutput updateAudio(){
+
//Q15n16 vibrato = (Q15n16) intensity * aVibrato.next();
+
auto vibrato = intensity * toSFraction(aVibrato.next()); // Oscils in Mozzi are 8bits: 7bits of signal plus one bit of sign, so what they fit into a SFixMath<0,7> which is a signed fixMath type with 7 bits of value.
+
return MonoOutput::from8Bit(aCos.phMod(vibrato)); // phase modulation to modulate frequency
+
}
+
+
void loop(){
+
audioHook();
+
}
+
diff --git a/extras/doc/html/02_8_control_2_control__echo__theremin_2_control__echo__theremin_8ino-example.html b/extras/doc/html/02_8_control_2_control__echo__theremin_2_control__echo__theremin_8ino-example.html index 4fbf32dfb..f038b50e5 100644 --- a/extras/doc/html/02_8_control_2_control__echo__theremin_2_control__echo__theremin_8ino-example.html +++ b/extras/doc/html/02_8_control_2_control__echo__theremin_2_control__echo__theremin_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,94 @@
02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino
-


- This is an example of how to use the ControlDelay class.

-
/* Example of a simple light-sensing theremin-like
instrument with long echoes,
using Mozzi sonification library.
Demonstrates ControlDelay() for echoing control values,
and smoothing an analog input from a sensor
signal with RollingAverage().
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 64
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <RollingAverage.h>
#include <ControlDelay.h>
#define INPUT_PIN 0 // analog control input
unsigned int echo_cells_1 = 32;
unsigned int echo_cells_2 = 60;
unsigned int echo_cells_3 = 127;
ControlDelay <128, int> kDelay; // 2seconds
// oscils to compare bumpy to averaged control input
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin0(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin1(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin2(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin3(SIN2048_DATA);
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage <int, 32> kAverage; // how_many_to_average has to be power of 2
int averaged;
void setup(){
kDelay.set(echo_cells_1);
startMozzi();
}
void updateControl(){
int bumpy_input = mozziAnalogRead(INPUT_PIN);
averaged = kAverage.next(bumpy_input);
aSin0.setFreq(averaged);
aSin1.setFreq(kDelay.next(averaged));
aSin2.setFreq(kDelay.read(echo_cells_2));
aSin3.setFreq(kDelay.read(echo_cells_3));
}
AudioOutput updateAudio(){
return MonoOutput::fromAlmostNBit(12,
3*((int)aSin0.next()+aSin1.next()+(aSin2.next()>>1)
+(aSin3.next()>>2))
);
}
void loop(){
audioHook();
}
+

This is an example of how to use the ControlDelay class.

+
/* Example of a simple light-sensing theremin-like
+
instrument with long echoes,
+
using Mozzi sonification library.
+
+
Demonstrates ControlDelay() for echoing control values,
+
and smoothing an analog input from a sensor
+
signal with RollingAverage().
+
+
The circuit:
+
+
Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
+
LDR from analog pin to +5V (3.3V on Teensy 3.1)
+
5.1k resistor from analog pin to ground
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 64
+
#include <Mozzi.h>
+
#include <Oscil.h> // oscillator template
+
#include <tables/sin2048_int8.h> // sine table for oscillator
+
#include <RollingAverage.h>
+
#include <ControlDelay.h>
+
+
#define INPUT_PIN 0 // analog control input
+
+
unsigned int echo_cells_1 = 32;
+
unsigned int echo_cells_2 = 60;
+
unsigned int echo_cells_3 = 127;
+
+
ControlDelay <128, int> kDelay; // 2seconds
+
+
// oscils to compare bumpy to averaged control input
+
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin0(SIN2048_DATA);
+
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin1(SIN2048_DATA);
+
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin2(SIN2048_DATA);
+
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin3(SIN2048_DATA);
+
+
// use: RollingAverage <number_type, how_many_to_average> myThing
+
RollingAverage <int, 32> kAverage; // how_many_to_average has to be power of 2
+
int averaged;
+
+
void setup(){
+
kDelay.set(echo_cells_1);
+
startMozzi();
+
}
+
+
+
void updateControl(){
+
int bumpy_input = mozziAnalogRead<10>(INPUT_PIN); // request reading at 10-bit resolution, i.e. 0-1023
+
averaged = kAverage.next(bumpy_input);
+
aSin0.setFreq(averaged);
+
aSin1.setFreq(kDelay.next(averaged));
+
aSin2.setFreq(kDelay.read(echo_cells_2));
+
aSin3.setFreq(kDelay.read(echo_cells_3));
+
}
+
+
+
AudioOutput updateAudio(){
+
return MonoOutput::fromAlmostNBit(12,
+
3*((int)aSin0.next()+aSin1.next()+(aSin2.next()>>1)
+
+(aSin3.next()>>2))
+
);
+
}
+
+
+
void loop(){
+
audioHook();
+
}
+
diff --git a/extras/doc/html/02_8_control_2_control__tremelo_2_control__tremelo_8ino-example.html b/extras/doc/html/02_8_control_2_control__tremelo_2_control__tremelo_8ino-example.html index 9e2f6a0ce..b1c5aecb4 100644 --- a/extras/doc/html/02_8_control_2_control__tremelo_2_control__tremelo_8ino-example.html +++ b/extras/doc/html/02_8_control_2_control__tremelo_2_control__tremelo_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 02.Control/Control_Tremelo/Control_Tremelo.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,79 @@
02.Control/Control_Tremelo/Control_Tremelo.ino
-


- This example demonstrates the Line class.

-
/* Example of amplitude modulation (as tremelo),
using Mozzi sonification library.
Demonstrates audio and control rate updates.
The tremelo oscillator is updated at control rate,
and a Line is used to interpolate the control updates
at audio rate, to remove zipper noise.
A bit contrived and probably less efficient than just
using an audio-rate tremelo oscillator, but hey it's a demo!
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/triangle_valve_2048_int8.h>
#include <tables/sin2048_int8.h>
#include <Line.h>
#include <mozzi_midi.h>
// audio oscillator
Oscil<TRIANGLE_VALVE_2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSig(TRIANGLE_VALVE_2048_DATA);
// control oscillator for tremelo
Oscil<SIN2048_NUM_CELLS, MOZZI_CONTROL_RATE> kTremelo(SIN2048_DATA);
// a line to interpolate control tremolo at audio rate
Line <unsigned int> aGain;
void setup(){
aSig.setFreq(mtof(65.f));
kTremelo.setFreq(5.5f);
startMozzi();
}
void updateControl(){
// gain shifted up to give enough range for line's internal steps
unsigned int gain = (128u+kTremelo.next())<<8;
aGain.set(gain, MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE); // divide of literals should get optimised away
}
AudioOutput updateAudio(){
// cast to long before multiply to give room for intermediate result,
// and also before shift,
// to give consistent results for both 8 and 32 bit processors.
return MonoOutput::fromNBit(24, (int32_t) aSig.next() * aGain.next()); // shifted back to audio range after multiply
}
void loop(){
audioHook();
}
+

This example demonstrates the Line class.

+
/* Example of amplitude modulation (as tremelo),
+
using Mozzi sonification library.
+
+
Demonstrates audio and control rate updates.
+
The tremelo oscillator is updated at control rate,
+
and a Line is used to interpolate the control updates
+
at audio rate, to remove zipper noise.
+
A bit contrived and probably less efficient than just
+
using an audio-rate tremelo oscillator, but hey it's a demo!
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
+
#include <Mozzi.h>
+
#include <Oscil.h>
+
#include <tables/triangle_valve_2048_int8.h>
+
#include <tables/sin2048_int8.h>
+
#include <Line.h>
+
#include <mozzi_midi.h>
+
+
// audio oscillator
+
Oscil<TRIANGLE_VALVE_2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSig(TRIANGLE_VALVE_2048_DATA);
+
// control oscillator for tremelo
+
Oscil<SIN2048_NUM_CELLS, MOZZI_CONTROL_RATE> kTremelo(SIN2048_DATA);
+
// a line to interpolate control tremolo at audio rate
+
Line <unsigned int> aGain;
+
+
+
void setup(){
+
aSig.setFreq(mtof(65.f));
+
kTremelo.setFreq(5.5f);
+
startMozzi();
+
}
+
+
+
void updateControl(){
+
// gain shifted up to give enough range for line's internal steps
+
unsigned int gain = (128u+kTremelo.next())<<8;
+
aGain.set(gain, MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE); // divide of literals should get optimised away
+
}
+
+
+
AudioOutput updateAudio(){
+
// cast to long before multiply to give room for intermediate result,
+
// and also before shift,
+
// to give consistent results for both 8 and 32 bit processors.
+
return MonoOutput::fromNBit(24, (int32_t) aSig.next() * aGain.next()); // shifted back to audio range after multiply
+
}
+
+
+
void loop(){
+
audioHook();
+
}
+
diff --git a/extras/doc/html/02_8_control_2_event_delay_2_event_delay_8ino-example.html b/extras/doc/html/02_8_control_2_event_delay_2_event_delay_8ino-example.html index 17f878ad1..329b688dd 100644 --- a/extras/doc/html/02_8_control_2_event_delay_2_event_delay_8ino-example.html +++ b/extras/doc/html/02_8_control_2_event_delay_2_event_delay_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 02.Control/EventDelay/EventDelay.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,74 @@
02.Control/EventDelay/EventDelay.ino
-


- This example shows how to use the EventDelay class.

-
/* Example of a sound being toggled on an off,
using Mozzi sonification library.
Demonstrates scheduling with EventDelay.
EventDelay is a way to make non-blocking
time delays for events. Use this instead of
the Arduino delay() function, which doesn't
work with Mozzi.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 64
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin8192_int8.h> // sine table for oscillator
#include <EventDelay.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SIN8192_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN8192_DATA);
// for scheduling audio gain changes
EventDelay kGainChangeDelay;
char gain = 1;
void setup(){
startMozzi();
aSin.setFreq(330); // set the frequency
kGainChangeDelay.set(1000); // 1 second countdown, within resolution of MOZZI_CONTROL_RATE
}
void updateControl(){
if(kGainChangeDelay.ready()){
gain = 1-gain; // flip 0/1
kGainChangeDelay.start();
}
}
AudioOutput updateAudio(){
return AudioOutput::from8Bit(aSin.next()*gain);
}
void loop(){
audioHook();
}
+

This example shows how to use the EventDelay class.

+
/* Example of a sound being toggled on an off,
+
using Mozzi sonification library.
+
+
Demonstrates scheduling with EventDelay.
+
EventDelay is a way to make non-blocking
+
time delays for events. Use this instead of
+
the Arduino delay() function, which doesn't
+
work with Mozzi.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 64
+
#include <Mozzi.h>
+
#include <Oscil.h> // oscillator template
+
#include <tables/sin8192_int8.h> // sine table for oscillator
+
#include <EventDelay.h>
+
+
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
+
Oscil <SIN8192_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN8192_DATA);
+
+
// for scheduling audio gain changes
+
EventDelay kGainChangeDelay;
+
+
char gain = 1;
+
+
void setup(){
+
startMozzi();
+
aSin.setFreq(330); // set the frequency
+
kGainChangeDelay.set(1000); // 1 second countdown, within resolution of MOZZI_CONTROL_RATE
+
}
+
+
+
void updateControl(){
+
if(kGainChangeDelay.ready()){
+
gain = 1-gain; // flip 0/1
+
kGainChangeDelay.start();
+
}
+
}
+
+
+
AudioOutput updateAudio(){
+
return AudioOutput::from8Bit(aSin.next()*gain);
+
}
+
+
+
void loop(){
+
audioHook();
+
}
+
diff --git a/extras/doc/html/02_8_control_2_metronome__sample_huffman_2_metronome__sample_huffman_8ino-example.html b/extras/doc/html/02_8_control_2_metronome__sample_huffman_2_metronome__sample_huffman_8ino-example.html index fc00645c6..79b3c5229 100644 --- a/extras/doc/html/02_8_control_2_metronome__sample_huffman_2_metronome__sample_huffman_8ino-example.html +++ b/extras/doc/html/02_8_control_2_metronome__sample_huffman_2_metronome__sample_huffman_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,106 @@
02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino
-


- This example shows how to use the Metronome class.

-
/* Example using Metronome to playing samples encoded with Huffman compression.
Demonstrates Metronome start, stop and ready, and the the SampleHuffman class.
Circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Metronome.h>
#include <SampleHuffman.h>
#include <mozzi_rand.h>
#include <samples/thumbpiano_huffman/thumbpiano0.h>
#include <samples/thumbpiano_huffman/thumbpiano1.h>
#include <samples/thumbpiano_huffman/thumbpiano2.h>
#include <samples/thumbpiano_huffman/thumbpiano3.h>
#include <samples/thumbpiano_huffman/thumbpiano4.h>
SampleHuffman thumb0(THUMB0_SOUNDDATA,THUMB0_HUFFMAN,THUMB0_SOUNDDATA_BITS);
SampleHuffman thumb1(THUMB1_SOUNDDATA,THUMB1_HUFFMAN,THUMB1_SOUNDDATA_BITS);
SampleHuffman thumb2(THUMB2_SOUNDDATA,THUMB2_HUFFMAN,THUMB2_SOUNDDATA_BITS);
SampleHuffman thumb3(THUMB3_SOUNDDATA,THUMB3_HUFFMAN,THUMB3_SOUNDDATA_BITS);
SampleHuffman thumb4(THUMB4_SOUNDDATA,THUMB4_HUFFMAN,THUMB4_SOUNDDATA_BITS);
const char NUM_SAMPLES = 5;
Metronome kMetro(800); // enough delay so samples don't overlap, because the load would be too much
void setup() {
startMozzi();
}
void updateControl(){
static unsigned int counter;
counter++;
if(counter==177)kMetro.stop();
if(counter==203){kMetro.start();counter = 0;}
if(kMetro.ready()){
switch(rand(NUM_SAMPLES)){
case 0:
thumb0.start();
break;
case 1:
thumb1.start();
break;
case 2:
thumb2.start();
break;
case 3:
thumb3.start();
break;
case 4:
thumb4.start();
break;
}
}
}
AudioOutput updateAudio(){
int asig = (int)
thumb0.next() +
thumb1.next() +
thumb2.next() +
thumb3.next() +
thumb4.next();
// Note: Samples don't overlap, here, therefore this the sum is still only 8 bits range
return MonoOutput::from8Bit(asig);
}
void loop() {
audioHook();
}
+

This example shows how to use the Metronome class.

+
/* Example using Metronome to playing samples encoded with Huffman compression.
+
+
Demonstrates Metronome start, stop and ready, and the the SampleHuffman class.
+
+
Circuit:
+
Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <Metronome.h>
+
#include <SampleHuffman.h>
+
#include <mozzi_rand.h>
+
+
#include <samples/thumbpiano_huffman/thumbpiano0.h>
+
#include <samples/thumbpiano_huffman/thumbpiano1.h>
+
#include <samples/thumbpiano_huffman/thumbpiano2.h>
+
#include <samples/thumbpiano_huffman/thumbpiano3.h>
+
#include <samples/thumbpiano_huffman/thumbpiano4.h>
+
+
SampleHuffman thumb0(THUMB0_SOUNDDATA,THUMB0_HUFFMAN,THUMB0_SOUNDDATA_BITS);
+
SampleHuffman thumb1(THUMB1_SOUNDDATA,THUMB1_HUFFMAN,THUMB1_SOUNDDATA_BITS);
+
SampleHuffman thumb2(THUMB2_SOUNDDATA,THUMB2_HUFFMAN,THUMB2_SOUNDDATA_BITS);
+
SampleHuffman thumb3(THUMB3_SOUNDDATA,THUMB3_HUFFMAN,THUMB3_SOUNDDATA_BITS);
+
SampleHuffman thumb4(THUMB4_SOUNDDATA,THUMB4_HUFFMAN,THUMB4_SOUNDDATA_BITS);
+
+
const char NUM_SAMPLES = 5;
+
+
Metronome kMetro(800); // enough delay so samples don't overlap, because the load would be too much
+
+
void setup() {
+
startMozzi();
+
}
+
+
+
+
void updateControl(){
+
static unsigned int counter;
+
counter++;
+
if(counter==177)kMetro.stop();
+
if(counter==203){kMetro.start();counter = 0;}
+
if(kMetro.ready()){
+
switch(rand(NUM_SAMPLES)){
+
case 0:
+
thumb0.start();
+
break;
+
+
case 1:
+
thumb1.start();
+
break;
+
+
case 2:
+
thumb2.start();
+
break;
+
+
case 3:
+
thumb3.start();
+
break;
+
+
case 4:
+
thumb4.start();
+
break;
+
}
+
}
+
}
+
+
+
AudioOutput updateAudio(){
+
int asig = (int)
+
thumb0.next() +
+
thumb1.next() +
+
thumb2.next() +
+
thumb3.next() +
+
thumb4.next();
+
// Note: Samples don't overlap, here, therefore this the sum is still only 8 bits range
+
return MonoOutput::from8Bit(asig);
+
}
+
+
+
void loop() {
+
audioHook();
+
}
+
diff --git a/extras/doc/html/03_8_sensors_2_knob__l_d_r_x2__wave_packet_2_knob__l_d_r_x2__wave_packet_8ino-example.html b/extras/doc/html/03_8_sensors_2_knob__l_d_r_x2__wave_packet_2_knob__l_d_r_x2__wave_packet_8ino-example.html index 380b60878..2bf7a22b8 100644 --- a/extras/doc/html/03_8_sensors_2_knob__l_d_r_x2__wave_packet_2_knob__l_d_r_x2__wave_packet_8ino-example.html +++ b/extras/doc/html/03_8_sensors_2_knob__l_d_r_x2__wave_packet_2_knob__l_d_r_x2__wave_packet_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,131 @@
03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
-


- This example demonstrates the AutoMap class.

-
/*
Example of Wavepacket synthesis, using analog
inputs to change the fundamental frequency,
bandwidth and centre frequency,
using Mozzi sonification library.
Demonstrates WavePacket, mozziAnalogRead(), and smoothing
control signals with RollingAverage.
Also demonstrates AutoMap, which maps unpredictable inputs to a set range.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#include <WavePacket.h>
#include <RollingAverage.h>
#include <AutoMap.h>
#include <IntMap.h>
const int KNOB_PIN = 0; // set the input for the knob to analog pin 0
const int LDR1_PIN=1; // set the analog input for fm_intensity to pin 1
const int LDR2_PIN=2; // set the analog input for mod rate to pin 2
// min and max values of synth parameters to map AutoRanged analog inputs to
const int MIN_F = 20;
const int MAX_F = 150;
const int MIN_BW = 20;
const int MAX_BW = 600;
const int MIN_CF = 60;
const int MAX_CF = 600;
// for smoothing the control signals
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage <int, 16> kAverageF;
RollingAverage <int, 16> kAverageBw;
RollingAverage <int, 16> kAverageCf;
// Intmap is a pre-calculated faster version of Arduino's map, OK for pots
IntMap kMapF(0,1023,MIN_F,MAX_F);
// AutoMap adapts to range of input as it arrives, useful for LDR's
AutoMap kMapBw(0,1023,MIN_BW,MAX_BW);
AutoMap kMapCf(0,1023,MIN_CF,MAX_CF);
WavePacket <DOUBLE> wavey; // DOUBLE selects 2 overlapping streams
void setup(){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial.begin(115200);
// wait before starting Mozzi to receive analog reads, so AutoRange will not get 0
delay(200);
startMozzi();
}
void updateControl(){
int fundamental = mozziAnalogRead(KNOB_PIN)+1;
fundamental = kMapF(fundamental);
Serial.print("f=");
Serial.print(fundamental);
int bandwidth = mozziAnalogRead(LDR1_PIN);
bandwidth = kMapBw(bandwidth);
Serial.print("\t bw=");
Serial.print(bandwidth);
int centre_freq = mozziAnalogRead(LDR2_PIN);
centre_freq = kMapCf(centre_freq);
Serial.print("\t cf=");
Serial.print(centre_freq);
Serial.println();
wavey.set(fundamental, bandwidth, centre_freq);
}
AudioOutput updateAudio(){
return MonoOutput::from16Bit(wavey.next());
}
void loop(){
audioHook(); // required here
}
+

This example demonstrates the AutoMap class.

+
/*
+
Example of Wavepacket synthesis, using analog
+
inputs to change the fundamental frequency,
+
bandwidth and centre frequency,
+
using Mozzi sonification library.
+
+
Demonstrates WavePacket, mozziAnalogRead(), and smoothing
+
control signals with RollingAverage.
+
Also demonstrates AutoMap, which maps unpredictable inputs to a set range.
+
+
This example goes with a tutorial on the Mozzi site:
+
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
+
+
The circuit:
+
Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Potentiometer connected to analog pin 0.
+
Center pin of the potentiometer goes to the analog pin.
+
Side pins of the potentiometer go to +5V and ground
+
+
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
+
LDR from analog pin to +5V (3.3V on Teensy 3.1)
+
5.1k resistor from analog pin to ground
+
+
Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
+
LDR from analog pin to +5V (3.3V on Teensy 3.1)
+
5.1k resistor from analog pin to ground
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_ANALOG_READ_RESOLUTION 10 // code below assumes readings to be in the classic 10-bit (0-1023) range
+
#include <Mozzi.h>
+
#include <WavePacket.h>
+
#include <RollingAverage.h>
+
#include <AutoMap.h>
+
#include <IntMap.h>
+
+
const int KNOB_PIN = 0; // set the input for the knob to analog pin 0
+
const int LDR1_PIN=1; // set the analog input for fm_intensity to pin 1
+
const int LDR2_PIN=2; // set the analog input for mod rate to pin 2
+
+
// min and max values of synth parameters to map AutoRanged analog inputs to
+
const int MIN_F = 20;
+
const int MAX_F = 150;
+
+
const int MIN_BW = 20;
+
const int MAX_BW = 600;
+
+
const int MIN_CF = 60;
+
const int MAX_CF = 600;
+
+
+
// for smoothing the control signals
+
// use: RollingAverage <number_type, how_many_to_average> myThing
+
RollingAverage <int, 16> kAverageF;
+
RollingAverage <int, 16> kAverageBw;
+
RollingAverage <int, 16> kAverageCf;
+
+
// Intmap is a pre-calculated faster version of Arduino's map, OK for pots
+
IntMap kMapF(0,1023,MIN_F,MAX_F);
+
// AutoMap adapts to range of input as it arrives, useful for LDR's
+
AutoMap kMapBw(0,1023,MIN_BW,MAX_BW);
+
AutoMap kMapCf(0,1023,MIN_CF,MAX_CF);
+
+
WavePacket <DOUBLE> wavey; // DOUBLE selects 2 overlapping streams
+
+
void setup(){
+
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
+
Serial.begin(115200);
+
// wait before starting Mozzi to receive analog reads, so AutoRange will not get 0
+
delay(200);
+
startMozzi();
+
}
+
+
+
void updateControl(){
+
int fundamental = mozziAnalogRead(KNOB_PIN)+1;
+
fundamental = kMapF(fundamental);
+
Serial.print("f=");
+
Serial.print(fundamental);
+
+
int bandwidth = mozziAnalogRead(LDR1_PIN);
+
bandwidth = kMapBw(bandwidth);
+
Serial.print("\t bw=");
+
Serial.print(bandwidth);
+
+
int centre_freq = mozziAnalogRead(LDR2_PIN);
+
centre_freq = kMapCf(centre_freq);
+
Serial.print("\t cf=");
+
Serial.print(centre_freq);
+
+
Serial.println();
+
+
wavey.set(fundamental, bandwidth, centre_freq);
+
}
+
+
+
+
AudioOutput updateAudio(){
+
return MonoOutput::from16Bit(wavey.next());
+
}
+
+
+
+
void loop(){
+
audioHook(); // required here
+
}
+
diff --git a/extras/doc/html/05_8_control__filters_2_d_c_filter_2_d_c_filter_8ino-example.html b/extras/doc/html/05_8_control__filters_2_d_c_filter_2_d_c_filter_8ino-example.html index 9a531f894..2ef379fc6 100644 --- a/extras/doc/html/05_8_control__filters_2_d_c_filter_2_d_c_filter_8ino-example.html +++ b/extras/doc/html/05_8_control__filters_2_d_c_filter_2_d_c_filter_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 05.Control_Filters/DCFilter/DCFilter.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,13 @@
05.Control_Filters/DCFilter/DCFilter.ino
-


- This example demonstrates the DCFilter class.

-
/* Example of filtering an analog input to remove DC bias,
using Mozzi sonification library.
Demonstrates DCfilter(), DC-blocking filter useful for
highlighting changes in control signals.
The output of the filter settles to 0 if the incoming signal stays constant.
If the input changes, the filter output swings to track the change and
eventually settles back to 0.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <DCfilter.h>
int sensorPin = A0;
DCfilter dcFiltered(0.9); // parameter sets how long the filter takes to settle
void setup() {
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial.begin(115200);
startMozzi();
}
void updateControl(){
// read the value from the sensor:
int sensorValue = mozziAnalogRead(sensorPin);
Serial.print(sensorValue);
Serial.print(" Filtered = ");
Serial.println(dcFiltered.next(sensorValue));
}
AudioOutput updateAudio(){
return 0;
}
void loop(){
audioHook();
}
+

This example demonstrates the DCFilter class.

+
diff --git a/extras/doc/html/05_8_control__filters_2_smooth_2_smooth_8ino-example.html b/extras/doc/html/05_8_control__filters_2_smooth_2_smooth_8ino-example.html index fdc1553c9..69ac34604 100644 --- a/extras/doc/html/05_8_control__filters_2_smooth_2_smooth_8ino-example.html +++ b/extras/doc/html/05_8_control__filters_2_smooth_2_smooth_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 05.Control_Filters/Smooth/Smooth.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,98 @@
05.Control_Filters/Smooth/Smooth.ino
-


- This example demonstrates the Smooth class.

-
/* Example of a sound changing volume with and without
smoothing of the control signal to remove obvious clicks,
using Mozzi sonification library.
Demonstrates using Smooth to filter a control signal at audio rate,
EventDelay to schedule changes and rand() to choose random volumes.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
your board check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 128
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <EventDelay.h>
#include <Smooth.h>
#include <mozzi_rand.h>
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA);
// for scheduling audio gain changes
EventDelay kGainChangeDelay;
const unsigned int gainChangeMsec = 200;
// for scheduling turning smoothing on and off
EventDelay kSmoothOnOff;
const unsigned int smoothOnOffMsec = 2000;
float smoothness = 0.9975f;
Smooth <long> aSmoothGain(smoothness);
boolean smoothIsOn=true;
long target_gain = 0;
void setup(){
aSin.setFreq(330); // set the frequency
kGainChangeDelay.set(gainChangeMsec);
kSmoothOnOff.set(smoothOnOffMsec);
startMozzi();
}
void updateControl(){
// switch smoothing on and off to show the difference
if(kSmoothOnOff.ready()){
if (smoothIsOn) {
aSmoothGain.setSmoothness(0.f);
smoothIsOn = false;
}
else{
aSmoothGain.setSmoothness(smoothness);
smoothIsOn = true;
}
kSmoothOnOff.start();
}
// random volume changes
if(kGainChangeDelay.ready()){
target_gain = rand((byte) 255);
kGainChangeDelay.start();
}
}
AudioOutput updateAudio(){
return MonoOutput::from16Bit(aSmoothGain.next(target_gain) * aSin.next());
}
void loop(){
audioHook();
}
+

This example demonstrates the Smooth class.

+
/* Example of a sound changing volume with and without
+
smoothing of the control signal to remove obvious clicks,
+
using Mozzi sonification library.
+
+
Demonstrates using Smooth to filter a control signal at audio rate,
+
EventDelay to schedule changes and rand() to choose random volumes.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
your board check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 128
+
#include <Mozzi.h>
+
#include <Oscil.h> // oscillator template
+
#include <tables/sin2048_int8.h> // sine table for oscillator
+
#include <EventDelay.h>
+
#include <Smooth.h>
+
#include <mozzi_rand.h>
+
+
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA);
+
+
// for scheduling audio gain changes
+
EventDelay kGainChangeDelay;
+
const unsigned int gainChangeMsec = 200;
+
+
// for scheduling turning smoothing on and off
+
EventDelay kSmoothOnOff;
+
const unsigned int smoothOnOffMsec = 2000;
+
+
float smoothness = 0.9975f;
+
Smooth <long> aSmoothGain(smoothness);
+
boolean smoothIsOn=true;
+
long target_gain = 0;
+
+
+
void setup(){
+
aSin.setFreq(330); // set the frequency
+
kGainChangeDelay.set(gainChangeMsec);
+
kSmoothOnOff.set(smoothOnOffMsec);
+
startMozzi();
+
}
+
+
+
void updateControl(){
+
// switch smoothing on and off to show the difference
+
if(kSmoothOnOff.ready()){
+
if (smoothIsOn) {
+
aSmoothGain.setSmoothness(0.f);
+
smoothIsOn = false;
+
}
+
else{
+
aSmoothGain.setSmoothness(smoothness);
+
smoothIsOn = true;
+
}
+
kSmoothOnOff.start();
+
}
+
+
// random volume changes
+
if(kGainChangeDelay.ready()){
+
target_gain = rand((byte) 255);
+
kGainChangeDelay.start();
+
}
+
+
}
+
+
+
AudioOutput updateAudio(){
+
return MonoOutput::from16Bit(aSmoothGain.next(target_gain) * aSin.next());
+
}
+
+
+
void loop(){
+
audioHook();
+
}
+
diff --git a/extras/doc/html/05_8_control__filters_2_teensy__u_s_b__m_i_d_i_portamento_2_teensy__u_s_b__m_i_d_i_portamento_8ino-example.html b/extras/doc/html/05_8_control__filters_2_teensy__u_s_b__m_i_d_i_portamento_2_teensy__u_s_b__m_i_d_i_portamento_8ino-example.html index 1e47824bb..fb5146e6f 100644 --- a/extras/doc/html/05_8_control__filters_2_teensy__u_s_b__m_i_d_i_portamento_2_teensy__u_s_b__m_i_d_i_portamento_8ino-example.html +++ b/extras/doc/html/05_8_control__filters_2_teensy__u_s_b__m_i_d_i_portamento_2_teensy__u_s_b__m_i_d_i_portamento_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,13 @@
05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino
-


- This example demonstrates the Portamento class.

+

This example demonstrates the Portamento class.

diff --git a/extras/doc/html/05_8_control__filters_2_thermistor__over_sample_2_thermistor__over_sample_8ino-example.html b/extras/doc/html/05_8_control__filters_2_thermistor__over_sample_2_thermistor__over_sample_8ino-example.html index 697a09390..d9fd752a9 100644 --- a/extras/doc/html/05_8_control__filters_2_thermistor__over_sample_2_thermistor__over_sample_8ino-example.html +++ b/extras/doc/html/05_8_control__filters_2_thermistor__over_sample_2_thermistor__over_sample_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,133 @@
05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino
-


- This is an example demonstrating the OverSample class.

-
/*
Example of oversampling analog input from a thermistor
for increased resolution. It's a basic attempt at a biofeedback
device used as an ineffective treatment for migraines. The idea
is that if you can focus on making your hands warm, increased blood
flow to the extremities is associated with a reduced stress response.
Anyway, the bleeps sweep up if the temperature increases, down for decrease,
and level for no change. The tremelo rate increases with the temperature.
Using Mozzi sonification library.
Demonstrates OverSample object.
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Temperature dependent resistor (Thermistor) and 5.1k resistor on analog pin 1:
Thermistor from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <Line.h>
#include <tables/sin2048_int8.h> // SINe table for oscillator
#include <OverSample.h>
#include <ControlDelay.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable)
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aTremelo(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aEnvelope(SIN2048_DATA);
Line <float> freqLine;
OverSample <unsigned int, 3> overSampler; // will give 10+3=13 bits resolution, 0->8191, using 128 bytes
const byte INPUT_PIN = 1;
float ENVELOPE_DURATION = 1.f;
const byte LINE_LENGTH = (byte)((float)MOZZI_CONTROL_RATE*ENVELOPE_DURATION*0.5); // 0.5 seconds per line
// adjustments to get tremelo in useful range from oversampled temperature input
const int TREMOLO_OFFSET = 4000;
const float TREMOLO_SCALE = 0.002;
void setup(){
pinMode(INPUT_PIN,INPUT);
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial.begin(115200);
aEnvelope.setFreq(ENVELOPE_DURATION);
startMozzi();
}
void updateControl(){
float start_freq, end_freq;
static int counter, old_oversampled;
// read the variable resistor
int sensor_value = mozziAnalogRead(INPUT_PIN); // value is 0-1023
// get the next oversampled sensor value
int oversampled = overSampler.next(sensor_value);
// modulate the amplitude of the sound in proportion to the magnitude of the oversampled sensor
float tremeloRate = TREMOLO_SCALE*(oversampled-TREMOLO_OFFSET);
tremeloRate = tremeloRate*tremeloRate*tremeloRate*tremeloRate*tremeloRate;
aTremelo.setFreq(tremeloRate);
// every half second
if (--counter<0){
if (oversampled>old_oversampled){ // high tweet up if temp rose
start_freq = 550.f;
end_freq = 660.f;
}else if(oversampled<old_oversampled){ // low tweet down if temp fell
start_freq = 330.f;
end_freq = 220.f;
} else { // flat beep if no change
start_freq = 440.f;
end_freq = 440.f;
}
old_oversampled = oversampled;
counter = LINE_LENGTH-1; // reset counter
// set the line to change the main frequency
freqLine.set(start_freq,end_freq,LINE_LENGTH);
// print out for debugging
Serial.print(oversampled);Serial.print("\t");Serial.print(start_freq);Serial.print("\t");Serial.println(end_freq);
}
// update the main frequency of the sound
aSin.setFreq(freqLine.next());
}
AudioOutput updateAudio(){
return MonoOutput::from16Bit((((int)aSin.next()*(128+aTremelo.next()))>>8)*aEnvelope.next());
}
void loop(){
audioHook(); // required here
}
+

This is an example demonstrating the OverSample class.

+
+
/*
+
Example of oversampling analog input from a thermistor
+
for increased resolution. It's a basic attempt at a biofeedback
+
device used as an ineffective treatment for migraines. The idea
+
is that if you can focus on making your hands warm, increased blood
+
flow to the extremities is associated with a reduced stress response.
+
Anyway, the bleeps sweep up if the temperature increases, down for decrease,
+
and level for no change. The tremelo rate increases with the temperature.
+
Using Mozzi sonification library.
+
+
Demonstrates OverSample object.
+
+
The circuit:
+
Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Temperature dependent resistor (Thermistor) and 5.1k resistor on analog pin 1:
+
Thermistor from analog pin to +5V (3.3V on Teensy 3.1)
+
5.1k resistor from analog pin to ground
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <Oscil.h> // oscillator template
+
#include <Line.h>
+
#include <tables/sin2048_int8.h> // SINe table for oscillator
+
#include <OverSample.h>
+
#include <ControlDelay.h>
+
+
// use: Oscil <table_size, update_rate> oscilName (wavetable)
+
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA);
+
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aTremelo(SIN2048_DATA);
+
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aEnvelope(SIN2048_DATA);
+
+
Line <float> freqLine;
+
+
OverSample <unsigned int, 3> overSampler; // will give 10+3=13 bits resolution, 0->8191, using 128 bytes
+
+
const byte INPUT_PIN = 1;
+
+
float ENVELOPE_DURATION = 1.f;
+
+
const byte LINE_LENGTH = (byte)((float)MOZZI_CONTROL_RATE*ENVELOPE_DURATION*0.5); // 0.5 seconds per line
+
+
// adjustments to get tremelo in useful range from oversampled temperature input
+
const int TREMOLO_OFFSET = 4000;
+
const float TREMOLO_SCALE = 0.002;
+
+
void setup(){
+
pinMode(INPUT_PIN,INPUT);
+
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
+
Serial.begin(115200);
+
aEnvelope.setFreq(ENVELOPE_DURATION);
+
startMozzi();
+
}
+
+
+
void updateControl(){
+
float start_freq, end_freq;
+
static int counter, old_oversampled;
+
+
// read the variable resistor
+
int sensor_value = mozziAnalogRead<10>(INPUT_PIN); // value is 0-1023
+
+
// get the next oversampled sensor value
+
int oversampled = overSampler.next(sensor_value);
+
+
// modulate the amplitude of the sound in proportion to the magnitude of the oversampled sensor
+
float tremeloRate = TREMOLO_SCALE*(oversampled-TREMOLO_OFFSET);
+
tremeloRate = tremeloRate*tremeloRate*tremeloRate*tremeloRate*tremeloRate;
+
aTremelo.setFreq(tremeloRate);
+
+
// every half second
+
if (--counter<0){
+
+
if (oversampled>old_oversampled){ // high tweet up if temp rose
+
start_freq = 550.f;
+
end_freq = 660.f;
+
}else if(oversampled<old_oversampled){ // low tweet down if temp fell
+
start_freq = 330.f;
+
end_freq = 220.f;
+
} else { // flat beep if no change
+
start_freq = 440.f;
+
end_freq = 440.f;
+
}
+
old_oversampled = oversampled;
+
counter = LINE_LENGTH-1; // reset counter
+
+
// set the line to change the main frequency
+
freqLine.set(start_freq,end_freq,LINE_LENGTH);
+
+
// print out for debugging
+
Serial.print(oversampled);Serial.print("\t");Serial.print(start_freq);Serial.print("\t");Serial.println(end_freq);
+
}
+
+
// update the main frequency of the sound
+
aSin.setFreq(freqLine.next());
+
+
}
+
+
+
AudioOutput updateAudio(){
+
return MonoOutput::from16Bit((((int)aSin.next()*(128+aTremelo.next()))>>8)*aEnvelope.next());
+
}
+
+
+
void loop(){
+
audioHook(); // required here
+
}
+
diff --git a/extras/doc/html/06_8_synthesis_2_non_alias__meta_oscil_2_non_alias__meta_oscil_8ino-example.html b/extras/doc/html/06_8_synthesis_2_non_alias__meta_oscil_2_non_alias__meta_oscil_8ino-example.html index 406aabc74..b0da04e43 100644 --- a/extras/doc/html/06_8_synthesis_2_non_alias__meta_oscil_2_non_alias__meta_oscil_8ino-example.html +++ b/extras/doc/html/06_8_synthesis_2_non_alias__meta_oscil_2_non_alias__meta_oscil_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,134 @@
06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino
-


- This example demonstrates the Meta_Oscil class.

-
/* Example using a MetaOscil to generate an alias free square wave on a sweep
using Mozzi sonification library.
Waveforms which are not only sines (Saw, square, triangle) are composed by a lot of harmonics which are at frequencies multiple of the fundamental frequency.
If the frequency of one of these harmonics is higher than half the sampling frequency (https://en.wikipedia.org/wiki/Nyquist_frequency) (MOZZI_AUDIO_RATE/2 here)
it will create "aliases" (https://en.wikipedia.org/wiki/Aliasing) which will sound out of tune are they not harmonically related to the fundamental.
The higher the pitch, the more harmonics are above the Nyquist limit and the more aliased will be present for a given waveform.
One way to avoid aliases is to use "band-limited" waveforms which have a limited sets of harmonics in order to avoid them to reach the Nyquist limit.
As these waveforms are band-limited they will sound less "crunchy" if they are used at frequencies lower than what they are meant to be because they
lack the high frequency contents.
In order to paliate that, a common technique is to "swap" wave tables on the fly in order to keep the frequency content up to the Nyquist frequency but
not above. This is the principal usage of MetaOscil.
MetaOscil can be used (after construction) as a proper Oscil but really is a bunch of oscillators with only one playing.
It will switch between different oscils seemlessly depending on the asked frequency. This allows to switch between oscillators with less
and less harmonics as the pitch goes up, in order to avoid aliases, which is demonstrated by this example.
The bandlimited tables are nammed according to the max frequency they can play without bringing aliases at a given frequency. For example:
square_max_90_at_16384_512_int8.h ensures that no aliases will be present up to 90Hz at 16384Hz sampling rate (the default for Arduino).
If your sampling rate is higher (say 32768 which is the default for most 32bits platforms) this table will be able to play up to
180=90*2Hz without aliases, as the Nyquist frequency is two times higher.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, Combriat T. 2021, CC by-nc-sa.
*/
// use #define for MOZZI_CONTROL_RATE, not a constant
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <MetaOscil.h>
// All the tables used for the MetaOscil need to be included
#include <tables/BandLimited_SQUARE/512/square_max_90_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 90Hz at a sampling frequency of 16384 (or 180Hz at a sampling frequency of 32768Hz)
#include <tables/BandLimited_SQUARE/512/square_max_101_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 101Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_122_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 122Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_138_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 138Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_154_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 154Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_174_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 174Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_210_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 210Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_264_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 264Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_327_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 327Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_431_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 431Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_546_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 546Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_744_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 744Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_910_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 910Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_1170_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 1170Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_1638_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 1638Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_2730_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 2730Hz at a sampling frequency of 16384
#include <tables/BandLimited_SQUARE/512/square_max_8192_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 8192Hz at a sampling frequency of 16384 (this is basically a sine wave)
// The proper Oscillators that will be managed by the MetaOscil
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SQUARE_MAX_90_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq90(SQUARE_MAX_90_AT_16384_512_DATA);
Oscil <SQUARE_MAX_101_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq101(SQUARE_MAX_101_AT_16384_512_DATA);
Oscil <SQUARE_MAX_122_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq122(SQUARE_MAX_122_AT_16384_512_DATA);
Oscil <SQUARE_MAX_138_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq138(SQUARE_MAX_138_AT_16384_512_DATA);
Oscil <SQUARE_MAX_154_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq154(SQUARE_MAX_154_AT_16384_512_DATA);
Oscil <SQUARE_MAX_174_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq174(SQUARE_MAX_174_AT_16384_512_DATA);
Oscil <SQUARE_MAX_210_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq210(SQUARE_MAX_210_AT_16384_512_DATA);
Oscil <SQUARE_MAX_264_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq264(SQUARE_MAX_264_AT_16384_512_DATA);
Oscil <SQUARE_MAX_327_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq327(SQUARE_MAX_327_AT_16384_512_DATA);
Oscil <SQUARE_MAX_431_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq431(SQUARE_MAX_431_AT_16384_512_DATA);
Oscil <SQUARE_MAX_546_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq546(SQUARE_MAX_546_AT_16384_512_DATA);
Oscil <SQUARE_MAX_744_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq744(SQUARE_MAX_744_AT_16384_512_DATA);
Oscil <SQUARE_MAX_910_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq910(SQUARE_MAX_910_AT_16384_512_DATA);
Oscil <SQUARE_MAX_1170_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq1170(SQUARE_MAX_1170_AT_16384_512_DATA);
Oscil <SQUARE_MAX_1638_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq1638(SQUARE_MAX_1638_AT_16384_512_DATA);
Oscil <SQUARE_MAX_2730_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq2730(SQUARE_MAX_2730_AT_16384_512_DATA);
Oscil <SQUARE_MAX_8192_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq8192(SQUARE_MAX_8192_AT_16384_512_DATA);
// use: MetaOscil <table_size, update_rate, number_of_oscil> MetaoscilName. All oscils used should have the same table_size and **have to be put in increasing order of cutoff_frequencies**.
MetaOscil<SQUARE_MAX_90_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE, 16> BL_aSq {&aSq90, &aSq101, &aSq122, &aSq138, &aSq154, &aSq174, &aSq210, &aSq264, &aSq327, &aSq431, &aSq546, &aSq744, &aSq1170, &aSq1638, &aSq2730, &aSq8192};
int freq = 10;
void setup() {
// Set the cutoff frequencies for all the Oscil in the MetaOscil ie at which frequency the MetaOscil will switch to the next Oscillator. Note that these are the same frequencies than the tables names in this case.
// This have to follow the order given at the MetaOscil creation: this needs to be in increasing order.
BL_aSq.setCutoffFreqs(90, 101, 122, 138, 154, 174, 210, 264, 327, 431, 546, 744, 1170, 1638, 2730, 8192);
// Cutoff frequencies can also be set or changed individually.
BL_aSq.setCutoffFreq(3000, 14);
startMozzi();
}
void updateControl() {
// Manually increasing the frequency by 1Hz
freq += 1;
if (freq > 3000) freq = 10;
aSq90.setFreq(freq);
BL_aSq.setFreq(freq); //BL_aSq which is a metaOscil can be used just as a regular Oscil.
}
AudioOutput updateAudio() {
//return MonoOutput::from8Bit(aSq90.next()); // try to use this line instead to hear the non-band limited version, sounds a bit like a radio
return MonoOutput::from8Bit(BL_aSq.next()); // return a sample of the correct oscil to acheive no alias
}
void loop() {
audioHook(); // required here
}
+

This example demonstrates the Meta_Oscil class.

+
/* Example using a MetaOscil to generate an alias free square wave on a sweep
+
using Mozzi sonification library.
+
+
Waveforms which are not only sines (Saw, square, triangle) are composed by a lot of harmonics which are at frequencies multiple of the fundamental frequency.
+
If the frequency of one of these harmonics is higher than half the sampling frequency (https://en.wikipedia.org/wiki/Nyquist_frequency) (MOZZI_AUDIO_RATE/2 here)
+
it will create "aliases" (https://en.wikipedia.org/wiki/Aliasing) which will sound out of tune are they not harmonically related to the fundamental.
+
The higher the pitch, the more harmonics are above the Nyquist limit and the more aliased will be present for a given waveform.
+
+
One way to avoid aliases is to use "band-limited" waveforms which have a limited sets of harmonics in order to avoid them to reach the Nyquist limit.
+
As these waveforms are band-limited they will sound less "crunchy" if they are used at frequencies lower than what they are meant to be because they
+
lack the high frequency contents.
+
+
In order to paliate that, a common technique is to "swap" wave tables on the fly in order to keep the frequency content up to the Nyquist frequency but
+
not above. This is the principal usage of MetaOscil.
+
+
MetaOscil can be used (after construction) as a proper Oscil but really is a bunch of oscillators with only one playing.
+
It will switch between different oscils seemlessly depending on the asked frequency. This allows to switch between oscillators with less
+
and less harmonics as the pitch goes up, in order to avoid aliases, which is demonstrated by this example.
+
+
The bandlimited tables are nammed according to the max frequency they can play without bringing aliases at a given frequency. For example:
+
square_max_90_at_16384_512_int8.h ensures that no aliases will be present up to 90Hz at 16384Hz sampling rate (the default for Arduino).
+
If your sampling rate is higher (say 32768 which is the default for most 32bits platforms) this table will be able to play up to
+
180=90*2Hz without aliases, as the Nyquist frequency is two times higher.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2021-2024 Tom Combriat and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
// use #define for MOZZI_CONTROL_RATE, not a constant
+
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
+
#include <Mozzi.h>
+
#include <Oscil.h> // oscillator template
+
#include <MetaOscil.h>
+
+
// All the tables used for the MetaOscil need to be included
+
#include <tables/BandLimited_SQUARE/512/square_max_90_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 90Hz at a sampling frequency of 16384 (or 180Hz at a sampling frequency of 32768Hz)
+
#include <tables/BandLimited_SQUARE/512/square_max_101_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 101Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_122_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 122Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_138_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 138Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_154_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 154Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_174_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 174Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_210_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 210Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_264_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 264Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_327_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 327Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_431_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 431Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_546_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 546Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_744_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 744Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_910_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 910Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_1170_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 1170Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_1638_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 1638Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_2730_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 2730Hz at a sampling frequency of 16384
+
#include <tables/BandLimited_SQUARE/512/square_max_8192_at_16384_512_int8.h> // band limited table that guarantee no alias up to a frequency of 8192Hz at a sampling frequency of 16384 (this is basically a sine wave)
+
+
// The proper Oscillators that will be managed by the MetaOscil
+
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
+
Oscil <SQUARE_MAX_90_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq90(SQUARE_MAX_90_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_101_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq101(SQUARE_MAX_101_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_122_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq122(SQUARE_MAX_122_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_138_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq138(SQUARE_MAX_138_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_154_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq154(SQUARE_MAX_154_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_174_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq174(SQUARE_MAX_174_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_210_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq210(SQUARE_MAX_210_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_264_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq264(SQUARE_MAX_264_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_327_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq327(SQUARE_MAX_327_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_431_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq431(SQUARE_MAX_431_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_546_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq546(SQUARE_MAX_546_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_744_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq744(SQUARE_MAX_744_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_910_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq910(SQUARE_MAX_910_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_1170_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq1170(SQUARE_MAX_1170_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_1638_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq1638(SQUARE_MAX_1638_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_2730_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq2730(SQUARE_MAX_2730_AT_16384_512_DATA);
+
Oscil <SQUARE_MAX_8192_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq8192(SQUARE_MAX_8192_AT_16384_512_DATA);
+
+
// use: MetaOscil <table_size, update_rate, number_of_oscil> MetaoscilName. All oscils used should have the same table_size and **have to be put in increasing order of cutoff_frequencies**.
+
MetaOscil<SQUARE_MAX_90_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE, 16> BL_aSq {&aSq90, &aSq101, &aSq122, &aSq138, &aSq154, &aSq174, &aSq210, &aSq264, &aSq327, &aSq431, &aSq546, &aSq744, &aSq1170, &aSq1638, &aSq2730, &aSq8192};
+
+
int freq = 10;
+
+
+
void setup() {
+
// Set the cutoff frequencies for all the Oscil in the MetaOscil ie at which frequency the MetaOscil will switch to the next Oscillator. Note that these are the same frequencies than the tables names in this case.
+
// This have to follow the order given at the MetaOscil creation: this needs to be in increasing order.
+
BL_aSq.setCutoffFreqs(90, 101, 122, 138, 154, 174, 210, 264, 327, 431, 546, 744, 1170, 1638, 2730, 8192);
+
+
// Cutoff frequencies can also be set or changed individually.
+
BL_aSq.setCutoffFreq(3000, 14);
+
startMozzi();
+
}
+
+
+
void updateControl() {
+
// Manually increasing the frequency by 1Hz
+
freq += 1;
+
if (freq > 3000) freq = 10;
+
+
aSq90.setFreq(freq);
+
BL_aSq.setFreq(freq); //BL_aSq which is a metaOscil can be used just as a regular Oscil.
+
}
+
+
+
AudioOutput updateAudio() {
+
//return MonoOutput::from8Bit(aSq90.next()); // try to use this line instead to hear the non-band limited version, sounds a bit like a radio
+
return MonoOutput::from8Bit(BL_aSq.next()); // return a sample of the correct oscil to acheive no alias
+
+
}
+
+
+
void loop() {
+
audioHook(); // required here
+
}
+
diff --git a/extras/doc/html/06_8_synthesis_2_p_w_m__phasing_2_p_w_m__phasing_8ino-example.html b/extras/doc/html/06_8_synthesis_2_p_w_m__phasing_2_p_w_m__phasing_8ino-example.html index 1f5529347..fc7f73ee3 100644 --- a/extras/doc/html/06_8_synthesis_2_p_w_m__phasing_2_p_w_m__phasing_8ino-example.html +++ b/extras/doc/html/06_8_synthesis_2_p_w_m__phasing_2_p_w_m__phasing_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 06.Synthesis/PWM_Phasing/PWM_Phasing.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,67 @@
06.Synthesis/PWM_Phasing/PWM_Phasing.ino
-


- This example demonstrates the Phasor class.

-
/* Example of pulse width modulation,
using Mozzi sonification library.
Based Miller Puckette's j03.pulse.width.mod example
in the Pure Data documentation, subtracting 2 sawtooth
waves with slightly different tunings to produce a
varying phase difference.
Demonstrates Phasor().
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Phasor.h>
Phasor <MOZZI_AUDIO_RATE> aPhasor1;
Phasor <MOZZI_AUDIO_RATE> aPhasor2;
float freq = 55.f;
void setup(){
aPhasor1.setFreq(freq);
aPhasor2.setFreq(freq+0.2f);
startMozzi(); // :)
}
void updateControl(){
}
AudioOutput updateAudio(){
char asig1 = (char)(aPhasor1.next()>>24);
char asig2 = (char)(aPhasor2.next()>>24);
return MonoOutput::fromNBit(9, ((int)asig1-asig2));
}
void loop(){
audioHook(); // required here
}
+

This example demonstrates the Phasor class.

+
/* Example of pulse width modulation,
+
using Mozzi sonification library.
+
+
Based Miller Puckette's j03.pulse.width.mod example
+
in the Pure Data documentation, subtracting 2 sawtooth
+
waves with slightly different tunings to produce a
+
varying phase difference.
+
+
Demonstrates Phasor().
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <Phasor.h>
+
+
Phasor <MOZZI_AUDIO_RATE> aPhasor1;
+
Phasor <MOZZI_AUDIO_RATE> aPhasor2;
+
+
float freq = 55.f;
+
+
void setup(){
+
aPhasor1.setFreq(freq);
+
aPhasor2.setFreq(freq+0.2f);
+
startMozzi(); // :)
+
}
+
+
+
void updateControl(){
+
}
+
+
+
AudioOutput updateAudio(){
+
char asig1 = (char)(aPhasor1.next()>>24);
+
char asig2 = (char)(aPhasor2.next()>>24);
+
return MonoOutput::fromNBit(9, ((int)asig1-asig2));
+
}
+
+
+
void loop(){
+
audioHook(); // required here
+
}
+
diff --git a/extras/doc/html/06_8_synthesis_2_wave_packet_2_wave_packet_8ino-example.html b/extras/doc/html/06_8_synthesis_2_wave_packet_2_wave_packet_8ino-example.html index 23404acc9..f098214eb 100644 --- a/extras/doc/html/06_8_synthesis_2_wave_packet_2_wave_packet_8ino-example.html +++ b/extras/doc/html/06_8_synthesis_2_wave_packet_2_wave_packet_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 06.Synthesis/WavePacket/WavePacket.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,13 @@
06.Synthesis/WavePacket/WavePacket.ino
-

This is an example of how to use the WavePacket class.

+

This is an example of how to use the WavePacket class.

diff --git a/extras/doc/html/06_8_synthesis_2_wave_packet__sample_2_wave_packet__sample_8ino-example.html b/extras/doc/html/06_8_synthesis_2_wave_packet__sample_2_wave_packet__sample_8ino-example.html index cb9f50927..d260d0d95 100644 --- a/extras/doc/html/06_8_synthesis_2_wave_packet__sample_2_wave_packet__sample_8ino-example.html +++ b/extras/doc/html/06_8_synthesis_2_wave_packet__sample_2_wave_packet__sample_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -104,14 +100,91 @@

This is an example of how to use the WavePacketSample class.

-
/* Example of Wavepacket synthesis, using Mozzi sonification library.
This sketch draws on Miller Puckette's
Pure Data example, F14.wave.packet.pd, with
two overlapping streams of wave packets.
Demonstrates the WavePacketSample object, which enables a
custom sound table to be used as the audio source for wavepackets.
Circuit:
Audio output on DAC/A14 on Teensy 3.0, 3.1,
or digital pin 9 on a Uno or similar, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Potentiometer connected to analog pin 1.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Potentiometer connected to analog pin 2.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <mozzi_analog.h>
#include <WavePacketSample.h>
#include <RollingAverage.h>
#include <samples/raven_arh_int8.h>
#define FUNDAMENTAL_PIN 0
#define BANDWIDTH_PIN 1
#define CENTREFREQ_PIN 2
// for smoothing the control signals
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage <int, 32> kAverageF;
RollingAverage <int, 32> kAverageBw;
RollingAverage <int, 32> kAverageCf;
WavePacketSample <DOUBLE> wavey; // DOUBLE selects 2 overlapping streams
void setup(){
wavey.setTable(RAVEN_ARH_DATA);
pinMode(11,OUTPUT);
digitalWrite(11,LOW);
startMozzi();
}
void updateControl(){
int f = kAverageF.next(mozziAnalogRead(FUNDAMENTAL_PIN))+1;
int b = kAverageBw.next(mozziAnalogRead(BANDWIDTH_PIN));
int cf = kAverageCf.next(2*mozziAnalogRead(CENTREFREQ_PIN));
wavey.set(f, b, cf);
}
AudioOutput updateAudio(){
return MonoOutput::from16Bit(wavey.next());
}
void loop(){
audioHook(); // required here
}
+
/* Example of Wavepacket synthesis, using Mozzi sonification library.
+
This sketch draws on Miller Puckette's
+
Pure Data example, F14.wave.packet.pd, with
+
two overlapping streams of wave packets.
+
+
Demonstrates the WavePacketSample object, which enables a
+
custom sound table to be used as the audio source for wavepackets.
+
+
Circuit:
+
Audio output on DAC/A14 on Teensy 3.0, 3.1,
+
or digital pin 9 on a Uno or similar, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Potentiometer connected to analog pin 0.
+
Center pin of the potentiometer goes to the analog pin.
+
Side pins of the potentiometer go to +5V and ground
+
+
Potentiometer connected to analog pin 1.
+
Center pin of the potentiometer goes to the analog pin.
+
Side pins of the potentiometer go to +5V and ground
+
+
Potentiometer connected to analog pin 2.
+
Center pin of the potentiometer goes to the analog pin.
+
Side pins of the potentiometer go to +5V and ground
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <mozzi_analog.h>
+
#include <WavePacketSample.h>
+
#include <RollingAverage.h>
+
#include <samples/raven_arh_int8.h>
+
+
#define FUNDAMENTAL_PIN 0
+
#define BANDWIDTH_PIN 1
+
#define CENTREFREQ_PIN 2
+
+
// for smoothing the control signals
+
// use: RollingAverage <number_type, how_many_to_average> myThing
+
RollingAverage <int, 32> kAverageF;
+
RollingAverage <int, 32> kAverageBw;
+
RollingAverage <int, 32> kAverageCf;
+
+
WavePacketSample <DOUBLE> wavey; // DOUBLE selects 2 overlapping streams
+
+
+
void setup(){
+
wavey.setTable(RAVEN_ARH_DATA);
+
pinMode(11,OUTPUT);
+
digitalWrite(11,LOW);
+
startMozzi();
+
}
+
+
+
void updateControl(){
+
int f = kAverageF.next(mozziAnalogRead<10>(FUNDAMENTAL_PIN))+1;
+
int b = kAverageBw.next(mozziAnalogRead<10>(BANDWIDTH_PIN));
+
int cf = kAverageCf.next(mozziAnalogRead<11>(CENTREFREQ_PIN));
+
wavey.set(f, b, cf);
+
}
+
+
+
AudioOutput updateAudio(){
+
return MonoOutput::from16Bit(wavey.next());
+
}
+
+
+
void loop(){
+
audioHook(); // required here
+
}
+
diff --git a/extras/doc/html/06_8_synthesis_2_wave_shaper_2_wave_shaper_8ino-example.html b/extras/doc/html/06_8_synthesis_2_wave_shaper_2_wave_shaper_8ino-example.html index 24186466c..2d438ea14 100644 --- a/extras/doc/html/06_8_synthesis_2_wave_shaper_2_wave_shaper_8ino-example.html +++ b/extras/doc/html/06_8_synthesis_2_wave_shaper_2_wave_shaper_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 06.Synthesis/WaveShaper/WaveShaper.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,13 @@
06.Synthesis/WaveShaper/WaveShaper.ino
-

This is an example of how to use the WaveShaper class.

-
/* Example using waveshaping to modify the spectrum of an audio signal
using Mozzi sonification library.
Demonstrates the use of WaveShaper(), EventDelay(), Smooth(),
rand(), and fixed-point numbers.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <WaveShaper.h>
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <Smooth.h>
#include <tables/sin2048_int8.h>
#include <tables/waveshape_chebyshev_3rd_256_int8.h>
#include <tables/waveshape_chebyshev_6th_256_int8.h>
#include <tables/waveshape_compress_512_to_488_int16.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA); // sine wave sound source
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aGain1(SIN2048_DATA); // to fade sine wave in and out before waveshaping
Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aGain2(SIN2048_DATA); // to fade sine wave in and out before waveshaping
// Chebyshev polynomial curves, The nth curve produces the n+2th harmonic component.
WaveShaper <char> aCheby3rd(CHEBYSHEV_3RD_256_DATA); // 5th harmonic
WaveShaper <char> aCheby6th(CHEBYSHEV_6TH_256_DATA); // 8th harmonic
WaveShaper <int> aCompress(WAVESHAPE_COMPRESS_512_TO_488_DATA); // to compress instead of dividing by 2 after adding signals
// for scheduling note changes
EventDelay kChangeNoteDelay;
// for random notes
Q8n0 octave_start_note = 42;
Q24n8 carrier_freq; // unsigned long with 24 integer bits and 8 fractional bits
// smooth transitions between notes
Smooth <unsigned int> kSmoothFreq(0.85f);
int target_freq, smoothed_freq;
void setup(){
startMozzi(); // :)
randSeed(); // reseed the random generator for different results each time the sketch runs
aSin.setFreq(110); // set the frequency
aGain1.setFreq(2.f); // use a float for low frequencies, in setup it doesn't need to be fast
aGain2.setFreq(.4f);
kChangeNoteDelay.set(4000); // note duration ms, within resolution of MOZZI_CONTROL_RATE
}
byte rndPentatonic(){
byte note = rand((byte)5);
switch(note){
case 0:
note = 0;
break;
case 1:
note = 3;
break;
case 2:
note = 5;
break;
case 3:
note = 7;
break;
case 4:
note = 10;
break;
}
return note;
}
void updateControl(){
if(kChangeNoteDelay.ready()){
if(rand((byte)5)==0){ // about 1 in 5 or so
// change octave to midi 24 or any of 3 octaves above
octave_start_note = (rand((byte)4)*12)+36;
}
Q16n16 midi_note = Q8n0_to_Q16n16(octave_start_note+rndPentatonic());
target_freq = Q16n16_to_Q16n0(Q16n16_mtof(midi_note)); // has to be 16 bits for Smooth
kChangeNoteDelay.start();
}
smoothed_freq = kSmoothFreq.next(target_freq*4); // temporarily scale up target_freq to get better int smoothing at low values
aSin.setFreq(smoothed_freq/4); // then scale it back down after it's smoothed
}
AudioOutput updateAudio(){
char asig0 = aSin.next(); // sine wave source
// make 2 signals fading in and out to show effect of amplitude when waveshaping with Chebyshev polynomial curves
// offset the signals by 128 to fit in the 0-255 range for the waveshaping table lookups
byte asig1 = (byte)128+((asig0*((byte)128+aGain1.next()))>>8);
byte asig2 = (byte)128+((asig0*((byte)128+aGain2.next()))>>8);
// get the waveshaped signals
char awaveshaped1 = aCheby3rd.next(asig1);
char awaveshaped2 = aCheby6th.next(asig2);
// use a waveshaping table to squeeze 2 summed 8 bit signals into the range -244 to 243
int awaveshaped3 = aCompress.next(256u + awaveshaped1 + awaveshaped2);
return MonoOutput::fromAlmostNBit(9, awaveshaped3);
}
void loop(){
audioHook(); // required here
}
+

This is an example of how to use the WaveShaper class.

+
diff --git a/extras/doc/html/07_8_envelopes_2_a_d_s_r__envelope_2_a_d_s_r__envelope_8ino-example.html b/extras/doc/html/07_8_envelopes_2_a_d_s_r__envelope_2_a_d_s_r__envelope_8ino-example.html index 03d7b0dd7..f13b7fca6 100644 --- a/extras/doc/html/07_8_envelopes_2_a_d_s_r__envelope_2_a_d_s_r__envelope_8ino-example.html +++ b/extras/doc/html/07_8_envelopes_2_a_d_s_r__envelope_2_a_d_s_r__envelope_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 07.Envelopes/ADSR_Envelope/ADSR_Envelope.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,13 @@
07.Envelopes/ADSR_Envelope/ADSR_Envelope.ino
-

This is an example of how to use the ADSR class.

-
+

This is an example of how to use the ADSR class.

+
diff --git a/extras/doc/html/07_8_envelopes_2_ead__envelope_2_ead__envelope_8ino-example.html b/extras/doc/html/07_8_envelopes_2_ead__envelope_2_ead__envelope_8ino-example.html index 97d3b23b0..a97d04b8e 100644 --- a/extras/doc/html/07_8_envelopes_2_ead__envelope_2_ead__envelope_8ino-example.html +++ b/extras/doc/html/07_8_envelopes_2_ead__envelope_2_ead__envelope_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 07.Envelopes/Ead_Envelope/Ead_Envelope.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,81 @@
07.Envelopes/Ead_Envelope/Ead_Envelope.ino
-


- This is an example of how to use the Ead class.

-
/* Example playing an enveloped noise source
using Mozzi sonification library.
Demonstrates Ead (exponential attack decay).
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa
*/
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/brownnoise8192_int8.h> // recorded audio wavetable
#include <Ead.h> // exponential attack decay
#include <EventDelay.h>
#include <mozzi_rand.h>
Oscil<BROWNNOISE8192_NUM_CELLS, MOZZI_AUDIO_RATE> aNoise(BROWNNOISE8192_DATA);
EventDelay kDelay; // for triggering envelope start
Ead kEnvelope(MOZZI_CONTROL_RATE); // resolution will be MOZZI_CONTROL_RATE
int gain;
void setup(){
// use float to set freq because it will be small and fractional
aNoise.setFreq((float)MOZZI_AUDIO_RATE/BROWNNOISE8192_SAMPLERATE);
randSeed(); // fresh random, MUST be called before startMozzi - wierd bug
startMozzi();
kDelay.start(1000);
}
void updateControl(){
// jump around in audio noise table to disrupt obvious looping
aNoise.setPhase(rand((unsigned int)BROWNNOISE8192_NUM_CELLS));
if(kDelay.ready()){
// set random parameters
unsigned int duration = rand(500u)+200;
unsigned int attack = rand(75)+5; // +5 so the internal step size is more likely to be >0
unsigned int decay = duration - attack;
kEnvelope.start(attack,decay);
kDelay.start(duration+500);
}
gain = (int) kEnvelope.next();
}
AudioOutput updateAudio(){
return MonoOutput::from16Bit(gain*aNoise.next());
}
void loop(){
audioHook(); // required here
}
+

This is an example of how to use the Ead class.

+
/* Example playing an enveloped noise source
+
using Mozzi sonification library.
+
+
Demonstrates Ead (exponential attack decay).
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
+
#include <Mozzi.h>
+
#include <Oscil.h> // oscillator template
+
#include <tables/brownnoise8192_int8.h> // recorded audio wavetable
+
#include <Ead.h> // exponential attack decay
+
#include <EventDelay.h>
+
#include <mozzi_rand.h>
+
+
Oscil<BROWNNOISE8192_NUM_CELLS, MOZZI_AUDIO_RATE> aNoise(BROWNNOISE8192_DATA);
+
EventDelay kDelay; // for triggering envelope start
+
Ead kEnvelope(MOZZI_CONTROL_RATE); // resolution will be MOZZI_CONTROL_RATE
+
+
int gain;
+
+
+
void setup(){
+
// use float to set freq because it will be small and fractional
+
aNoise.setFreq((float)MOZZI_AUDIO_RATE/BROWNNOISE8192_SAMPLERATE);
+
randSeed(); // fresh random, MUST be called before startMozzi - wierd bug
+
startMozzi();
+
kDelay.start(1000);
+
}
+
+
+
void updateControl(){
+
// jump around in audio noise table to disrupt obvious looping
+
aNoise.setPhase(rand((unsigned int)BROWNNOISE8192_NUM_CELLS));
+
+
if(kDelay.ready()){
+
// set random parameters
+
unsigned int duration = rand(500u)+200;
+
unsigned int attack = rand(75)+5; // +5 so the internal step size is more likely to be >0
+
unsigned int decay = duration - attack;
+
kEnvelope.start(attack,decay);
+
kDelay.start(duration+500);
+
}
+
gain = (int) kEnvelope.next();
+
}
+
+
+
AudioOutput updateAudio(){
+
return MonoOutput::from16Bit(gain*aNoise.next());
+
}
+
+
+
void loop(){
+
audioHook(); // required here
+
}
+
diff --git a/extras/doc/html/08_8_samples_2_sample_2_sample_8ino-example.html b/extras/doc/html/08_8_samples_2_sample_2_sample_8ino-example.html index 053aaaf9f..179f972a4 100644 --- a/extras/doc/html/08_8_samples_2_sample_2_sample_8ino-example.html +++ b/extras/doc/html/08_8_samples_2_sample_2_sample_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 08.Samples/Sample/Sample.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,68 @@
08.Samples/Sample/Sample.ino
-


- This example demonstrates the Sample class.

-
/* Example of playing a sampled sound,
using Mozzi sonification library.
Demonstrates one-shot samples scheduled
with EventDelay.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include <samples/burroughs1_18649_int8.h>
#include <EventDelay.h>
// use: Sample <table_size, update_rate> SampleName (wavetable)
Sample <BURROUGHS1_18649_NUM_CELLS, MOZZI_AUDIO_RATE> aSample(BURROUGHS1_18649_DATA);
// for scheduling sample start
EventDelay kTriggerDelay;
void setup(){
startMozzi();
aSample.setFreq((float) BURROUGHS1_18649_SAMPLERATE / (float) BURROUGHS1_18649_NUM_CELLS); // play at the speed it was recorded
kTriggerDelay.set(1500); // 1500 msec countdown, within resolution of MOZZI_CONTROL_RATE
}
void updateControl(){
if(kTriggerDelay.ready()){
aSample.start();
kTriggerDelay.start();
}
}
AudioOutput updateAudio(){
return MonoOutput::from8Bit((int) aSample.next());
}
void loop(){
audioHook();
}
+

This example demonstrates the Sample class.

+
/* Example of playing a sampled sound,
+
using Mozzi sonification library.
+
+
Demonstrates one-shot samples scheduled
+
with EventDelay.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <Sample.h> // Sample template
+
#include <samples/burroughs1_18649_int8.h>
+
#include <EventDelay.h>
+
+
// use: Sample <table_size, update_rate> SampleName (wavetable)
+
Sample <BURROUGHS1_18649_NUM_CELLS, MOZZI_AUDIO_RATE> aSample(BURROUGHS1_18649_DATA);
+
+
// for scheduling sample start
+
EventDelay kTriggerDelay;
+
+
void setup(){
+
startMozzi();
+
aSample.setFreq((float) BURROUGHS1_18649_SAMPLERATE / (float) BURROUGHS1_18649_NUM_CELLS); // play at the speed it was recorded
+
kTriggerDelay.set(1500); // 1500 msec countdown, within resolution of MOZZI_CONTROL_RATE
+
}
+
+
+
void updateControl(){
+
if(kTriggerDelay.ready()){
+
aSample.start();
+
kTriggerDelay.start();
+
}
+
}
+
+
+
AudioOutput updateAudio(){
+
return MonoOutput::from8Bit((int) aSample.next());
+
}
+
+
+
void loop(){
+
audioHook();
+
}
+
diff --git a/extras/doc/html/08_8_samples_2_sample_huffman__umpah_2_sample_huffman__umpah_8ino-example.html b/extras/doc/html/08_8_samples_2_sample_huffman__umpah_2_sample_huffman__umpah_8ino-example.html index 3b5224bd1..97f402164 100644 --- a/extras/doc/html/08_8_samples_2_sample_huffman__umpah_2_sample_huffman__umpah_8ino-example.html +++ b/extras/doc/html/08_8_samples_2_sample_huffman__umpah_2_sample_huffman__umpah_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,85 @@
08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino
-


- This example demonstrates the Sample class.

-
/*
Example playing samples encoded with Huffman compression.
Demonstrates the SampleHuffman class.
SampleHuffman, most of this explanation, and the audio2huff.py script are adapted from "audioout",
an Arduino sketch by Thomas Grill, 2011 http//grrrr.org.
Huffman decoding is used on sample differentials,
saving 50-70% of space for 8 bit data, depending on the sample rate.
This implementation just plays back one sample each time next() is called, with no
speed or other adjustments. It's slow, so it's likely you will only be able to play one sound at a time.
Audio data, Huffman decoder table, sample rate and bit depth are defined
in a sounddata.h header file. This file can be generated for a sound file with the
accompanying Python script audio2huff.py, in Mozzi/extras/python/
Invoke with:
python audio2huff.py --sndfile=arduinosnd.wav --hdrfile=sounddata.h --bits=8 --name=soundtablename
You can resample and dither your audio file with SOX,
e.g. to 8 bits depth @ Mozzi's 16384 Hz sample rate:
sox fullglory.wav -b 8 -r 16384 arduinosnd.wav
Alternatively you can export a sound from Audacity, which seems to have less noticeable or no dithering,
using Project Rate 16384 Hz and these output options:
Other uncompressed files, Header: WAV(Microsoft), Encoding: Unsigned 8 bit PCM
The header file contains two lengthy arrays:
One is "SOUNDDATA" which must fit into Flash RAM (available in total: 32k for ATMega328)
The other is "HUFFMAN" which must also fit into Flash RAM
Circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <SampleHuffman.h>
#include "umpah_huff.h"
SampleHuffman umpah(UMPAH_SOUNDDATA,UMPAH_HUFFMAN,UMPAH_SOUNDDATA_BITS);
void setup() {
umpah.setLoopingOn();
startMozzi();
}
void updateControl(){
}
AudioOutput updateAudio(){
return MonoOutput::from8Bit(umpah.next());
}
void loop() {
audioHook();
}
+

This example demonstrates the Sample class.

+
/*
+
Example playing samples encoded with Huffman compression.
+
+
Demonstrates the SampleHuffman class.
+
SampleHuffman, most of this explanation, and the audio2huff.py script are adapted from "audioout",
+
an Arduino sketch by Thomas Grill, 2011 http//grrrr.org.
+
+
Huffman decoding is used on sample differentials,
+
saving 50-70% of space for 8 bit data, depending on the sample rate.
+
+
This implementation just plays back one sample each time next() is called, with no
+
speed or other adjustments. It's slow, so it's likely you will only be able to play one sound at a time.
+
+
Audio data, Huffman decoder table, sample rate and bit depth are defined
+
in a sounddata.h header file. This file can be generated for a sound file with the
+
accompanying Python script audio2huff.py, in Mozzi/extras/python/
+
+
Invoke with:
+
python audio2huff.py --sndfile=arduinosnd.wav --hdrfile=sounddata.h --bits=8 --name=soundtablename
+
+
You can resample and dither your audio file with SOX,
+
e.g. to 8 bits depth @ Mozzi's 16384 Hz sample rate:
+
sox fullglory.wav -b 8 -r 16384 arduinosnd.wav
+
+
Alternatively you can export a sound from Audacity, which seems to have less noticeable or no dithering,
+
using Project Rate 16384 Hz and these output options:
+
Other uncompressed files, Header: WAV(Microsoft), Encoding: Unsigned 8 bit PCM
+
+
The header file contains two lengthy arrays:
+
One is "SOUNDDATA" which must fit into Flash RAM (available in total: 32k for ATMega328)
+
The other is "HUFFMAN" which must also fit into Flash RAM
+
+
Circuit:
+
Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <SampleHuffman.h>
+
#include "umpah_huff.h"
+
+
SampleHuffman umpah(UMPAH_SOUNDDATA,UMPAH_HUFFMAN,UMPAH_SOUNDDATA_BITS);
+
+
void setup() {
+
umpah.setLoopingOn();
+
startMozzi();
+
}
+
+
+
void updateControl(){
+
}
+
+
+
AudioOutput updateAudio(){
+
return MonoOutput::from8Bit(umpah.next());
+
}
+
+
+
void loop() {
+
audioHook();
+
}
+
diff --git a/extras/doc/html/09_8_delays_2_audio_delay_2_audio_delay_8ino-example.html b/extras/doc/html/09_8_delays_2_audio_delay_2_audio_delay_8ino-example.html index 9dab97de4..3b87aeb04 100644 --- a/extras/doc/html/09_8_delays_2_audio_delay_2_audio_delay_8ino-example.html +++ b/extras/doc/html/09_8_delays_2_audio_delay_2_audio_delay_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 09.Delays/AudioDelay/AudioDelay.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,65 @@
09.Delays/AudioDelay/AudioDelay.ino
-


- This is an example of how to use the AudioDelay class.

-
/* Example of modulating a signal by using a variable delay,
using Mozzi sonification library.
Demonstrates AudioDelay.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/triangle_analogue512_int8.h> // wavetable
#include <tables/cos2048_int8.h> // wavetable
#include <AudioDelay.h>
#include <mozzi_midi.h> // for mtof
Oscil<TRIANGLE_ANALOGUE512_NUM_CELLS, MOZZI_AUDIO_RATE> aTriangle(TRIANGLE_ANALOGUE512_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFreq(COS2048_DATA);
AudioDelay <256> aDel;
int del_samps;
void setup(){
aTriangle.setFreq(mtof(60.f));
kFreq.setFreq(.63f);
startMozzi();
}
void loop(){
audioHook();
}
void updateControl(){
del_samps = 128+kFreq.next();
}
AudioOutput updateAudio(){
char asig = aDel.next(aTriangle.next(), del_samps);
return MonoOutput::from8Bit(asig);
}
+

This is an example of how to use the AudioDelay class.

+
/* Example of modulating a signal by using a variable delay,
+
using Mozzi sonification library.
+
+
Demonstrates AudioDelay.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
+
#include <Mozzi.h>
+
#include <Oscil.h>
+
#include <tables/triangle_analogue512_int8.h> // wavetable
+
#include <tables/cos2048_int8.h> // wavetable
+
#include <AudioDelay.h>
+
#include <mozzi_midi.h> // for mtof
+
+
Oscil<TRIANGLE_ANALOGUE512_NUM_CELLS, MOZZI_AUDIO_RATE> aTriangle(TRIANGLE_ANALOGUE512_DATA);
+
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFreq(COS2048_DATA);
+
+
AudioDelay <256> aDel;
+
int del_samps;
+
+
void setup(){
+
aTriangle.setFreq(mtof(60.f));
+
kFreq.setFreq(.63f);
+
startMozzi();
+
}
+
+
void loop(){
+
audioHook();
+
}
+
+
void updateControl(){
+
del_samps = 128+kFreq.next();
+
}
+
+
AudioOutput updateAudio(){
+
char asig = aDel.next(aTriangle.next(), del_samps);
+
return MonoOutput::from8Bit(asig);
+
}
+
diff --git a/extras/doc/html/09_8_delays_2_audio_delay_feedback_2_audio_delay_feedback_8ino-example.html b/extras/doc/html/09_8_delays_2_audio_delay_feedback_2_audio_delay_feedback_8ino-example.html index 9221a67c1..366b4c387 100644 --- a/extras/doc/html/09_8_delays_2_audio_delay_feedback_2_audio_delay_feedback_8ino-example.html +++ b/extras/doc/html/09_8_delays_2_audio_delay_feedback_2_audio_delay_feedback_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,83 @@
09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino
-


- This is an example of how to use the AudioDelayFeedback class.

-
/* Example of flanging,
using Mozzi sonification library.
Demonstrates AudioDelayFeedback.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012-13, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/triangle_analogue512_int8.h> // wavetable
#include <tables/triangle512_int8.h> // wavetable
#include <AudioDelayFeedback.h>
#include <mozzi_midi.h> // for mtof
Oscil<TRIANGLE_ANALOGUE512_NUM_CELLS, MOZZI_AUDIO_RATE> aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator
Oscil<TRIANGLE512_NUM_CELLS, MOZZI_CONTROL_RATE> kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples
AudioDelayFeedback <128> aDel;
// the delay time, measured in samples, updated in updateControl, and used in updateAudio
byte del_samps;
void setup(){
startMozzi();
aTriangle.setFreq(mtof(48.f));
kDelSamps.setFreq(.163f); // set the delay time modulation frequency (ie. the sweep frequency)
aDel.setFeedbackLevel(-111); // can be -128 to 127
}
Q16n16 deltime;
void updateControl(){
// delay time range from 0 to 127 samples, @ 16384 samps per sec = 0 to 7 milliseconds
//del_samps = 64+kDelSamps.next();
// delay time range from 1 to 33 samples, @ 16384 samps per sec = 0 to 2 milliseconds
//del_samps = 17+kDelSamps.next()/8;
deltime = Q8n0_to_Q16n16(17) + ((long)kDelSamps.next()<<12);
}
AudioOutput updateAudio(){
char asig = aTriangle.next(); // get this so it can be used twice without calling next() again
//return asig/8 + aDel.next(asig, (uint16_t) del_samps); // mix some straight signal with the delayed signal
//return aDel.next(aTriangle.next(), (uint16_t) del_samps); // instead of the previous 2 lines for only the delayed signal
return MonoOutput::fromAlmostNBit(9, (asig >> 3) + aDel.next(asig, deltime)); // mix some straight signal with the delayed signal
}
void loop(){
audioHook();
}
+

This is an example of how to use the AudioDelayFeedback class.

+
/* Example of flanging,
+
using Mozzi sonification library.
+
+
Demonstrates AudioDelayFeedback.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
+
#include <Mozzi.h>
+
#include <Oscil.h>
+
#include <tables/triangle_analogue512_int8.h> // wavetable
+
#include <tables/triangle512_int8.h> // wavetable
+
#include <AudioDelayFeedback.h>
+
#include <mozzi_midi.h> // for mtof
+
+
Oscil<TRIANGLE_ANALOGUE512_NUM_CELLS, MOZZI_AUDIO_RATE> aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator
+
Oscil<TRIANGLE512_NUM_CELLS, MOZZI_CONTROL_RATE> kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples
+
+
AudioDelayFeedback <128> aDel;
+
+
// the delay time, measured in samples, updated in updateControl, and used in updateAudio
+
byte del_samps;
+
+
void setup(){
+
startMozzi();
+
aTriangle.setFreq(mtof(48.f));
+
kDelSamps.setFreq(.163f); // set the delay time modulation frequency (ie. the sweep frequency)
+
aDel.setFeedbackLevel(-111); // can be -128 to 127
+
}
+
+
+
Q16n16 deltime;
+
+
+
void updateControl(){
+
// delay time range from 0 to 127 samples, @ 16384 samps per sec = 0 to 7 milliseconds
+
//del_samps = 64+kDelSamps.next();
+
+
// delay time range from 1 to 33 samples, @ 16384 samps per sec = 0 to 2 milliseconds
+
//del_samps = 17+kDelSamps.next()/8;
+
+
deltime = Q8n0_to_Q16n16(17) + ((long)kDelSamps.next()<<12);
+
+
}
+
+
+
AudioOutput updateAudio(){
+
char asig = aTriangle.next(); // get this so it can be used twice without calling next() again
+
//return asig/8 + aDel.next(asig, (uint16_t) del_samps); // mix some straight signal with the delayed signal
+
//return aDel.next(aTriangle.next(), (uint16_t) del_samps); // instead of the previous 2 lines for only the delayed signal
+
return MonoOutput::fromAlmostNBit(9, (asig >> 3) + aDel.next(asig, deltime)); // mix some straight signal with the delayed signal
+
}
+
+
+
void loop(){
+
audioHook();
+
}
+
diff --git a/extras/doc/html/09_8_delays_2_reverb_tank__s_t_a_n_d_a_r_d_2_reverb_tank__s_t_a_n_d_a_r_d_8ino-example.html b/extras/doc/html/09_8_delays_2_reverb_tank__s_t_a_n_d_a_r_d_2_reverb_tank__s_t_a_n_d_a_r_d_8ino-example.html index f7e0861f9..c78d20e7a 100644 --- a/extras/doc/html/09_8_delays_2_reverb_tank__s_t_a_n_d_a_r_d_2_reverb_tank__s_t_a_n_d_a_r_d_8ino-example.html +++ b/extras/doc/html/09_8_delays_2_reverb_tank__s_t_a_n_d_a_r_d_2_reverb_tank__s_t_a_n_d_a_r_d_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,89 @@
09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino
-


- This example demonstrates the ReverbTank class.

-
/* Example of reverb on a synthesised sound
using Mozzi sonification library.
Demonstrates ReverbTank, a reverb small enough to fit on
the Arduino Nano, which for some reason wasn't able to fit a larger version
which did fit on other 328 based boards.
It's a pretty horrible reverb which sounds like the inside of a tin can.
For simplicity, ReverbTank has hardcoded maximum delay sizes
but also has default delay times which can be changed in the constructor
or by setting during run time to allow live tweaking.
The synthesised sound comes from the phasemod synth example.
Circuit: Audio output on digital pin 9 for STANDARD output on a Uno or similar, or
see the readme.md file for others.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth
#include <Mozzi.h>
#include <ReverbTank.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <tables/envelop2048_uint8.h>
ReverbTank reverb;
// Synth from PhaseMod_Envelope example
Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aCarrier(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aModulator(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aModWidth(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, MOZZI_CONTROL_RATE> kModFreq1(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, MOZZI_CONTROL_RATE> kModFreq2(COS8192_DATA);
Oscil <ENVELOP2048_NUM_CELLS, MOZZI_AUDIO_RATE> aEnvelop(ENVELOP2048_DATA);
void setup(){
// synth params
aCarrier.setFreq(55);
kModFreq1.setFreq(3.98f);
kModFreq2.setFreq(3.31757f);
aModWidth.setFreq(2.52434f);
aEnvelop.setFreq(9.0f);
startMozzi();
}
void updateControl(){
// synth control
aModulator.setFreq(277.0f + 0.4313f*kModFreq1.next() + kModFreq2.next());
}
AudioOutput updateAudio(){
int synth = aCarrier.phMod((int)aModulator.next()*(150u+aModWidth.next()));
synth *= (byte)aEnvelop.next();
synth >>= 8;
// here's the reverb
int arev = reverb.next(synth);
// add the dry and wet signals
return MonoOutput::fromAlmostNBit(9, synth + (arev>>3));
}
void loop(){
audioHook();
}
+

This example demonstrates the ReverbTank class.

+
/* Example of reverb on a synthesised sound
+
using Mozzi sonification library.
+
+
Demonstrates ReverbTank, a reverb small enough to fit on
+
the Arduino Nano, which for some reason wasn't able to fit a larger version
+
which did fit on other 328 based boards.
+
It's a pretty horrible reverb which sounds like the inside of a tin can.
+
For simplicity, ReverbTank has hardcoded maximum delay sizes
+
but also has default delay times which can be changed in the constructor
+
or by setting during run time to allow live tweaking.
+
The synthesised sound comes from the phasemod synth example.
+
+
Circuit: Audio output on digital pin 9 for STANDARD output on a Uno or similar, or
+
see the readme.md file for others.
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth
+
#include <Mozzi.h>
+
#include <ReverbTank.h>
+
#include <Oscil.h>
+
#include <tables/cos8192_int8.h>
+
#include <tables/envelop2048_uint8.h>
+
+
ReverbTank reverb;
+
+
// Synth from PhaseMod_Envelope example
+
Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aCarrier(COS8192_DATA);
+
Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aModulator(COS8192_DATA);
+
Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aModWidth(COS8192_DATA);
+
Oscil <COS8192_NUM_CELLS, MOZZI_CONTROL_RATE> kModFreq1(COS8192_DATA);
+
Oscil <COS8192_NUM_CELLS, MOZZI_CONTROL_RATE> kModFreq2(COS8192_DATA);
+
Oscil <ENVELOP2048_NUM_CELLS, MOZZI_AUDIO_RATE> aEnvelop(ENVELOP2048_DATA);
+
+
+
void setup(){
+
// synth params
+
aCarrier.setFreq(55);
+
kModFreq1.setFreq(3.98f);
+
kModFreq2.setFreq(3.31757f);
+
aModWidth.setFreq(2.52434f);
+
aEnvelop.setFreq(9.0f);
+
+
startMozzi();
+
}
+
+
+
void updateControl(){
+
// synth control
+
aModulator.setFreq(277.0f + 0.4313f*kModFreq1.next() + kModFreq2.next());
+
}
+
+
+
AudioOutput updateAudio(){
+
int synth = aCarrier.phMod((int)aModulator.next()*(150u+aModWidth.next()));
+
synth *= (byte)aEnvelop.next();
+
synth >>= 8;
+
// here's the reverb
+
int arev = reverb.next(synth);
+
// add the dry and wet signals
+
return MonoOutput::fromAlmostNBit(9, synth + (arev>>3));
+
}
+
+
+
void loop(){
+
audioHook();
+
}
+
diff --git a/extras/doc/html/10_8_audio__filters_2_multi_resonant_filter_2_multi_resonant_filter_8ino-example.html b/extras/doc/html/10_8_audio__filters_2_multi_resonant_filter_2_multi_resonant_filter_8ino-example.html index 58eab7086..8ec8fb690 100644 --- a/extras/doc/html/10_8_audio__filters_2_multi_resonant_filter_2_multi_resonant_filter_8ino-example.html +++ b/extras/doc/html/10_8_audio__filters_2_multi_resonant_filter_2_multi_resonant_filter_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -104,14 +100,100 @@

This example demonstrates the MultiResonantFilter specification of this class.

-
/* Example of filtering a wave with different types of filters
using Mozzi sonification library.
Demonstrates MultiResonantFilter<uint8_t>.
MultiResonantFilter is a derivative of ResonantFilter which allows all filter types to be accessed with only one filter.
It behaves similarly to ResonantFilter except:
- next(in) does not return anything and is just used to pass the current sample to the filter. Except for special cases should probably be called only once in updateAudio()
- different filter outputs are accessible via low(), high(), band() and notch() functions.
- note that the different filter types can be called in the same updateAudio(), for eg. to get different part of the signal.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
Thomas Combriat 2023, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil<CHUM9_NUM_CELLS, MOZZI_AUDIO_RATE> aCrunchySound(CHUM9_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod2(COS2048_DATA);
MultiResonantFilter<uint8_t> mf; // Multifilter applied to a 8 bits signal.
// MultiResonantFilter<uint16_t> can also be used for signals with higher number of bits
// in this last case, both the cutoff frequency and the resonance are uint16_t,
// ranging from 0, to 65535.
enum types {lowpass, bandpass, highpass, notch};
byte filter_type = 0;
uint8_t resonance = 200; // range 0-255, 255 is most resonant.
void setup() {
startMozzi();
aCrunchySound.setFreq(2.f);
kFilterMod.setFreq(1.3f);
kFilterMod2.setFreq(0.1f);
}
void loop() {
audioHook();
}
void updateControl() {
if (rand(MOZZI_CONTROL_RATE / 2) == 0) { // about once every half second
kFilterMod.setFreq((float)rand(255) / 64); // choose a new modulation frequency
filter_type = rand(4); // change the filter type, randomly
}
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
uint8_t cutoff_freq = (100 + kFilterMod.next() / 2) ;
mf.setCutoffFreqAndResonance(cutoff_freq, resonance);
}
AudioOutput updateAudio() {
AudioOutput asig;
mf.next(aCrunchySound.next()); // this send the current sample to the filter, does not return anything
switch (filter_type) // recover the output from the current selected filter type.
{
case lowpass:
asig = mf.low(); // lowpassed sample
break;
case highpass:
asig = mf.high(); // highpassed sample
break;
case bandpass:
asig = mf.band(); // bandpassed sample
break;
case notch:
asig = mf.notch(); // notched sample
break;
}
return MonoOutput::fromNBit(9, asig); // signal is theoretically 8 bits, but resonance push it further so we let one bit of margin
}
+
/* Example of filtering a wave with different types of filters
+
using Mozzi sonification library.
+
+
Demonstrates MultiResonantFilter<uint8_t>.
+
+
MultiResonantFilter is a derivative of ResonantFilter which allows all filter types to be accessed with only one filter.
+
It behaves similarly to ResonantFilter except:
+
- next(in) does not return anything and is just used to pass the current sample to the filter. Except for special cases should probably be called only once in updateAudio()
+
- different filter outputs are accessible via low(), high(), band() and notch() functions.
+
- note that the different filter types can be called in the same updateAudio(), for eg. to get different part of the signal.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2023-2024 Tom Combriat and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <Oscil.h>
+
#include <tables/chum9_int8.h> // recorded audio wavetable
+
#include <tables/cos2048_int8.h> // for filter modulation
+
#include <ResonantFilter.h>
+
#include <mozzi_rand.h>
+
+
Oscil<CHUM9_NUM_CELLS, MOZZI_AUDIO_RATE> aCrunchySound(CHUM9_DATA);
+
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod(COS2048_DATA);
+
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod2(COS2048_DATA);
+
+
MultiResonantFilter<uint8_t> mf; // Multifilter applied to a 8 bits signal.
+
// MultiResonantFilter<uint16_t> can also be used for signals with higher number of bits
+
// in this last case, both the cutoff frequency and the resonance are uint16_t,
+
// ranging from 0, to 65535.
+
+
enum types {lowpass, bandpass, highpass, notch};
+
byte filter_type = 0;
+
+
uint8_t resonance = 200; // range 0-255, 255 is most resonant.
+
+
void setup() {
+
startMozzi();
+
aCrunchySound.setFreq(2.f);
+
kFilterMod.setFreq(1.3f);
+
kFilterMod2.setFreq(0.1f);
+
}
+
+
void loop() {
+
audioHook();
+
}
+
+
void updateControl() {
+
if (rand(MOZZI_CONTROL_RATE / 2) == 0) { // about once every half second
+
kFilterMod.setFreq((float)rand(255) / 64); // choose a new modulation frequency
+
filter_type = rand(4); // change the filter type, randomly
+
}
+
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
+
uint8_t cutoff_freq = (100 + kFilterMod.next() / 2) ;
+
mf.setCutoffFreqAndResonance(cutoff_freq, resonance);
+
}
+
+
AudioOutput updateAudio() {
+
AudioOutput asig;
+
mf.next(aCrunchySound.next()); // this send the current sample to the filter, does not return anything
+
switch (filter_type) // recover the output from the current selected filter type.
+
{
+
case lowpass:
+
asig = mf.low(); // lowpassed sample
+
break;
+
case highpass:
+
asig = mf.high(); // highpassed sample
+
break;
+
case bandpass:
+
asig = mf.band(); // bandpassed sample
+
break;
+
case notch:
+
asig = mf.notch(); // notched sample
+
break;
+
}
+
return MonoOutput::fromNBit(9, asig); // signal is theoretically 8 bits, but resonance push it further so we let one bit of margin
+
}
+
diff --git a/extras/doc/html/10_8_audio__filters_2_resonant_filter16_2_resonant_filter16_8ino-example.html b/extras/doc/html/10_8_audio__filters_2_resonant_filter16_2_resonant_filter16_8ino-example.html index 0583a4855..6c067785a 100644 --- a/extras/doc/html/10_8_audio__filters_2_resonant_filter16_2_resonant_filter16_8ino-example.html +++ b/extras/doc/html/10_8_audio__filters_2_resonant_filter16_2_resonant_filter16_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -104,14 +100,83 @@

This example demonstrates the ResonantFilter16 specification of this class.

-
/* Example of filtering a wave,
using Mozzi sonification library.
Demonstrates ResonantFilter<uint16_t, FILTER_TYPE>.
ResonantFilter<uint16_t, FILTER_TYPE> is a different version of ResonantFilter<uint8_t, FILTER_TYPE> which uses bigger containing types for internal calculations.
The main differences with LowPassFilter are:
- parameters (resonance and cutoff_freq) are coded on 16bits, allowing for smoother transitions and finer tuning if needed,
- for 8bits platforms (like the Arduino) it will accept input samples of more than 8bits without overflowing,
- the drawback is higher CPU usage, especially for 8bits platform. If speed is crucial, you should probably use ResonantFilter<uint8_t, FILTER_TYPE> instead.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil<CHUM9_NUM_CELLS, MOZZI_AUDIO_RATE> aCrunchySound(CHUM9_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod2(COS2048_DATA);
//Different types of filters available
LowPassFilter16 rf; // Equivalent to ResonantFilter<LOWPASS, uint16_t>
//ResonantFilter<HIGHPASS, uint16_t> rf; // HighPass filter
//ResonantFilter<BANDPASS, uint16_t> rf; // BandPass filter
//ResonantFilter<NOTCH, uint16_t> rf; // Notch filter
uint16_t resonance = 50000; // range 0-65535, 65535 is most resonant.
// note the difference of type with the LowPassFilter()
void setup(){
startMozzi();
aCrunchySound.setFreq(2.f);
kFilterMod.setFreq(1.3f);
kFilterMod2.setFreq(0.1f);
}
void loop(){
audioHook();
}
void updateControl(){
if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second
kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency
}
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
uint16_t cutoff_freq = (100 + kFilterMod.next()/2) * (170+kFilterMod2.next());
rf.setCutoffFreqAndResonance(cutoff_freq, resonance);
}
AudioOutput updateAudio(){
AudioOutput asig = rf.next(aCrunchySound.next());
return MonoOutput::from8Bit(asig);
}
+
/* Example of filtering a wave,
+
using Mozzi sonification library.
+
+
Demonstrates ResonantFilter<uint16_t, FILTER_TYPE>.
+
+
ResonantFilter<uint16_t, FILTER_TYPE> is a different version of ResonantFilter<uint8_t, FILTER_TYPE> which uses bigger containing types for internal calculations.
+
The main differences with LowPassFilter are:
+
- parameters (resonance and cutoff_freq) are coded on 16bits, allowing for smoother transitions and finer tuning if needed,
+
- for 8bits platforms (like the Arduino) it will accept input samples of more than 8bits without overflowing,
+
- the drawback is higher CPU usage, especially for 8bits platform. If speed is crucial, you should probably use ResonantFilter<uint8_t, FILTER_TYPE> instead.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <Oscil.h>
+
#include <tables/chum9_int8.h> // recorded audio wavetable
+
#include <tables/cos2048_int8.h> // for filter modulation
+
#include <ResonantFilter.h>
+
#include <mozzi_rand.h>
+
+
Oscil<CHUM9_NUM_CELLS, MOZZI_AUDIO_RATE> aCrunchySound(CHUM9_DATA);
+
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod(COS2048_DATA);
+
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod2(COS2048_DATA);
+
+
//Different types of filters available
+
LowPassFilter16 rf; // Equivalent to ResonantFilter<LOWPASS, uint16_t>
+
//ResonantFilter<HIGHPASS, uint16_t> rf; // HighPass filter
+
//ResonantFilter<BANDPASS, uint16_t> rf; // BandPass filter
+
//ResonantFilter<NOTCH, uint16_t> rf; // Notch filter
+
+
+
uint16_t resonance = 50000; // range 0-65535, 65535 is most resonant.
+
// note the difference of type with the LowPassFilter()
+
+
void setup(){
+
startMozzi();
+
aCrunchySound.setFreq(2.f);
+
kFilterMod.setFreq(1.3f);
+
kFilterMod2.setFreq(0.1f);
+
}
+
+
void loop(){
+
audioHook();
+
}
+
+
void updateControl(){
+
if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second
+
kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency
+
}
+
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
+
uint16_t cutoff_freq = (100 + kFilterMod.next()/2) * (170+kFilterMod2.next());
+
rf.setCutoffFreqAndResonance(cutoff_freq, resonance);
+
}
+
+
AudioOutput updateAudio(){
+
AudioOutput asig = rf.next(aCrunchySound.next());
+
return MonoOutput::from8Bit(asig);
+
}
+
diff --git a/extras/doc/html/10_8_audio__filters_2_resonant_filter_2_resonant_filter_8ino-example.html b/extras/doc/html/10_8_audio__filters_2_resonant_filter_2_resonant_filter_8ino-example.html index 842d3b3d3..6a34f70ac 100644 --- a/extras/doc/html/10_8_audio__filters_2_resonant_filter_2_resonant_filter_8ino-example.html +++ b/extras/doc/html/10_8_audio__filters_2_resonant_filter_2_resonant_filter_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 10.Audio_Filters/ResonantFilter/ResonantFilter.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,78 @@
10.Audio_Filters/ResonantFilter/ResonantFilter.ino
-


- This example demonstrates the ResonantFilter specification of this class.

-
/* Example of filtering a wave,
using Mozzi sonification library.
Demonstrates ResonantFilter<uint8_t, FILTER_TYPE>>.
Note that, on 8bits platforms (Arduino) this filter cannot work
on samples of more than 8bits. Use LowPassFilter16() if you need
more than that.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil<CHUM9_NUM_CELLS, MOZZI_AUDIO_RATE> aCrunchySound(CHUM9_DATA);
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod(COS2048_DATA);
//Different types of filters available
LowPassFilter rf; // Equivalent to ResonantFilter<LOWPASS>
//ResonantFilter<HIGHPASS> rf; // HighPass filter
//ResonantFilter<BANDPASS> rf; // BandPass filter
//ResonantFilter<NOTCH> rf; // Notch filter
uint8_t resonance = 200; // range 0-255, 255 is most resonant
void setup(){
startMozzi();
aCrunchySound.setFreq(2.f);
kFilterMod.setFreq(1.3f);
}
void loop(){
audioHook();
}
void updateControl(){
if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second
kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency
}
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
byte cutoff_freq = 100 + kFilterMod.next()/2;
rf.setCutoffFreqAndResonance(cutoff_freq, resonance);
}
AudioOutput updateAudio(){
char asig = rf.next(aCrunchySound.next());
return MonoOutput::from8Bit(asig);
}
+

This example demonstrates the ResonantFilter specification of this class.

+
/* Example of filtering a wave,
+
using Mozzi sonification library.
+
+
Demonstrates ResonantFilter<uint8_t, FILTER_TYPE>>.
+
+
Note that, on 8bits platforms (Arduino) this filter cannot work
+
on samples of more than 8bits. Use LowPassFilter16() if you need
+
more than that.
+
+
Circuit: Audio output on digital pin 9 on a Uno or similar, or
+
DAC/A14 on Teensy 3.1, or
+
check the README or http://sensorium.github.io/Mozzi/
+
+
Mozzi documentation/API
+
https://sensorium.github.io/Mozzi/doc/html/index.html
+
+
Mozzi help/discussion/announcements:
+
https://groups.google.com/forum/#!forum/mozzi-users
+
+
Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
+
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
*/
+
+
#include <Mozzi.h>
+
#include <Oscil.h>
+
#include <tables/chum9_int8.h> // recorded audio wavetable
+
#include <tables/cos2048_int8.h> // for filter modulation
+
#include <ResonantFilter.h>
+
#include <mozzi_rand.h>
+
+
Oscil<CHUM9_NUM_CELLS, MOZZI_AUDIO_RATE> aCrunchySound(CHUM9_DATA);
+
Oscil<COS2048_NUM_CELLS, MOZZI_CONTROL_RATE> kFilterMod(COS2048_DATA);
+
+
//Different types of filters available
+
LowPassFilter rf; // Equivalent to ResonantFilter<LOWPASS>
+
//ResonantFilter<HIGHPASS> rf; // HighPass filter
+
//ResonantFilter<BANDPASS> rf; // BandPass filter
+
//ResonantFilter<NOTCH> rf; // Notch filter
+
+
uint8_t resonance = 200; // range 0-255, 255 is most resonant
+
+
void setup(){
+
startMozzi();
+
aCrunchySound.setFreq(2.f);
+
kFilterMod.setFreq(1.3f);
+
}
+
+
void loop(){
+
audioHook();
+
}
+
+
void updateControl(){
+
if (rand(MOZZI_CONTROL_RATE/2) == 0){ // about once every half second
+
kFilterMod.setFreq((float)rand(255)/64); // choose a new modulation frequency
+
}
+
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
+
byte cutoff_freq = 100 + kFilterMod.next()/2;
+
rf.setCutoffFreqAndResonance(cutoff_freq, resonance);
+
}
+
+
AudioOutput updateAudio(){
+
char asig = rf.next(aCrunchySound.next());
+
return MonoOutput::from8Bit(asig);
+
}
+
diff --git a/extras/doc/html/11_8_audio__filters_2_state_variable_filter_2_state_variable_filter_8ino-example.html b/extras/doc/html/11_8_audio__filters_2_state_variable_filter_2_state_variable_filter_8ino-example.html index 640fee29d..badfc0864 100644 --- a/extras/doc/html/11_8_audio__filters_2_state_variable_filter_2_state_variable_filter_8ino-example.html +++ b/extras/doc/html/11_8_audio__filters_2_state_variable_filter_2_state_variable_filter_8ino-example.html @@ -1,9 +1,9 @@ - + - + Mozzi: 11.Audio_Filters/StateVariableFilter/StateVariableFilter.ino @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,13 @@
11.Audio_Filters/StateVariableFilter/StateVariableFilter.ino
-


- This example demonstrates the StateVariable class.

+

This example demonstrates the StateVariable class.

diff --git a/extras/doc/html/_a_d_s_r_8h_source.html b/extras/doc/html/_a_d_s_r_8h_source.html index a18bdcf1f..22c40ea96 100644 --- a/extras/doc/html/_a_d_s_r_8h_source.html +++ b/extras/doc/html/_a_d_s_r_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: ADSR.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,41 +99,453 @@
ADSR.h
-
1 /*
2  * ADSR.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef ADSR_H_
13 #define ADSR_H_
14 
15 #include <Arduino.h>
16 #include "Line.h"
17 #include "mozzi_fixmath.h"
18 
19 
20 /** A simple ADSR envelope generator. This implementation has separate update() and next()
21 methods, where next() interpolates values between each update().
22 The "normal" way to use this would be with update() in updateControl(), where it calculates a new internal state each control step,
23 and then next() is in updateAudio(), called much more often, where it interpolates between the control values.
24 This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update.
25 @tparam CONTROL_UPDATE_RATE The frequency of control updates.
26 Ordinarily this will be MOZZI_CONTROL_RATE, but an alternative (amongst others) is
27 to set this as well as the LERP_RATE parameter to MOZZI_AUDIO_RATE, and call both update() and next() in updateAudio().
28 Such a use would allow accurate envelopes with finer resolution of the control points than MOZZI_CONTROL_RATE.
29 @tparam LERP_RATE Sets how often next() will be called, to interpolate between updates set by CONTROL_UPDATE_RATE.
30 This will produce the smoothest results if it's set to MOZZI_AUDIO_RATE, but if you need to save processor time and your
31 envelope changes slowly or controls something like a filter where there may not be problems with glitchy or clicking transitions,
32 LERP_RATE could be set to MOZZI_CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(),
33 greatly reducing the amount of processing required compared to calling next() in updateAudio().
34 @todo Test whether using the template parameters makes any difference to speed,
35 and rationalise which units do and don't need them.
36 Template objects are messy when you try to use pointers to them,
37 you have to include the whole template in the pointer handling.
38 */
39 
40 template <unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
41 class ADSR
42 {
43 private:
44 
45  const unsigned int LERPS_PER_CONTROL;
46 
47  T update_step_counter;
48  T num_update_steps;
49 
50  enum {ATTACK,DECAY,SUSTAIN,RELEASE,IDLE};
51 
52 
53  struct phase{
54  byte phase_type;
55  T update_steps;
56  long lerp_steps; // signed, to match params to transition (line) type Q15n16, below
57  Q8n0 level;
58  }attack,decay,sustain,release,idle;
59 
60  phase * current_phase;
61 
62  // Linear audio rate transitions for envelope
63  //Line <unsigned long> transition;
64  Line <Q15n16> transition; // scale up unsigned char levels for better accuracy, then scale down again for output
65 
66  inline
67  T convertMsecToControlUpdateSteps(unsigned int msec){
68  return (T) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
69  }
70 
71 
72  inline
73  void setPhase(phase * next_phase) {
74  update_step_counter = 0;
75  num_update_steps = next_phase->update_steps;
76  transition.set(Q8n0_to_Q15n16(next_phase->level),next_phase->lerp_steps);
77  current_phase = next_phase;
78  }
79 
80 
81  inline
82  void checkForAndSetNextPhase(phase * next_phase) {
83  if (++update_step_counter >= num_update_steps){
84  setPhase(next_phase);
85  }
86  }
87 
88 
89 
90  inline
91  void setTime(phase * p, unsigned int msec)
92  {
93  p->update_steps = convertMsecToControlUpdateSteps(msec);
94  p->lerp_steps = (long) p->update_steps * LERPS_PER_CONTROL;
95  }
96 
97 
98  inline
99  void setUpdateSteps(phase * p, unsigned int steps)
100  {
101  p->update_steps = steps;
102  p->lerp_steps = (long) steps * LERPS_PER_CONTROL;
103  }
104 
105 
106 
107 public:
108 
109  /** Constructor.
110  */
111  ADSR():LERPS_PER_CONTROL(LERP_RATE/CONTROL_UPDATE_RATE)
112  {
113  attack.phase_type = ATTACK;
114  decay.phase_type = DECAY;
115  sustain.phase_type = SUSTAIN;
116  release.phase_type = RELEASE;
117  idle.phase_type = IDLE;
118  release.level = 0;
119  adsr_playing = false;
120  current_phase = &idle;
121  }
122 
123 
124 
125  /** Updates the internal controls of the ADSR.
126  Call this in updateControl().
127  */
128  void update(){ // control rate
129 
130  switch(current_phase->phase_type) {
131 
132  case ATTACK:
133  checkForAndSetNextPhase(&decay);
134  break;
135 
136  case DECAY:
137  checkForAndSetNextPhase(&sustain);
138  break;
139 
140  case SUSTAIN:
141  checkForAndSetNextPhase(&release);
142  break;
143 
144  case RELEASE:
145  checkForAndSetNextPhase(&idle);
146  break;
147 
148  case IDLE:
149  adsr_playing = false;
150  break;
151  }
152  }
153 
154 
155 
156  /** Advances one audio step along the ADSR and returns the level.
157  Call this in updateAudio().
158  @return the next value, as an unsigned char.
159  */
160  inline
161  unsigned char next()
162  {
163  unsigned char out = 0;
164  if (adsr_playing) out = Q15n16_to_Q8n0(transition.next());
165  return out;
166  }
167 
168 
169 
170  /** Start the attack phase of the ADSR. This will restart the ADSR no matter what phase it is up to.
171  @param reset If true, the envelope will start from 0, even if it is still playing (often useful for effect envelopes).
172  If false (default if omitted), the envelope will start rising from the current level, which could be non-zero, if
173  it is still playing (most useful for note envelopes).
174  */
175  inline
176  void noteOn(bool reset=false){
177  if (reset) transition.set(0);
178  setPhase(&attack);
179  adsr_playing = true;
180  }
181 
182 
183 
184  /** Start the release phase of the ADSR.
185  @todo fix release for rate rather than steps (time), so it releases at the same rate whatever the current level.
186  */
187  inline
188  void noteOff(){
189  setPhase(&release);
190  }
191 
192 
193 
194  /** Set the attack level of the ADSR.
195  @param value the attack level.
196  */
197  inline
198  void setAttackLevel(byte value)
199  {
200  attack.level=value;
201  }
202 
203 
204 
205  /** Set the decay level of the ADSR.
206  @param value the decay level.
207  */
208  inline
209  void setDecayLevel(byte value)
210  {
211  decay.level=value;
212  }
213 
214 
215  /** Set the sustain level of the ADSR.
216  @param value the sustain level. Usually the same as the decay level,
217  for a steady sustained note.
218  */
219  inline
220  void setSustainLevel(byte value)
221  {
222  sustain.level=value;
223  }
224 
225  /** Set the release level of the ADSR. Normally you'd make this 0,
226  but you have the option of some other value.
227  @param value the release level (usually 0).
228  */
229  inline
230  void setReleaseLevel(byte value)
231  {
232  release.level=value;
233  }
234 
235 
236  inline
237  void setIdleLevel(byte value)
238  {
239  idle.level=value;
240  }
241 
242 
243  /** Set the attack and decay levels of the ADSR. This assumes a conventional
244  ADSR where the sustain continues at the same level as the decay, till the release ramps to 0.
245  @param attack the new attack level.
246  @param decay the new decay level.
247  */
248  inline
249  void setADLevels(byte attack, byte decay)
250  {
251  setAttackLevel(attack);
252  setDecayLevel(decay);
253  setSustainLevel(decay); // stay at decay level
254  setReleaseLevel(1);
255  setIdleLevel(0);
256  }
257 
258 
259  /** Set the attack, decay, sustain and release levels.
260  @param attack the new attack level.
261  @param decay the new sustain level.
262  @param attack the new sustain level.
263  @param decay the new release level.
264  */
265  inline
266  void setLevels(byte attack, byte decay, byte sustain, byte release)
267  {
268  setAttackLevel(attack);
269  setDecayLevel(decay);
270  setSustainLevel(sustain);
271  setReleaseLevel(release);
272  setIdleLevel(0);
273  }
274 
275 
276  /** Set the attack time of the ADSR in milliseconds.
277  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
278  @param msec the unsigned int attack time in milliseconds.
279  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
280  in case internal step size gets calculated as 0, which would mean nothing happens.
281  */
282  inline
283  void setAttackTime(unsigned int msec)
284  {
285  setTime(&attack, msec);
286  }
287 
288 
289  /** Set the decay time of the ADSR in milliseconds.
290  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
291  @param msec the unsigned int decay time in milliseconds.
292  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
293  in case internal step size gets calculated as 0, which would mean nothing happens.
294  */
295  inline
296  void setDecayTime(unsigned int msec)
297  {
298  setTime(&decay, msec);
299  }
300 
301 
302  /** Set the sustain time of the ADSR in milliseconds.
303  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
304  The sustain phase will finish if the ADSR recieves a noteOff().
305  @param msec the unsigned int sustain time in milliseconds.
306  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
307  in case internal step size gets calculated as 0, which would mean nothing happens.
308  */
309  inline
310  void setSustainTime(unsigned int msec)
311  {
312  setTime(&sustain, msec);
313  }
314 
315 
316 
317  /** Set the release time of the ADSR in milliseconds.
318  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
319  @param msec the unsigned int release time in milliseconds.
320  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
321  in case internal step size gets calculated as 0, which would mean nothing happens.
322  */
323  inline
324  void setReleaseTime(unsigned int msec)
325  {
326  setTime(&release, msec);
327  }
328 
329 
330  inline
331  void setIdleTime(unsigned int msec)
332  {
333  setTime(&idle, msec);
334  }
335 
336 
337  /** Set the attack, decay and release times of the ADSR in milliseconds.
338  The actual times will be resolved within the resolution of MOZZI_CONTROL_RATE.
339  @param attack_ms the new attack time in milliseconds.
340  @param decay_ms the new decay time in milliseconds.
341  @param sustain_ms the new sustain time in milliseconds.
342  @param release_ms the new release time in milliseconds.
343  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
344  in case internal step size gets calculated as 0, which would mean nothing happens.
345  */
346  inline
347  void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
348  {
349  setAttackTime(attack_ms);
350  setDecayTime(decay_ms);
351  setSustainTime(sustain_ms);
352  setReleaseTime(release_ms);
353  setIdleTime(65535); // guarantee step size of line will be 0
354  }
355 
356 
357 
358  /** Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the attack phase.
359  @param steps the number of times ADSR::update() will be called in the attack phase.
360  */
361  inline
362  void setAttackUpdateSteps(unsigned int steps)
363  {
364  setUpdateSteps(&attack, steps);
365  }
366 
367 
368  /** Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the decay phase.
369  @param steps the number of times ADSR::update() will be called in the decay phase.
370  */
371  inline
372  void setDecayUpdateSteps(unsigned int steps)
373  {
374  setUpdateSteps(&decay, steps);
375  }
376 
377 
378  /** Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the sustain phase.
379  @param steps the number of times ADSR::update() will be called in the sustain phase.
380  */
381  inline
382  void setSustainUpdateSteps(unsigned int steps)
383  {
384  setUpdateSteps(&sustain, steps);
385  }
386 
387 
388  /** Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the release phase.
389  @param steps the number of times ADSR::update() will be called in the release phase.
390  */
391  inline
392  void setReleaseUpdateSteps(unsigned int steps)
393  {
394  setUpdateSteps(&release, steps);
395  }
396 
397 
398  inline
399  void setIdleUpdateSteps(unsigned int steps)
400  {
401  setUpdateSteps(&idle, steps);
402  }
403 
404  /** Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() interpolation steps).
405  @param attack_steps the number of update steps in the attack phase
406  @param decay_steps the number of update steps in the decay phase
407  @param sustain_steps the number of update steps in the sustain phase
408  @param release_steps the number of update steps in the release phase
409  */
410  inline
411  void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
412  {
413  setAttackUpdateSteps(attack_steps);
414  setDecayUpdateSteps(decay_steps);
415  setSustainUpdateSteps(sustain_steps);
416  setReleaseUpdateSteps(release_steps);
417  setIdleUpdateSteps(65535); // guarantee step size of line will be 0
418  }
419 
420 
421 bool adsr_playing;
422 
423  /** Tells if the envelope is currently playing.
424  @return true if playing, false if in IDLE state
425  */
426  inline
427  bool playing()
428  {
429  return adsr_playing;
430  }
431 
432 
433 };
434 
435 
436 /** @example 07.Envelopes/ADSR_Envelope/ADSR_Envelope.ino
437 This is an example of how to use the ADSR class.
438 */
439 
440 #endif /* ADSR_H_ */
void setDecayLevel(byte value)
Set the decay level of the ADSR.
Definition: ADSR.h:209
-
void noteOn(bool reset=false)
Start the attack phase of the ADSR.
Definition: ADSR.h:176
-
void setAttackUpdateSteps(unsigned int steps)
Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolat...
Definition: ADSR.h:362
-
void setSustainLevel(byte value)
Set the sustain level of the ADSR.
Definition: ADSR.h:220
-
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:38
-
void setLevels(byte attack, byte decay, byte sustain, byte release)
Set the attack, decay, sustain and release levels.
Definition: ADSR.h:266
-
unsigned char next()
Advances one audio step along the ADSR and returns the level.
Definition: ADSR.h:161
-
void setSustainUpdateSteps(unsigned int steps)
Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpola...
Definition: ADSR.h:382
-
void setReleaseUpdateSteps(unsigned int steps)
Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpola...
Definition: ADSR.h:392
-
void setReleaseTime(unsigned int msec)
Set the release time of the ADSR in milliseconds.
Definition: ADSR.h:324
-
void setDecayUpdateSteps(unsigned int steps)
Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolati...
Definition: ADSR.h:372
-
void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() inte...
Definition: ADSR.h:411
-
void noteOff()
Start the release phase of the ADSR.
Definition: ADSR.h:188
-
For linear changes with a minimum of calculation at each step.
Definition: Line.h:33
-
void setAttackLevel(byte value)
Set the attack level of the ADSR.
Definition: ADSR.h:198
-
void setADLevels(byte attack, byte decay)
Set the attack and decay levels of the ADSR.
Definition: ADSR.h:249
-
bool playing()
Tells if the envelope is currently playing.
Definition: ADSR.h:427
-
void setAttackTime(unsigned int msec)
Set the attack time of the ADSR in milliseconds.
Definition: ADSR.h:283
-
void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
Set the attack, decay and release times of the ADSR in milliseconds.
Definition: ADSR.h:347
-
void setReleaseLevel(byte value)
Set the release level of the ADSR.
Definition: ADSR.h:230
-
void setDecayTime(unsigned int msec)
Set the decay time of the ADSR in milliseconds.
Definition: ADSR.h:296
-
ADSR()
Constructor.
Definition: ADSR.h:111
-
uint8_t Q8n0
normal uint8_t with 0 fractional bits, represents 0.0 to 255.0
Definition: mozzi_fixmath.h:26
-
void setSustainTime(unsigned int msec)
Set the sustain time of the ADSR in milliseconds.
Definition: ADSR.h:310
-
A simple ADSR envelope generator.
Definition: ADSR.h:41
-
void update()
Updates the internal controls of the ADSR.
Definition: ADSR.h:128
+
1 /*
+
2  * ADSR.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 ADSR_H_
+
13 #define ADSR_H_
+
14 
+
15 #include <Arduino.h>
+
16 #include "Line.h"
+
17 #include "mozzi_fixmath.h"
+
18 
+
19 
+
20 /** A simple ADSR envelope generator. This implementation has separate update() and next()
+
21 methods, where next() interpolates values between each update().
+
22 The "normal" way to use this would be with update() in updateControl(), where it calculates a new internal state each control step,
+
23 and then next() is in updateAudio(), called much more often, where it interpolates between the control values.
+
24 This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update.
+
25 @tparam CONTROL_UPDATE_RATE The frequency of control updates.
+
26 Ordinarily this will be MOZZI_CONTROL_RATE, but an alternative (amongst others) is
+
27 to set this as well as the LERP_RATE parameter to MOZZI_AUDIO_RATE, and call both update() and next() in updateAudio().
+
28 Such a use would allow accurate envelopes with finer resolution of the control points than MOZZI_CONTROL_RATE.
+
29 @tparam LERP_RATE Sets how often next() will be called, to interpolate between updates set by CONTROL_UPDATE_RATE.
+
30 This will produce the smoothest results if it's set to MOZZI_AUDIO_RATE, but if you need to save processor time and your
+
31 envelope changes slowly or controls something like a filter where there may not be problems with glitchy or clicking transitions,
+
32 LERP_RATE could be set to MOZZI_CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(),
+
33 greatly reducing the amount of processing required compared to calling next() in updateAudio().
+
34 @todo Test whether using the template parameters makes any difference to speed,
+
35 and rationalise which units do and don't need them.
+
36 Template objects are messy when you try to use pointers to them,
+
37 you have to include the whole template in the pointer handling.
+
38 */
+
39 
+
40 template <unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+
41 class ADSR
+
42 {
+
43 private:
+
44 
+
45  const unsigned int LERPS_PER_CONTROL;
+
46 
+
47  T update_step_counter;
+
48  T num_update_steps;
+
49 
+
50  enum {ATTACK,DECAY,SUSTAIN,RELEASE,IDLE};
+
51 
+
52 
+
53  struct phase{
+
54  byte phase_type;
+
55  T update_steps;
+
56  long lerp_steps; // signed, to match params to transition (line) type Q15n16, below
+
57  Q8n0 level;
+
58  }attack,decay,sustain,release,idle;
+
59 
+
60  phase * current_phase;
+
61 
+
62  // Linear audio rate transitions for envelope
+
63  //Line <unsigned long> transition;
+
64  Line <Q15n16> transition; // scale up unsigned char levels for better accuracy, then scale down again for output
+
65 
+
66  inline
+
67  T convertMsecToControlUpdateSteps(unsigned int msec){
+
68  return (T) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
+
69  }
+
70 
+
71 
+
72  inline
+
73  void setPhase(phase * next_phase) {
+
74  update_step_counter = 0;
+
75  num_update_steps = next_phase->update_steps;
+
76  transition.set(Q8n0_to_Q15n16(next_phase->level),next_phase->lerp_steps);
+
77  current_phase = next_phase;
+
78  }
+
79 
+
80 
+
81  inline
+
82  void checkForAndSetNextPhase(phase * next_phase) {
+
83  if (++update_step_counter >= num_update_steps){
+
84  setPhase(next_phase);
+
85  }
+
86  }
+
87 
+
88 
+
89 
+
90  inline
+
91  void setTime(phase * p, unsigned int msec)
+
92  {
+
93  p->update_steps = convertMsecToControlUpdateSteps(msec);
+
94  p->lerp_steps = (long) p->update_steps * LERPS_PER_CONTROL;
+
95  }
+
96 
+
97 
+
98  inline
+
99  void setUpdateSteps(phase * p, unsigned int steps)
+
100  {
+
101  p->update_steps = steps;
+
102  p->lerp_steps = (long) steps * LERPS_PER_CONTROL;
+
103  }
+
104 
+
105 
+
106 
+
107 public:
+
108 
+
109  /** Constructor.
+
110  */
+
111  ADSR():LERPS_PER_CONTROL(LERP_RATE/CONTROL_UPDATE_RATE)
+
112  {
+
113  attack.phase_type = ATTACK;
+
114  decay.phase_type = DECAY;
+
115  sustain.phase_type = SUSTAIN;
+
116  release.phase_type = RELEASE;
+
117  idle.phase_type = IDLE;
+
118  release.level = 0;
+
119  adsr_playing = false;
+
120  current_phase = &idle;
+
121  }
+
122 
+
123 
+
124 
+
125  /** Updates the internal controls of the ADSR.
+
126  Call this in updateControl().
+
127  */
+
128  void update(){ // control rate
+
129 
+
130  switch(current_phase->phase_type) {
+
131 
+
132  case ATTACK:
+
133  checkForAndSetNextPhase(&decay);
+
134  break;
+
135 
+
136  case DECAY:
+
137  checkForAndSetNextPhase(&sustain);
+
138  break;
+
139 
+
140  case SUSTAIN:
+
141  checkForAndSetNextPhase(&release);
+
142  break;
+
143 
+
144  case RELEASE:
+
145  checkForAndSetNextPhase(&idle);
+
146  break;
+
147 
+
148  case IDLE:
+
149  adsr_playing = false;
+
150  break;
+
151  }
+
152  }
+
153 
+
154 
+
155 
+
156  /** Advances one audio step along the ADSR and returns the level.
+
157  Call this in updateAudio().
+
158  @return the next value, as an unsigned char.
+
159  */
+
160  inline
+
161  unsigned char next()
+
162  {
+
163  unsigned char out = 0;
+
164  if (adsr_playing) out = Q15n16_to_Q8n0(transition.next());
+
165  return out;
+
166  }
+
167 
+
168 
+
169 
+
170  /** Start the attack phase of the ADSR. This will restart the ADSR no matter what phase it is up to.
+
171  @param reset If true, the envelope will start from 0, even if it is still playing (often useful for effect envelopes).
+
172  If false (default if omitted), the envelope will start rising from the current level, which could be non-zero, if
+
173  it is still playing (most useful for note envelopes).
+
174  */
+
175  inline
+
176  void noteOn(bool reset=false){
+
177  if (reset) transition.set(0);
+
178  setPhase(&attack);
+
179  adsr_playing = true;
+
180  }
+
181 
+
182 
+
183 
+
184  /** Start the release phase of the ADSR.
+
185  @todo fix release for rate rather than steps (time), so it releases at the same rate whatever the current level.
+
186  */
+
187  inline
+
188  void noteOff(){
+
189  setPhase(&release);
+
190  }
+
191 
+
192 
+
193 
+
194  /** Set the attack level of the ADSR.
+
195  @param value the attack level.
+
196  */
+
197  inline
+
198  void setAttackLevel(byte value)
+
199  {
+
200  attack.level=value;
+
201  }
+
202 
+
203 
+
204 
+
205  /** Set the decay level of the ADSR.
+
206  @param value the decay level.
+
207  */
+
208  inline
+
209  void setDecayLevel(byte value)
+
210  {
+
211  decay.level=value;
+
212  }
+
213 
+
214 
+
215  /** Set the sustain level of the ADSR.
+
216  @param value the sustain level. Usually the same as the decay level,
+
217  for a steady sustained note.
+
218  */
+
219  inline
+
220  void setSustainLevel(byte value)
+
221  {
+
222  sustain.level=value;
+
223  }
+
224 
+
225  /** Set the release level of the ADSR. Normally you'd make this 0,
+
226  but you have the option of some other value.
+
227  @param value the release level (usually 0).
+
228  */
+
229  inline
+
230  void setReleaseLevel(byte value)
+
231  {
+
232  release.level=value;
+
233  }
+
234 
+
235 
+
236  inline
+
237  void setIdleLevel(byte value)
+
238  {
+
239  idle.level=value;
+
240  }
+
241 
+
242 
+
243  /** Set the attack and decay levels of the ADSR. This assumes a conventional
+
244  ADSR where the sustain continues at the same level as the decay, till the release ramps to 0.
+
245  @param attack the new attack level.
+
246  @param decay the new decay level.
+
247  */
+
248  inline
+
249  void setADLevels(byte attack, byte decay)
+
250  {
+
251  setAttackLevel(attack);
+
252  setDecayLevel(decay);
+
253  setSustainLevel(decay); // stay at decay level
+
254  setReleaseLevel(1);
+
255  setIdleLevel(0);
+
256  }
+
257 
+
258 
+
259  /** Set the attack, decay, sustain and release levels.
+
260  @param attack the new attack level.
+
261  @param decay the new sustain level.
+
262  @param attack the new sustain level.
+
263  @param decay the new release level.
+
264  */
+
265  inline
+
266  void setLevels(byte attack, byte decay, byte sustain, byte release)
+
267  {
+
268  setAttackLevel(attack);
+
269  setDecayLevel(decay);
+
270  setSustainLevel(sustain);
+
271  setReleaseLevel(release);
+
272  setIdleLevel(0);
+
273  }
+
274 
+
275 
+
276  /** Set the attack time of the ADSR in milliseconds.
+
277  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
+
278  @param msec the unsigned int attack time in milliseconds.
+
279  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
+
280  in case internal step size gets calculated as 0, which would mean nothing happens.
+
281  */
+
282  inline
+
283  void setAttackTime(unsigned int msec)
+
284  {
+
285  setTime(&attack, msec);
+
286  }
+
287 
+
288 
+
289  /** Set the decay time of the ADSR in milliseconds.
+
290  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
+
291  @param msec the unsigned int decay time in milliseconds.
+
292  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
+
293  in case internal step size gets calculated as 0, which would mean nothing happens.
+
294  */
+
295  inline
+
296  void setDecayTime(unsigned int msec)
+
297  {
+
298  setTime(&decay, msec);
+
299  }
+
300 
+
301 
+
302  /** Set the sustain time of the ADSR in milliseconds.
+
303  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
+
304  The sustain phase will finish if the ADSR recieves a noteOff().
+
305  @param msec the unsigned int sustain time in milliseconds.
+
306  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
+
307  in case internal step size gets calculated as 0, which would mean nothing happens.
+
308  */
+
309  inline
+
310  void setSustainTime(unsigned int msec)
+
311  {
+
312  setTime(&sustain, msec);
+
313  }
+
314 
+
315 
+
316 
+
317  /** Set the release time of the ADSR in milliseconds.
+
318  The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.
+
319  @param msec the unsigned int release time in milliseconds.
+
320  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
+
321  in case internal step size gets calculated as 0, which would mean nothing happens.
+
322  */
+
323  inline
+
324  void setReleaseTime(unsigned int msec)
+
325  {
+
326  setTime(&release, msec);
+
327  }
+
328 
+
329 
+
330  inline
+
331  void setIdleTime(unsigned int msec)
+
332  {
+
333  setTime(&idle, msec);
+
334  }
+
335 
+
336 
+
337  /** Set the attack, decay and release times of the ADSR in milliseconds.
+
338  The actual times will be resolved within the resolution of MOZZI_CONTROL_RATE.
+
339  @param attack_ms the new attack time in milliseconds.
+
340  @param decay_ms the new decay time in milliseconds.
+
341  @param sustain_ms the new sustain time in milliseconds.
+
342  @param release_ms the new release time in milliseconds.
+
343  @note Beware of low values (less than 20 or so, depending on how many steps are being taken),
+
344  in case internal step size gets calculated as 0, which would mean nothing happens.
+
345  */
+
346  inline
+
347  void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
+
348  {
+
349  setAttackTime(attack_ms);
+
350  setDecayTime(decay_ms);
+
351  setSustainTime(sustain_ms);
+
352  setReleaseTime(release_ms);
+
353  setIdleTime(65535); // guarantee step size of line will be 0
+
354  }
+
355 
+
356 
+
357 
+
358  /** Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the attack phase.
+
359  @param steps the number of times ADSR::update() will be called in the attack phase.
+
360  */
+
361  inline
+
362  void setAttackUpdateSteps(unsigned int steps)
+
363  {
+
364  setUpdateSteps(&attack, steps);
+
365  }
+
366 
+
367 
+
368  /** Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the decay phase.
+
369  @param steps the number of times ADSR::update() will be called in the decay phase.
+
370  */
+
371  inline
+
372  void setDecayUpdateSteps(unsigned int steps)
+
373  {
+
374  setUpdateSteps(&decay, steps);
+
375  }
+
376 
+
377 
+
378  /** Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the sustain phase.
+
379  @param steps the number of times ADSR::update() will be called in the sustain phase.
+
380  */
+
381  inline
+
382  void setSustainUpdateSteps(unsigned int steps)
+
383  {
+
384  setUpdateSteps(&sustain, steps);
+
385  }
+
386 
+
387 
+
388  /** Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the release phase.
+
389  @param steps the number of times ADSR::update() will be called in the release phase.
+
390  */
+
391  inline
+
392  void setReleaseUpdateSteps(unsigned int steps)
+
393  {
+
394  setUpdateSteps(&release, steps);
+
395  }
+
396 
+
397 
+
398  inline
+
399  void setIdleUpdateSteps(unsigned int steps)
+
400  {
+
401  setUpdateSteps(&idle, steps);
+
402  }
+
403 
+
404  /** Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() interpolation steps).
+
405  @param attack_steps the number of update steps in the attack phase
+
406  @param decay_steps the number of update steps in the decay phase
+
407  @param sustain_steps the number of update steps in the sustain phase
+
408  @param release_steps the number of update steps in the release phase
+
409  */
+
410  inline
+
411  void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
+
412  {
+
413  setAttackUpdateSteps(attack_steps);
+
414  setDecayUpdateSteps(decay_steps);
+
415  setSustainUpdateSteps(sustain_steps);
+
416  setReleaseUpdateSteps(release_steps);
+
417  setIdleUpdateSteps(65535); // guarantee step size of line will be 0
+
418  }
+
419 
+
420 
+
421 bool adsr_playing;
+
422 
+
423  /** Tells if the envelope is currently playing.
+
424  @return true if playing, false if in IDLE state
+
425  */
+
426  inline
+
427  bool playing()
+
428  {
+
429  return adsr_playing;
+
430  }
+
431 
+
432 
+
433 };
+
434 
+
435 
+
436 /** @example 07.Envelopes/ADSR_Envelope/ADSR_Envelope.ino
+
437 This is an example of how to use the ADSR class.
+
438 */
+
439 
+
440 #endif /* ADSR_H_ */
diff --git a/extras/doc/html/_audio_delay_8h_source.html b/extras/doc/html/_audio_delay_8h_source.html index 57d4595e6..15c130a47 100644 --- a/extras/doc/html/_audio_delay_8h_source.html +++ b/extras/doc/html/_audio_delay_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: AudioDelay.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,22 +99,141 @@
AudioDelay.h
-
1 /*
2  * AudioDelay.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUDIODELAY_H_
13 #define AUDIODELAY_H_
14 
15 
16 /** Audio delay line for comb filter, flange, chorus and short echo effects.
17 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples. This should
18 be a power of two. The largest delay you'll fit in an atmega328 will be 512
19 cells, which at 16384 Hz sample rate is 31 milliseconds. More of a flanger or a
20 doubler than an echo. The amount of memory available for delays on other chips will vary.
21 AudioDelay() doesn't have feedback. If you want feedback, use AudioDelayFeedback().
22 @tparam the type of numbers to use for the signal in the delay. The default is int8_t, but int could be useful
23 when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
24 */
25 
26 template <unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
28 {
29 
30 private:
31 
32  T delay_array[NUM_BUFFER_SAMPLES];
33  unsigned int _write_pos;
34  unsigned int _delaytime_cells;
35 
36 public:
37 
38  /** Constructor.
39  */
40  AudioDelay(): _write_pos(0)
41  {}
42 
43 
44  /** Constructor.
45  @param delaytime_cells delay time expressed in cells.
46  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
47  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
48  */
49  AudioDelay(unsigned int delaytime_cells): _write_pos(0), _delaytime_cells(delaytime_cells)
50  {}
51 
52 
53 
54  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
55  @param in_value the signal input.
56  @param delaytime_cells sets the delay time in terms of cells in the delay buffer.
57  */
58  inline
59  T next(T in_value, unsigned int delaytime_cells)
60  {
61  ++_write_pos &= (NUM_BUFFER_SAMPLES - 1);
62  unsigned int read_pos = (_write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
63 
64  // why does delay jump if I read it before writing?
65  delay_array[_write_pos] = in_value; // write to buffer
66  int8_t delay_sig = delay_array[read_pos] ; // read the delay buffer
67 
68  return (T)delay_sig;
69  }
70 
71 
72 
73  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
74  @param in_value the signal input.
75  */
76  inline
77  T next(T in_value)
78  {
79  ++_write_pos &= (NUM_BUFFER_SAMPLES - 1);
80  unsigned int read_pos = (_write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
81 
82  // why does delay jump if I read it before writing?
83  delay_array[_write_pos] = in_value; // write to buffer
84  T delay_sig = delay_array[read_pos] ; // read the delay buffer
85 
86  return delay_sig;
87  }
88 
89 
90  /** Set the delay time, measured in cells.
91  @param delaytime_cells how many cells to delay the input signal by.
92  */
93  inline
94  void set(unsigned int delaytime_cells){
95  _delaytime_cells = delaytime_cells;
96  }
97 
98 
99  /** Retrieve the signal in the delay line at the position delaytime_cells.
100  It doesn't change the stored internal value of _delaytime_cells.
101  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
102  */
103  inline
104  T read(unsigned int delaytime_cells)
105  {
106  unsigned int read_pos = (_write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
107  return delay_array[read_pos];
108  }
109 
110 
111  // /** Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal.
112  // This can be useful for manually adding feedback to the delay line, "behind" the advancing write head.
113  // @param input the signal input.
114  // */
115  // inline
116  // void writeFeedback(T input)
117  // {
118  // delay_array[_write_pos] = input;
119  // }
120 
121 };
122 
123 /**
124 @example 09.Delays/AudioDelay/AudioDelay.ino
125 This is an example of how to use the AudioDelay class.
126 */
127 
128 #endif // #ifndef AUDIODELAY_H_
T next(T in_value)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells...
Definition: AudioDelay.h:77
-
void set(unsigned int delaytime_cells)
Set the delay time, measured in cells.
Definition: AudioDelay.h:94
-
Audio delay line for comb filter, flange, chorus and short echo effects.
Definition: AudioDelay.h:27
-
AudioDelay(unsigned int delaytime_cells)
Constructor.
Definition: AudioDelay.h:49
-
T next(T in_value, unsigned int delaytime_cells)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells...
Definition: AudioDelay.h:59
-
AudioDelay()
Constructor.
Definition: AudioDelay.h:40
-
T read(unsigned int delaytime_cells)
Retrieve the signal in the delay line at the position delaytime_cells.
Definition: AudioDelay.h:104
+
1 /*
+
2  * AudioDelay.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 AUDIODELAY_H_
+
13 #define AUDIODELAY_H_
+
14 
+
15 
+
16 /** Audio delay line for comb filter, flange, chorus and short echo effects.
+
17 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples. This should
+
18 be a power of two. The largest delay you'll fit in an atmega328 will be 512
+
19 cells, which at 16384 Hz sample rate is 31 milliseconds. More of a flanger or a
+
20 doubler than an echo. The amount of memory available for delays on other chips will vary.
+
21 AudioDelay() doesn't have feedback. If you want feedback, use AudioDelayFeedback().
+
22 @tparam the type of numbers to use for the signal in the delay. The default is int8_t, but int could be useful
+
23 when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
+
24 */
+
25 
+
26 template <unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
+ +
28 {
+
29 
+
30 private:
+
31 
+
32  T delay_array[NUM_BUFFER_SAMPLES];
+
33  unsigned int _write_pos;
+
34  unsigned int _delaytime_cells;
+
35 
+
36 public:
+
37 
+
38  /** Constructor.
+
39  */
+
40  AudioDelay(): _write_pos(0)
+
41  {}
+
42 
+
43 
+
44  /** Constructor.
+
45  @param delaytime_cells delay time expressed in cells.
+
46  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
+
47  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
+
48  */
+
49  AudioDelay(unsigned int delaytime_cells): _write_pos(0), _delaytime_cells(delaytime_cells)
+
50  {}
+
51 
+
52 
+
53 
+
54  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
+
55  @param in_value the signal input.
+
56  @param delaytime_cells sets the delay time in terms of cells in the delay buffer.
+
57  */
+
58  inline
+
59  T next(T in_value, unsigned int delaytime_cells)
+
60  {
+
61  ++_write_pos &= (NUM_BUFFER_SAMPLES - 1);
+
62  unsigned int read_pos = (_write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
+
63 
+
64  // why does delay jump if I read it before writing?
+
65  delay_array[_write_pos] = in_value; // write to buffer
+
66  int8_t delay_sig = delay_array[read_pos] ; // read the delay buffer
+
67 
+
68  return (T)delay_sig;
+
69  }
+
70 
+
71 
+
72 
+
73  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
+
74  @param in_value the signal input.
+
75  */
+
76  inline
+
77  T next(T in_value)
+
78  {
+
79  ++_write_pos &= (NUM_BUFFER_SAMPLES - 1);
+
80  unsigned int read_pos = (_write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
+
81 
+
82  // why does delay jump if I read it before writing?
+
83  delay_array[_write_pos] = in_value; // write to buffer
+
84  T delay_sig = delay_array[read_pos] ; // read the delay buffer
+
85 
+
86  return delay_sig;
+
87  }
+
88 
+
89 
+
90  /** Set the delay time, measured in cells.
+
91  @param delaytime_cells how many cells to delay the input signal by.
+
92  */
+
93  inline
+
94  void set(unsigned int delaytime_cells){
+
95  _delaytime_cells = delaytime_cells;
+
96  }
+
97 
+
98 
+
99  /** Retrieve the signal in the delay line at the position delaytime_cells.
+
100  It doesn't change the stored internal value of _delaytime_cells.
+
101  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
+
102  */
+
103  inline
+
104  T read(unsigned int delaytime_cells)
+
105  {
+
106  unsigned int read_pos = (_write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
+
107  return delay_array[read_pos];
+
108  }
+
109 
+
110 
+
111  // /** Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal.
+
112  // This can be useful for manually adding feedback to the delay line, "behind" the advancing write head.
+
113  // @param input the signal input.
+
114  // */
+
115  // inline
+
116  // void writeFeedback(T input)
+
117  // {
+
118  // delay_array[_write_pos] = input;
+
119  // }
+
120 
+
121 };
+
122 
+
123 /**
+
124 @example 09.Delays/AudioDelay/AudioDelay.ino
+
125 This is an example of how to use the AudioDelay class.
+
126 */
+
127 
+
128 #endif // #ifndef AUDIODELAY_H_
diff --git a/extras/doc/html/_audio_delay_feedback_8h_source.html b/extras/doc/html/_audio_delay_feedback_8h_source.html index f87fc857b..e37859c6d 100644 --- a/extras/doc/html/_audio_delay_feedback_8h_source.html +++ b/extras/doc/html/_audio_delay_feedback_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: AudioDelayFeedback.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,27 +99,418 @@
AudioDelayFeedback.h
-
1 /*
2  * AudioDelayFeedback.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUDIODELAY_FEEDBACK_H_
13 #define AUDIODELAY_FEEDBACK_H_
14 
15 #include <Arduino.h>
16 
17 #include "mozzi_utils.h"
18 #include "meta.h"
19 
20 enum interpolation_types {LINEAR,ALLPASS};
21 
22 
23 /** Audio delay line with feedback for comb filter, flange, chorus and short echo effects.
24 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples, and should be a
25 power of two. The maximum delay length which will fit in an atmega328 is half
26 that of a plain AudioDelay object, in this case 256 cells, or about 15
27 milliseconds. AudioDelayFeedback uses int16_t sized cells to accomodate the higher
28 amplitude of direct input to the delay as well as the feedback, without losing
29 precision. Output is only the delay line signal. If you want to mix the delay
30 with the input, do it in your sketch. AudioDelayFeedback uses more processing and memory
31 than a plain AudioDelay, but allows for more dramatic effects with feedback.
32 @tparam INTERP_TYPE a choice of LINEAR (default) or ALLPASS interpolation. LINEAR is better
33 for sweeping delay times, ALLPASS may be better for reverb-like effects.
34 */
35 template <uint16_t NUM_BUFFER_SAMPLES, int8_t INTERP_TYPE = LINEAR>
36 class AudioDelayFeedback
37 {
38 
39 public:
40  /** Constructor.
41  */
43  {}
44 
45 
46  /** Constructor.
47  @param delaytime_cells delay time expressed in cells.
48  For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
49  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
50  */
52  {}
53 
54 
55  /** Constructor.
56  @param delaytime_cells delay time expressed in cells.
57  For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
58  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
59  @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1).
60  */
61  AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level): write_pos(0), _feedback_level(feedback_level), _delaytime_cells(delaytime_cells)
62  {}
63 
64 
65 
66  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
67  @param input the signal input.
68  @note slower than next(int8_t input, uint16_t delaytime_cells)
69  */
70  inline
72  {
73  // chooses a different next() function depending on whether the
74  // the template parameter is LINEAR(default if none provided) or ALLPASS.
75  // See meta.h.
76  return next(input, Int2Type<INTERP_TYPE>());
77  }
78 
79 
80 
81  /** Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells, and add feedback from the output to the input.
82  @param input the signal input.
83  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
84  It doesn't change the stored internal value of _delaytime_cells.
85  @note Timing: 4us
86  */
87  inline
88  int16_t next(int8_t input, uint16_t delaytime_cells)
89  {
90  //setPin13High();
91  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
92  uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
93  // < 1us to here
94  int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
95  // with this line, the method takes 18us
96  //int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
97  // this line, the whole method takes 4us... Compiler doesn't optimise pow2 divides. Why?
98  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
99  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
100  //setPin13Low();
101  return delay_sig;
102  }
103 
104 
105 
106  /** Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input.
107  @param input the signal input.
108  @param delaytime_cells is a fractional number to set the delay time in terms of cells
109  or partial cells in the delay buffer. It doesn't change the stored internal
110  value of _delaytime_cells.
111  */
112  inline
113  int16_t next(int8_t input, Q16n16 delaytime_cells)
114  {
115  //setPin13High();
116  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
117 
118  uint16_t index = Q16n16_to_Q16n0(delaytime_cells);
119  uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word
120 
121  uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
122  int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
123 
124  uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
125  int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
126 
127 
128  int16_t difference = delay_sig2 - delay_sig1;
129  int16_t delay_sig_fraction = (int16_t)((int32_t)((int32_t) fraction * difference) >> 16);
130 
131  int16_t delay_sig = delay_sig1+delay_sig_fraction;
132 
133  //int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
134 
135  int8_t feedback_sig = (int8_t) min(max((((int16_t)(delay_sig * _feedback_level))>>7),-128),127); // feedback clipped
136  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
137  //setPin13Low();
138  return delay_sig;
139  }
140 
141 
142  /** Input a value to the delay but don't change the delay time or retrieve the output signal.
143  @param input the signal input.
144  */
145  inline
146  void write(int8_t input)
147  {
148  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
149  delay_array[write_pos] = input;
150  }
151 
152 
153  /** Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal.
154  This can be useful for manually adding feedback to the delay line, "behind" the advancing write head.
155  @param input the signal input.
156  */
157  inline
158  void writeFeedback(int8_t input)
159  {
160  delay_array[write_pos] = input;
161  }
162 
163 
164  /** Input a value to the delay at an offset from the current write position. Don't advance the main
165  write position or change the stored delay time or retrieve the output signal.
166  @param input the signal input.
167  @param offset the number of cells behind the ordinary write position where the input will be written.
168  */
169  inline
170  void write(int8_t input, uint16_t offset)
171  {
172  uint16_t _pos = (write_pos + offset) & (NUM_BUFFER_SAMPLES - 1);
173  delay_array[_pos] = input;
174  }
175 
176 
177  /** Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
178  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
179  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
180  */
181  inline
183  {
184  return read(delaytime_cells, Int2Type<INTERP_TYPE>());
185  }
186 
187 
188  /** Retrieve the signal in the delay line at the current stored delaytime_cells.
189  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
190  */
191  inline
193  {
194  return read(Int2Type<INTERP_TYPE>());
195  }
196 
197 
198  /** Set delay time expressed in samples.
199  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
200  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
201  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
202  */
203  inline
204  void setDelayTimeCells(uint16_t delaytime_cells)
205  {
206  _delaytime_cells = (uint16_t) delaytime_cells;
207  }
208 
209 
210  /** Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
211  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
212  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
213  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
214  */
215  inline
216  void setDelayTimeCells(Q16n16 delaytime_cells)
217  {
218  return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
219  }
220 
221 
222  /** Set delay time expressed in samples, fractional float for an interpolating delay.
223  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
224  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
225  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
226  */
227  inline
228  void setDelayTimeCells(float delaytime_cells)
229  {
230  return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
231  }
232 
233 
234  /** Set the feedback gain.
235  @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1).
236  */
237  inline
238  void setFeedbackLevel(int8_t feedback_level)
239  {
240  _feedback_level = feedback_level;
241  }
242 
243 
244 
245 private:
246  int16_t delay_array[NUM_BUFFER_SAMPLES];
247  uint16_t write_pos;
248  int8_t _feedback_level;
249  uint16_t _delaytime_cells;
250  Q15n16 _coeff; // for allpass interpolation
251 
252 
253 
254  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
255  @param in_value the signal input.
256  */
257  inline
258  int16_t next(int8_t in_value, Int2Type<LINEAR>)
259  {
260  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
261  uint16_t read_pos = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
262 
263  int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
264  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
265  delay_array[write_pos] = (int16_t) in_value + feedback_sig; // write to buffer
266 
267  return delay_sig;
268  }
269 
270 
271 
272  /** The delaytime_cells has to be set seperately, because it's slowish
273  and in this implementation the allpass interpolation mode doesn't slide
274  nicely from one delay time to another.
275  @param input an audio signal in
276  @return the delayed signal, including feedback
277  @note Timing: 10us
278  */
279  inline
280  int16_t next(int8_t input, Int2Type<ALLPASS>)
281  {
282  /*
283  http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
284  also https://ccrma.stanford.edu/~jos/Interpolation/Interpolation_4up.pdf
285  for desired fractional delay of d samples,
286  coeff = (1-d)/(1+d)
287  or
288  coeff = ((d-1)>1) + (((d-1)*(d-1))>>2) - (((d-1)*(d-1)*(d-1))>>3)
289  out = coeff * in + last_in - coeff * last_out
290  = coeff * (in-last_out) + last_in
291  */
292  //setPin13High();
293  static int8_t last_in;
294  static int16_t last_out;
295 
296  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
297 
298  uint16_t read_pos1 = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
299  int16_t delay_sig = delay_array[read_pos1]; // read the delay buffer
300 
301  int16_t interp = (int16_t)(_coeff * ((int16_t)input - last_out)>>16) + last_in; // Q15n16*Q15n0 + Q15n0 = Q15n16 + Q15n0 = Q15n16
302  delay_sig += interp;
303 
304  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
305  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
306 
307  last_in = input;
308  last_out = delay_sig;
309  //setPin13Low();
310  return delay_sig;
311  }
312 
313 
314 
315  // 20-25us
316  inline
317  void setDelayTimeCells(Q16n16 delaytime_cells, Int2Type<ALLPASS>)
318  {
319  /*
320  integer optimisation/approximation from
321  Van Duyne, Jaffe, Scandalis, Stilson 1997
322  http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
323  //coeff = -((d-1)>1) + (((d-1)*(d-1))>>2) - (((d-1)*(d-1)*(d-1))>>3) , d is fractional part
324  */
325  _delaytime_cells = delaytime_cells>>16; // whole integer part
326  Q15n16 dminus1 = - Q15n16_FIX1 + (uint16_t) delaytime_cells;
327  Q15n16 dminus1squared = (dminus1)*(dminus1)>>16;
328  _coeff = -(dminus1>>1) + (dminus1squared>>2) - (((dminus1squared*dminus1)>>16)>>3);
329  }
330 
331 
332  // 100us
333  inline
334  void setDelayTimeCells(float delaytime_cells, Int2Type<ALLPASS>)
335  {
336  //coeff = (1-d)/(1+d)
337  _delaytime_cells = (uint16_t) delaytime_cells;
338 
339  float fraction = delaytime_cells - _delaytime_cells;
340 
341  // modified from stk DelayA.cpp
342  float alpha_ = 1.0f + fraction; // fractional part
343  if ( alpha_ < 0.5f ) {
344  // (stk): The optimal range for alpha is about 0.5 - 1.5 in order to
345  // achieve the flattest phase delay response.
346 
347  // something's not right about how I use _delaytime_cells and
348  // NUM_BUFFER_SAMPLES etc. in my ringbuffer compared to stk
349  _delaytime_cells += 1;
350  if ( _delaytime_cells >= NUM_BUFFER_SAMPLES ) _delaytime_cells -= NUM_BUFFER_SAMPLES;
351  alpha_ += 1.0f;
352  }
353  // otherwise this would use fraction instead of alpha
354  _coeff = float_to_Q15n16((1.f-alpha_)/(1.f+alpha_));
355  }
356 
357  // Retrieve the signal in the delay line at the position delaytime_cells.
358  // It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
359  // param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
360  //
361  // inline
362  // int16_t read(uint16_t delaytime_cells, Int2Type<LINEAR>)
363  // {
364  // uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
365  // int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
366  //
367  // return delay_sig;
368  // }
369 
370  /** Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
371  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
372  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
373  */
374  inline
375  int16_t read(Q16n16 delaytime_cells, Int2Type<LINEAR>)
376  {
377  uint16_t index = (Q16n16)delaytime_cells >> 16;
378  uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word
379 
380  uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
381  int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
382 
383  uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
384  int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
385 
386  /*
387  int16_t difference = delay_sig2 - delay_sig1;
388  int16_t delay_sig_fraction = ((int32_t) fraction * difference) >> 16;
389 
390  int16_t delay_sig = delay_sig1+delay_sig_fraction;
391  */
392  int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
393 
394  return delay_sig;
395  }
396 
397 
398 };
399 
400 /**
401 @example 09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino
402 This is an example of how to use the AudioDelayFeedback class.
403 */
404 
405 #endif // #ifndef AUDIODELAY_FEEDBACK_H_
void write(int8_t input)
Input a value to the delay but don&#39;t change the delay time or retrieve the output signal...
-
void write(int8_t input, uint16_t offset)
Input a value to the delay at an offset from the current write position.
-
void setFeedbackLevel(int8_t feedback_level)
Set the feedback gain.
-
int16_t read(Q16n16 delaytime_cells)
Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
-
AudioDelayFeedback()
Constructor.
-
void writeFeedback(int8_t input)
Input a value to the delay but don&#39;t advance the write position, change the delay time or retrieve th...
-
void setDelayTimeCells(float delaytime_cells)
Set delay time expressed in samples, fractional float for an interpolating delay. ...
-
int16_t read()
Retrieve the signal in the delay line at the current stored delaytime_cells.
-
AudioDelayFeedback(uint16_t delaytime_cells)
Constructor.
-
void setDelayTimeCells(Q16n16 delaytime_cells)
Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
-
int16_t next(int8_t input)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells...
-
AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level)
Constructor.
+
1 /*
+
2  * AudioDelayFeedback.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 AUDIODELAY_FEEDBACK_H_
+
13 #define AUDIODELAY_FEEDBACK_H_
+
14 
+
15 #include <Arduino.h>
+
16 
+
17 #include "mozzi_utils.h"
+
18 #include "meta.h"
+
19 
+
20 enum interpolation_types {LINEAR,ALLPASS};
+
21 
+
22 
+
23 /** Audio delay line with feedback for comb filter, flange, chorus and short echo effects.
+
24 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples, and should be a
+
25 power of two. The maximum delay length which will fit in an atmega328 is half
+
26 that of a plain AudioDelay object, in this case 256 cells, or about 15
+
27 milliseconds. AudioDelayFeedback uses int16_t sized cells to accomodate the higher
+
28 amplitude of direct input to the delay as well as the feedback, without losing
+
29 precision. Output is only the delay line signal. If you want to mix the delay
+
30 with the input, do it in your sketch. AudioDelayFeedback uses more processing and memory
+
31 than a plain AudioDelay, but allows for more dramatic effects with feedback.
+
32 @tparam INTERP_TYPE a choice of LINEAR (default) or ALLPASS interpolation. LINEAR is better
+
33 for sweeping delay times, ALLPASS may be better for reverb-like effects.
+
34 */
+
35 template <uint16_t NUM_BUFFER_SAMPLES, int8_t INTERP_TYPE = LINEAR>
+ +
37 {
+
38 
+
39 public:
+
40  /** Constructor.
+
41  */
+ +
43  {}
+
44 
+
45 
+
46  /** Constructor.
+
47  @param delaytime_cells delay time expressed in cells.
+
48  For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
+
49  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
+
50  */
+ +
52  {}
+
53 
+
54 
+
55  /** Constructor.
+
56  @param delaytime_cells delay time expressed in cells.
+
57  For example, 128 cells delay at MOZZI_AUDIO_RATE 16384 would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
+
58  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
+
59  @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1).
+
60  */
+
61  AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level): write_pos(0), _feedback_level(feedback_level), _delaytime_cells(delaytime_cells)
+
62  {}
+
63 
+
64 
+
65 
+
66  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
+
67  @param input the signal input.
+
68  @note slower than next(int8_t input, uint16_t delaytime_cells)
+
69  */
+
70  inline
+ +
72  {
+
73  // chooses a different next() function depending on whether the
+
74  // the template parameter is LINEAR(default if none provided) or ALLPASS.
+
75  // See meta.h.
+
76  return next(input, Int2Type<INTERP_TYPE>());
+
77  }
+
78 
+
79 
+
80 
+
81  /** Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells, and add feedback from the output to the input.
+
82  @param input the signal input.
+
83  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
+
84  It doesn't change the stored internal value of _delaytime_cells.
+
85  @note Timing: 4us
+
86  */
+
87  inline
+ +
89  {
+
90  //setPin13High();
+
91  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
+
92  uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
+
93  // < 1us to here
+
94  int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
+
95  // with this line, the method takes 18us
+
96  //int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
+
97  // this line, the whole method takes 4us... Compiler doesn't optimise pow2 divides. Why?
+
98  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
+
99  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
+
100  //setPin13Low();
+
101  return delay_sig;
+
102  }
+
103 
+
104 
+
105 
+
106  /** Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input.
+
107  @param input the signal input.
+
108  @param delaytime_cells is a fractional number to set the delay time in terms of cells
+
109  or partial cells in the delay buffer. It doesn't change the stored internal
+
110  value of _delaytime_cells.
+
111  */
+
112  inline
+ +
114  {
+
115  //setPin13High();
+
116  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
+
117 
+
118  uint16_t index = Q16n16_to_Q16n0(delaytime_cells);
+
119  uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word
+
120 
+
121  uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
+
122  int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
+
123 
+
124  uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
+
125  int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
+
126 
+
127 
+
128  int16_t difference = delay_sig2 - delay_sig1;
+
129  int16_t delay_sig_fraction = (int16_t)((int32_t)((int32_t) fraction * difference) >> 16);
+
130 
+
131  int16_t delay_sig = delay_sig1+delay_sig_fraction;
+
132 
+
133  //int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
+
134 
+
135  int8_t feedback_sig = (int8_t) min(max((((int16_t)(delay_sig * _feedback_level))>>7),-128),127); // feedback clipped
+
136  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
+
137  //setPin13Low();
+
138  return delay_sig;
+
139  }
+
140 
+
141 
+
142  /** Input a value to the delay but don't change the delay time or retrieve the output signal.
+
143  @param input the signal input.
+
144  */
+
145  inline
+
146  void write(int8_t input)
+
147  {
+
148  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
+
149  delay_array[write_pos] = input;
+
150  }
+
151 
+
152 
+
153  /** Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal.
+
154  This can be useful for manually adding feedback to the delay line, "behind" the advancing write head.
+
155  @param input the signal input.
+
156  */
+
157  inline
+
158  void writeFeedback(int8_t input)
+
159  {
+
160  delay_array[write_pos] = input;
+
161  }
+
162 
+
163 
+
164  /** Input a value to the delay at an offset from the current write position. Don't advance the main
+
165  write position or change the stored delay time or retrieve the output signal.
+
166  @param input the signal input.
+
167  @param offset the number of cells behind the ordinary write position where the input will be written.
+
168  */
+
169  inline
+
170  void write(int8_t input, uint16_t offset)
+
171  {
+
172  uint16_t _pos = (write_pos + offset) & (NUM_BUFFER_SAMPLES - 1);
+
173  delay_array[_pos] = input;
+
174  }
+
175 
+
176 
+
177  /** Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
+
178  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
+
179  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
+
180  */
+
181  inline
+ +
183  {
+
184  return read(delaytime_cells, Int2Type<INTERP_TYPE>());
+
185  }
+
186 
+
187 
+
188  /** Retrieve the signal in the delay line at the current stored delaytime_cells.
+
189  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
+
190  */
+
191  inline
+ +
193  {
+
194  return read(Int2Type<INTERP_TYPE>());
+
195  }
+
196 
+
197 
+
198  /** Set delay time expressed in samples.
+
199  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
+
200  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
+
201  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
+
202  */
+
203  inline
+
204  void setDelayTimeCells(uint16_t delaytime_cells)
+
205  {
+
206  _delaytime_cells = (uint16_t) delaytime_cells;
+
207  }
+
208 
+
209 
+
210  /** Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
+
211  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
+
212  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
+
213  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
+
214  */
+
215  inline
+
216  void setDelayTimeCells(Q16n16 delaytime_cells)
+
217  {
+
218  return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
+
219  }
+
220 
+
221 
+
222  /** Set delay time expressed in samples, fractional float for an interpolating delay.
+
223  @param delaytime_cells delay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE.
+
224  For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms
+
225  Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
+
226  */
+
227  inline
+
228  void setDelayTimeCells(float delaytime_cells)
+
229  {
+
230  return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
+
231  }
+
232 
+
233 
+
234  /** Set the feedback gain.
+
235  @param feedback_level is the feedback level from -128 to 127 (representing -1 to 1).
+
236  */
+
237  inline
+
238  void setFeedbackLevel(int8_t feedback_level)
+
239  {
+
240  _feedback_level = feedback_level;
+
241  }
+
242 
+
243 
+
244 
+
245 private:
+ +
247  uint16_t write_pos;
+
248  int8_t _feedback_level;
+
249  uint16_t _delaytime_cells;
+
250  Q15n16 _coeff; // for allpass interpolation
+
251 
+
252 
+
253 
+
254  /** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
+
255  @param in_value the signal input.
+
256  */
+
257  inline
+
258  int16_t next(int8_t in_value, Int2Type<LINEAR>)
+
259  {
+
260  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
+
261  uint16_t read_pos = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
+
262 
+
263  int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
+
264  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
+
265  delay_array[write_pos] = (int16_t) in_value + feedback_sig; // write to buffer
+
266 
+
267  return delay_sig;
+
268  }
+
269 
+
270 
+
271 
+
272  /** The delaytime_cells has to be set seperately, because it's slowish
+
273  and in this implementation the allpass interpolation mode doesn't slide
+
274  nicely from one delay time to another.
+
275  @param input an audio signal in
+
276  @return the delayed signal, including feedback
+
277  @note Timing: 10us
+
278  */
+
279  inline
+
280  int16_t next(int8_t input, Int2Type<ALLPASS>)
+
281  {
+
282  /*
+
283  http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
+
284  also https://ccrma.stanford.edu/~jos/Interpolation/Interpolation_4up.pdf
+
285  for desired fractional delay of d samples,
+
286  coeff = (1-d)/(1+d)
+
287  or
+
288  coeff = ((d-1)>1) + (((d-1)*(d-1))>>2) - (((d-1)*(d-1)*(d-1))>>3)
+
289  out = coeff * in + last_in - coeff * last_out
+
290  = coeff * (in-last_out) + last_in
+
291  */
+
292  //setPin13High();
+
293  static int8_t last_in;
+
294  static int16_t last_out;
+
295 
+
296  ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
+
297 
+
298  uint16_t read_pos1 = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
+
299  int16_t delay_sig = delay_array[read_pos1]; // read the delay buffer
+
300 
+
301  int16_t interp = (int16_t)(_coeff * ((int16_t)input - last_out)>>16) + last_in; // Q15n16*Q15n0 + Q15n0 = Q15n16 + Q15n0 = Q15n16
+
302  delay_sig += interp;
+
303 
+
304  int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
+
305  delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
+
306 
+
307  last_in = input;
+
308  last_out = delay_sig;
+
309  //setPin13Low();
+
310  return delay_sig;
+
311  }
+
312 
+
313 
+
314 
+
315  // 20-25us
+
316  inline
+
317  void setDelayTimeCells(Q16n16 delaytime_cells, Int2Type<ALLPASS>)
+
318  {
+
319  /*
+
320  integer optimisation/approximation from
+
321  Van Duyne, Jaffe, Scandalis, Stilson 1997
+
322  http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
+
323  //coeff = -((d-1)>1) + (((d-1)*(d-1))>>2) - (((d-1)*(d-1)*(d-1))>>3) , d is fractional part
+
324  */
+
325  _delaytime_cells = delaytime_cells>>16; // whole integer part
+
326  Q15n16 dminus1 = - Q15n16_FIX1 + (uint16_t) delaytime_cells;
+
327  Q15n16 dminus1squared = (dminus1)*(dminus1)>>16;
+
328  _coeff = -(dminus1>>1) + (dminus1squared>>2) - (((dminus1squared*dminus1)>>16)>>3);
+
329  }
+
330 
+
331 
+
332  // 100us
+
333  inline
+
334  void setDelayTimeCells(float delaytime_cells, Int2Type<ALLPASS>)
+
335  {
+
336  //coeff = (1-d)/(1+d)
+
337  _delaytime_cells = (uint16_t) delaytime_cells;
+
338 
+
339  float fraction = delaytime_cells - _delaytime_cells;
+
340 
+
341  // modified from stk DelayA.cpp
+
342  float alpha_ = 1.0f + fraction; // fractional part
+
343  if ( alpha_ < 0.5f ) {
+
344  // (stk): The optimal range for alpha is about 0.5 - 1.5 in order to
+
345  // achieve the flattest phase delay response.
+
346 
+
347  // something's not right about how I use _delaytime_cells and
+
348  // NUM_BUFFER_SAMPLES etc. in my ringbuffer compared to stk
+
349  _delaytime_cells += 1;
+
350  if ( _delaytime_cells >= NUM_BUFFER_SAMPLES ) _delaytime_cells -= NUM_BUFFER_SAMPLES;
+
351  alpha_ += 1.0f;
+
352  }
+
353  // otherwise this would use fraction instead of alpha
+
354  _coeff = float_to_Q15n16((1.f-alpha_)/(1.f+alpha_));
+
355  }
+
356 
+
357  // Retrieve the signal in the delay line at the position delaytime_cells.
+
358  // It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
+
359  // param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
+
360  //
+
361  // inline
+
362  // int16_t read(uint16_t delaytime_cells, Int2Type<LINEAR>)
+
363  // {
+
364  // uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
+
365  // int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
+
366  //
+
367  // return delay_sig;
+
368  // }
+
369 
+
370  /** Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
+
371  It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
+
372  @param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
+
373  */
+
374  inline
+
375  int16_t read(Q16n16 delaytime_cells, Int2Type<LINEAR>)
+
376  {
+
377  uint16_t index = (Q16n16)delaytime_cells >> 16;
+
378  uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word
+
379 
+
380  uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
+
381  int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
+
382 
+
383  uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
+
384  int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
+
385 
+
386  /*
+
387  int16_t difference = delay_sig2 - delay_sig1;
+
388  int16_t delay_sig_fraction = ((int32_t) fraction * difference) >> 16;
+
389 
+
390  int16_t delay_sig = delay_sig1+delay_sig_fraction;
+
391  */
+
392  int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
+
393 
+
394  return delay_sig;
+
395  }
+
396 
+
397 
+
398 };
+
399 
+
400 /**
+
401 @example 09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino
+
402 This is an example of how to use the AudioDelayFeedback class.
+
403 */
+
404 
+
405 #endif // #ifndef AUDIODELAY_FEEDBACK_H_
diff --git a/extras/doc/html/_audio_output_8h_source.html b/extras/doc/html/_audio_output_8h_source.html index f30427af5..6d084b00c 100644 --- a/extras/doc/html/_audio_output_8h_source.html +++ b/extras/doc/html/_audio_output_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: AudioOutput.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,33 +99,260 @@
AudioOutput.h
-
1 /** @defgroup audio_output Audio Output and Buffering
2  *
3  * @details Documentation on basic Mozzi architecture and output modes */
4 
5 /** @ingroup audio_output
6  * @page mozzi_audio_output_architecture Basic architecture of audio generation, buffering, and output in Mozzi
7  *
8  * Mozzi provides support for audio ouput on a range of different boards and CPUs. This page is about the following related topics:
9  *
10  * - adding a custom output method (importantly using external DACs) to your sketch
11  * - writing sketches that will work on different platforms / with different output methods
12  * - extending Mozzi for a new architecture
13  *
14  * For all of these topics, it is helpful to have a basic understanding of the basic output steps in Mozzi:
15  *
16  * 1. Inside the loop() function in your sketch you call audioHook().
17  * 1a. If the audio output buffer is currently filled, this does nothing.
18  * 1b. Otherwise, this calls updateAudio(). The generated sample is then added to the audio output buffer. (Also, updateControl() will be called at an appropriate rate,
19  * and a few other details that are not important for this discussion.)
20  *
21  * 2. A platform-specific timer is triggered at audio rate (usually), takes a sample from the output buffer and sends it to audioOutput().
22  *
23  * 3. The audioOutput() function - usually predefined inside Mozzi - takes care of sending the sample to the hardware.
24  *
25  * These output steps are not always followed, however. Firstly, when using @ref external_audio output, the audioOutput() funtion is supplied by the user sketch,
26  * instead of Mozzi. @ref external_audio output.
27  *
28  * Some ports will also want to bypass the Mozzi audio output buffer. For instance, an internal DAC may be addressable via an efficient DMA-connected
29  * buffer, already, and also have a built-in rate control. In this case, ports will internally set the define @ref BYPASS_MOZZI_OUTPUT_BUFFER to true. Such a port will
30  * have to provide a custom definition of canBufferAudioOutput(), returning true, whenever a new sample of output can be accepted. No timer at audio-rate is set up in this
31  * case.
32  *
33  * Finally, the @ref external_audio output mode (@ref MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM) is essentially a combination of the two. Here, the user sketch needs to provide
34  * both audioOutput() and canBufferAudioOutput(). The latter is again called from audioHook(), and whenever it returns true, a new sample is generated and passed to
35  * audioOutput().
36  *
37  * @section audio_shifting Platform specific audio resolution
38  * Different output methods often support a different resolution of output samples. To provide best performance on slow boards, Mozzi expects your updateAudio() function to
39  * return samples in exactly the width that is needed at the output stage. Thus, defining this naively, an updateAudio() function designed for 8 bit output will produce very
40  * low volume output on a 16 bit DAC, while the other way around overflows will result in way too loud and heavily distored output. Fortunately, all that is needed to write
41  * portable sketches is to specify how many bits your updateAudio() function provides. The (inline) functions in the AudioOutput namespace do just that. Using them makes sure
42  * your audio output is shifted if, and as much as needed on all platforms.
43  *
44  * @see MonoOutput::fromNBit(), StereoOutput::fromNBit()
45  */
46 
47 #ifndef AUDIOOUTPUT_H
48 #define AUDIOOUTPUT_H
49 
50 /** The type used to store a single channel of a single frame, internally. For compatibility with earlier versions of Mozzi this is defined as int.
51  * If you do not care about keeping old sketches working, you may be able to save some RAM by using int16_t, instead (on boards where int is larger
52  * than 16 bits). */
53 #define AudioOutputStorage_t int
54 
55 template<typename T> constexpr AudioOutputStorage_t SCALE_AUDIO(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS ? (x) >> (bits - MOZZI_AUDIO_BITS) : (x) << (MOZZI_AUDIO_BITS - bits)); }
56 template<typename T> constexpr AudioOutputStorage_t SCALE_AUDIO_NEAR(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS_OPTIMISTIC ? (x) >> (bits - MOZZI_AUDIO_BITS_OPTIMISTIC) : (x) << (MOZZI_AUDIO_BITS_OPTIMISTIC - bits)); }
57 template<typename T> constexpr AudioOutputStorage_t CLIP_AUDIO(T x) { return (constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) (MOZZI_AUDIO_BIAS-1))); }
58 
59 struct MonoOutput;
60 struct StereoOutput;
61 
62 #if MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO)
63 typedef StereoOutput AudioOutput;
64 #else
65 /** Representation of an single audio output sample/frame. This typedef maps to either MonoOutput or StereoOutput, depending on what is configured
66  * in MOZZI_AUDIO_CHANNELS. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g.
67  * both have functions l() and r(), to return "two" audio channels (which will be the same in case of mono).
68  *
69  * You will not usually use or encounter this definition, unless using @ref external_audio output mode.
70  */
71 typedef MonoOutput AudioOutput;
72 #endif
73 
74 #if MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST
75 #if (MOZZI_COMPATIBILITY_LEVEL <= MOZZI_COMPATIBILITY_1_1) && MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_MONO)
76 typedef int AudioOutput_t; // Note: Needed for pre 1.1 backwards compatibility
77 #else
78 /** Transitory alias to AudioOutput. The only point of this typedef is to keep old code working. In new code,
79  * use AudioOutput, directly, instead.
80 */
81 MOZZI_DEPRECATED("2.0", "Replace AudioOutput_t with simple AudioOutput") typedef AudioOutput AudioOutput_t;
82 #endif
83 #endif
84 
85 /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to a single int value, but the struct provides
86  * useful API an top of that, for the following:
87  *
88  * a) To construct an output frame, you should use one of the from8Bit(), fromNBit(), etc. functions. Given a raw input value, at a known resolution (number of bits),
89  * this scales the output efficiently to whatever is needed on the target platform. Using this, your updateAudio() function will be portable across different CPU and
90  * different output methods, including external DACs.
91  * b) The struct provides some convenience API on top of this. Right now, this is the function clip(), replacing the more verbose, and non-portable constrain(x, -244, 243)
92  * found in some old sketches.
93  * c) The struct provides accessors l() and r() that are source-compatible with StereoOutput, making it easy to e.g. implement support for an external DAC in both mono
94  * and stereo.
95  * d) Finally, an automatic conversion operator to int aka AudioOutput_t provides backward compatibility with old Mozzi sketches. Internally, the compiler will actually
96  * do away with this whole struct, leaving just the same basic fast integer operations as in older Mozzi sketches. However, now, you don't have to rewrite those for
97  * different configurations.
98  */
99 struct MonoOutput {
100  /** Default constructor. Does not initialize the sample! */
102  /** Construct an audio frame from raw values (zero-centered) */
104 #if (MOZZI_AUDIO_CHANNELS > 1)
105  /** Conversion to stereo operator: If used in a stereo config, returns identical channels (and gives a compile time warning).
106  This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
107  using StereoOutput in a mono config, is not intended. */
108  StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check MOZZI_AUDIO_CHANNELS setting."))); // Note: defintion below
109 #endif
110  /** Conversion to int operator. */
111  operator AudioOutputStorage_t() const { return _l; };
112 
113  AudioOutputStorage_t l() const { return _l; };
114  AudioOutputStorage_t r() const { return _l; };
115  /** Clip frame to supported range. This is useful when at times, but only rarely, the signal may exceed the usual range. Using this function does not avoid
116  * artifacts, entirely, but gives much better results than an overflow. */
117  MonoOutput& clip() { _l = CLIP_AUDIO(_l); return *this; };
118 
119  /** Construct an audio frame a zero-centered value known to be in the N bit range. Appropriate left- or right-shifting will be performed, based on the number of output
120  * bits available. While this function takes care of the shifting, beware of potential overflow issues, if your intermediary results exceed the 16 bit range. Use proper
121  * casts to int32_t or larger in that case (and the compiler will automatically pick the 32 bit overload in this case) */
122  template<typename T> static inline MonoOutput fromNBit(uint8_t bits, T l) { return MonoOutput(SCALE_AUDIO(l, bits)); }
123  /** Construct an audio frame from a zero-centered value known to be in the 8 bit range. On AVR, if MOZZI_OUTPUT_PWM mode, this is effectively the same as calling the
124  * constructor, directly (no scaling gets applied). On platforms/configs using more bits, an appropriate left-shift will be performed. */
125  static inline MonoOutput from8Bit(int16_t l) { return fromNBit(8, l); }
126  /** Construct an audio frame a zero-centered value known to be in the 16 bit range. This is jsut a shortcut for fromNBit(16, ...) provided for convenience. */
127  static inline MonoOutput from16Bit(int16_t l) { return fromNBit(16, l); }
128  /** Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit range, e.g. at N=8 bits and a litte. On most platforms, this is
129  * exactly the same as fromNBit(), shifting up or down to the platforms' available resolution.
130  *
131  * However, on AVR, MOZZI_OUTPUT_PWM mode (where about 8.5 bits are usable), the value will be shifted to the (almost) 9 bit range, instead of to the 8 bit range. allowing to
132  * make use of that extra half bit of resolution. In many cases it is useful to follow up this call with clip(). E.g.:
133  *
134  * @code
135  * return MonoOutput::fromAlmostNBit(10, oscilA.next() + oscilB.next() + oscilC.next()).clip();
136  * @endcode
137  */
138  template<typename A, typename B> static inline MonoOutput fromAlmostNBit(A bits, B l) { return MonoOutput(SCALE_AUDIO_NEAR(l, bits)); }
139 
140 private:
142 };
143 
144 /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to two int values, but the struct provides
145  * useful API an top of that. For more detail see @ref MonoOutput . */
146 struct StereoOutput {
147  /** Construct an audio frame from raw values (zero-centered) */
149  /** Default constructor. Does not initialize the sample! */
151 #if !MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO)
152  /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning).
153  This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
154  using StereoOutput in a mono config, is not intended. */
155  inline AudioOutput portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; };
156 # if GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO
157  inline operator AudioOutput() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; };
158 # endif
159 #endif
160  AudioOutputStorage_t l() const { return _l; };
161  AudioOutputStorage_t r() const { return _r; };
162  /** See @ref MonoOutput::clip(). Clips both channels. */
163  StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; };
164 
165  /** See @ref MonoOutput::fromNBit(), stereo variant */
166 template<typename T> static inline StereoOutput fromNBit(uint8_t bits, T l, T r) { return StereoOutput(SCALE_AUDIO(l, bits), SCALE_AUDIO(r, bits)); }
167  /** See @ref MonoOutput::from8Bit(), stereo variant */
168  static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); }
169  /** See @ref MonoOutput::from16Bit(), stereo variant */
170  static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); }
171  /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */
172  template<typename A, typename B> static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); }
173 private:
176 };
177 
178 #if MOZZI_AUDIO_CHANNELS > 1
179 StereoOutput MonoOutput::portable() const { return StereoOutput(_l, _l); };
180 #endif
181 
182 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
183 /** When setting using one of the external output modes (@ref MOZZI_OUTPUT_EXTERNAL_TIMED or @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM) implement this function to take care of writing samples to the hardware.
184  * In all otther cases, it will be provided by the platform implementation. You should never call this function, directly, in your sketch. */
185 void audioOutput(const AudioOutput f);
186 #endif
187 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
188 /** For @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM implement this function to return true, if and only if your hardware (or custom buffer) is ready to accept the next sample. */
189 inline bool canBufferAudioOutput();
190 #endif
191 
192 /** Perform one step of (fast) pdm encoding, returning 8 "bits" (i.e. 8 ones and zeros).
193  * You will usually call this at least four or eight times, and possibly much more often
194  * for a single input sample.
195  *
196  * The return type is defined as uint32_t to avoid conversion steps. Actually, only the 8 lowest
197  * bits of the return value are set. */
198 inline uint32_t pdmCode8(uint16_t sample) {
199  // lookup table for fast pdm coding on 8 output bits at a time
200  static const byte fast_pdm_table[]{0, 0b00010000, 0b01000100,
201  0b10010010, 0b10101010, 0b10110101,
202  0b11011101, 0b11110111, 0b11111111};
203 
204  static uint32_t lastwritten = 0;
205  static uint32_t nexttarget = 0;
206  // in each iteration, code the highest 3-and-a-little bits.
207  // Note that sample only has 16 bits, while the
208  // highest bit we consider for writing is bit 17.
209  // Thus, if the highest bit is set, the next
210  // three bits cannot be. (highest possible values:
211  // nexttarget-lastwritten == 0b00001111111111111,
212  // sample == 0b01111111111111111)
213  nexttarget += sample;
214  nexttarget -= lastwritten;
215  lastwritten = nexttarget & 0b11110000000000000;
216  return fast_pdm_table[lastwritten >> 13];
217 }
218 
219 /** Convenience function to perform four iterations of pdmCode8() */
220 inline uint32_t pdmCode32(uint16_t sample) {
221  uint32_t outbits = 0;
222  for (uint8_t i = 0; i < 4; ++i) {
223  outbits = outbits << 8;
224  outbits |= pdmCode8(sample);
225  }
226  return outbits;
227 }
228 
229 #endif
static MonoOutput from16Bit(int16_t l)
Construct an audio frame a zero-centered value known to be in the 16 bit range.
Definition: AudioOutput.h:127
-
static MonoOutput fromAlmostNBit(A bits, B l)
Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit ra...
Definition: AudioOutput.h:138
-
StereoOutput & clip()
See MonoOutput::clip().
Definition: AudioOutput.h:163
-
static StereoOutput fromNBit(uint8_t bits, T l, T r)
See MonoOutput::fromNBit(), stereo variant.
Definition: AudioOutput.h:166
-
StereoOutput()
Default constructor.
Definition: AudioOutput.h:150
-
static MonoOutput from8Bit(int16_t l)
Construct an audio frame from a zero-centered value known to be in the 8 bit range.
Definition: AudioOutput.h:125
-
AudioOutput portable() const __attribute__((deprecated("Sketch generates stereo output
Conversion to int operator: If used in a mono config, returns only the left channel (and gives a comp...
-
This struct encapsulates one frame of mono audio output.
Definition: AudioOutput.h:99
-
static StereoOutput from8Bit(int16_t l, int16_t r)
See MonoOutput::from8Bit(), stereo variant.
Definition: AudioOutput.h:168
-
MonoOutput()
Default constructor.
Definition: AudioOutput.h:101
-
MonoOutput(AudioOutputStorage_t l)
Construct an audio frame from raw values (zero-centered)
Definition: AudioOutput.h:103
-
MonoOutput & clip()
Clip frame to supported range.
Definition: AudioOutput.h:117
-
static StereoOutput from16Bit(int16_t l, int16_t r)
See MonoOutput::from16Bit(), stereo variant.
Definition: AudioOutput.h:170
-
operator AudioOutputStorage_t() const
Conversion to int operator.
Definition: AudioOutput.h:111
-
StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r)
Construct an audio frame from raw values (zero-centered)
Definition: AudioOutput.h:148
-
static StereoOutput fromAlmostNBit(A bits, B l, B r)
See MonoOutput::fromAlmostNBit(), stereo variant.
Definition: AudioOutput.h:172
-
static MonoOutput fromNBit(uint8_t bits, T l)
Construct an audio frame a zero-centered value known to be in the N bit range.
Definition: AudioOutput.h:122
-
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:53
+
1 /*
+
2  * AudioOutput.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2021-2024 Thomas Friedrichsmeier 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 /** @defgroup audio_output Audio Output and Buffering
+
13  *
+
14  * @details Documentation on basic Mozzi architecture and output modes */
+
15 
+
16 /** @ingroup audio_output
+
17  * @page mozzi_audio_output_architecture Basic architecture of audio generation, buffering, and output in Mozzi
+
18  *
+
19  * Mozzi provides support for audio ouput on a range of different boards and CPUs. This page is about the following related topics:
+
20  *
+
21  * - adding a custom output method (importantly using external DACs) to your sketch
+
22  * - writing sketches that will work on different platforms / with different output methods
+
23  * - extending Mozzi for a new architecture
+
24  *
+
25  * For all of these topics, it is helpful to have a basic understanding of the basic output steps in Mozzi:
+
26  *
+
27  * 1. Inside the loop() function in your sketch you call audioHook().
+
28  * 1a. If the audio output buffer is currently filled, this does nothing.
+
29  * 1b. Otherwise, this calls updateAudio(). The generated sample is then added to the audio output buffer. (Also, updateControl() will be called at an appropriate rate,
+
30  * and a few other details that are not important for this discussion.)
+
31  *
+
32  * 2. A platform-specific timer is triggered at audio rate (usually), takes a sample from the output buffer and sends it to audioOutput().
+
33  *
+
34  * 3. The audioOutput() function - usually predefined inside Mozzi - takes care of sending the sample to the hardware.
+
35  *
+
36  * These output steps are not always followed, however. Firstly, when using @ref external_audio output, the audioOutput() funtion is supplied by the user sketch,
+
37  * instead of Mozzi. @ref external_audio output.
+
38  *
+
39  * Some ports will also want to bypass the Mozzi audio output buffer. For instance, an internal DAC may be addressable via an efficient DMA-connected
+
40  * buffer, already, and also have a built-in rate control. In this case, ports will internally set the define @ref BYPASS_MOZZI_OUTPUT_BUFFER to true. Such a port will
+
41  * have to provide a custom definition of canBufferAudioOutput(), returning true, whenever a new sample of output can be accepted. No timer at audio-rate is set up in this
+
42  * case.
+
43  *
+
44  * Finally, the @ref external_audio output mode (@ref MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM) is essentially a combination of the two. Here, the user sketch needs to provide
+
45  * both audioOutput() and canBufferAudioOutput(). The latter is again called from audioHook(), and whenever it returns true, a new sample is generated and passed to
+
46  * audioOutput().
+
47  *
+
48  * @section audio_shifting Platform specific audio resolution
+
49  * Different output methods often support a different resolution of output samples. To provide best performance on slow boards, Mozzi expects your updateAudio() function to
+
50  * return samples in exactly the width that is needed at the output stage. Thus, defining this naively, an updateAudio() function designed for 8 bit output will produce very
+
51  * low volume output on a 16 bit DAC, while the other way around overflows will result in way too loud and heavily distored output. Fortunately, all that is needed to write
+
52  * portable sketches is to specify how many bits your updateAudio() function provides. The (inline) functions in the AudioOutput namespace do just that. Using them makes sure
+
53  * your audio output is shifted if, and as much as needed on all platforms.
+
54  *
+
55  * @see MonoOutput::fromNBit(), StereoOutput::fromNBit()
+
56  */
+
57 
+
58 #ifndef AUDIOOUTPUT_H
+
59 #define AUDIOOUTPUT_H
+
60 #include <FixMath.h>
+
61 
+
62 /** The type used to store a single channel of a single frame, internally. For compatibility with earlier versions of Mozzi this is defined as int.
+
63  * If you do not care about keeping old sketches working, you may be able to save some RAM by using int16_t, instead (on boards where int is larger
+
64  * than 16 bits). */
+
65 #define AudioOutputStorage_t int
+
66 
+
67 template<typename T> constexpr AudioOutputStorage_t SCALE_AUDIO(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS ? (x) >> (bits - MOZZI_AUDIO_BITS) : (x) << (MOZZI_AUDIO_BITS - bits)); }
+
68 template<typename T> constexpr AudioOutputStorage_t SCALE_AUDIO_NEAR(T x, byte bits) { return (bits > MOZZI_AUDIO_BITS_OPTIMISTIC ? (x) >> (bits - MOZZI_AUDIO_BITS_OPTIMISTIC) : (x) << (MOZZI_AUDIO_BITS_OPTIMISTIC - bits)); }
+
69 template<typename T> constexpr AudioOutputStorage_t CLIP_AUDIO(T x) { return (constrain((x), (-(AudioOutputStorage_t) MOZZI_AUDIO_BIAS), (AudioOutputStorage_t) (MOZZI_AUDIO_BIAS-1))); }
+
70 
+
71 struct MonoOutput;
+
72 struct StereoOutput;
+
73 
+ +
75 typedef StereoOutput AudioOutput;
+
76 #else
+
77 /** Representation of an single audio output sample/frame. This typedef maps to either MonoOutput or StereoOutput, depending on what is configured
+
78  * in MOZZI_AUDIO_CHANNELS. Since the two are source compatible to a large degree, it often isn't even necessary to test, which it is, in your code. E.g.
+
79  * both have functions l() and r(), to return "two" audio channels (which will be the same in case of mono).
+
80  *
+
81  * You will not usually use or encounter this definition, unless using @ref external_audio output mode.
+
82  */
+
83 typedef MonoOutput AudioOutput;
+
84 #endif
+
85 
+ + +
88 typedef int AudioOutput_t; // Note: Needed for pre 1.1 backwards compatibility
+
89 #else
+
90 /** Transitory alias to AudioOutput. The only point of this typedef is to keep old code working. In new code,
+
91  * use AudioOutput, directly, instead.
+
92 */
+
93 MOZZI_DEPRECATED("2.0", "Replace AudioOutput_t with simple AudioOutput") typedef AudioOutput AudioOutput_t;
+
94 #endif
+
95 #endif
+
96 
+
97 /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to a single int value, but the struct provides
+
98  * useful API an top of that, for the following:
+
99  *
+
100  * a) To construct an output frame, you should use one of the from8Bit(), fromNBit(), etc. functions. Given a raw input value, at a known resolution (number of bits),
+
101  * this scales the output efficiently to whatever is needed on the target platform. Using this, your updateAudio() function will be portable across different CPU and
+
102  * different output methods, including external DACs.
+
103  * b) The struct provides some convenience API on top of this. Right now, this is the function clip(), replacing the more verbose, and non-portable constrain(x, -244, 243)
+
104  * found in some old sketches.
+
105  * c) The struct provides accessors l() and r() that are source-compatible with StereoOutput, making it easy to e.g. implement support for an external DAC in both mono
+
106  * and stereo.
+
107  * d) Finally, an automatic conversion operator to int aka AudioOutput_t provides backward compatibility with old Mozzi sketches. Internally, the compiler will actually
+
108  * do away with this whole struct, leaving just the same basic fast integer operations as in older Mozzi sketches. However, now, you don't have to rewrite those for
+
109  * different configurations.
+
110  */
+
111 struct MonoOutput {
+
112  /** Default constructor. Does not initialize the sample! */
+ +
114  /** Construct an audio frame from raw values (zero-centered) */
+ +
116 #if (MOZZI_AUDIO_CHANNELS > 1)
+
117  /** Conversion to stereo operator: If used in a stereo config, returns identical channels (and gives a compile time warning).
+
118  This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
+
119  using StereoOutput in a mono config, is not intended. */
+
120  StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check MOZZI_AUDIO_CHANNELS setting."))); // Note: defintion below
+
121 #endif
+
122  /** Conversion to int operator. */
+
123  operator AudioOutputStorage_t() const { return _l; };
+
124 
+
125  AudioOutputStorage_t l() const { return _l; };
+
126  AudioOutputStorage_t r() const { return _l; };
+
127  /** Clip frame to supported range. This is useful when at times, but only rarely, the signal may exceed the usual range. Using this function does not avoid
+
128  * artifacts, entirely, but gives much better results than an overflow. */
+
129  MonoOutput& clip() { _l = CLIP_AUDIO(_l); return *this; };
+
130 
+
131  /** Construct an audio frame a zero-centered value known to be in the N bit range. Appropriate left- or right-shifting will be performed, based on the number of output
+
132  * bits available. While this function takes care of the shifting, beware of potential overflow issues, if your intermediary results exceed the 16 bit range. Use proper
+
133  * casts to int32_t or larger in that case (and the compiler will automatically pick the 32 bit overload in this case) */
+
134  template<typename T> static inline MonoOutput fromNBit(uint8_t bits, T l) { return MonoOutput(SCALE_AUDIO(l, bits)); }
+
135  /** Construct an audio frame from a zero-centered value known to be in the 8 bit range. On AVR, if MOZZI_OUTPUT_PWM mode, this is effectively the same as calling the
+
136  * constructor, directly (no scaling gets applied). On platforms/configs using more bits, an appropriate left-shift will be performed. */
+
137  static inline MonoOutput from8Bit(int16_t l) { return fromNBit(8, l); }
+
138  /** Construct an audio frame from a zero-centered value known to be in the 16 bit range. This is jsut a shortcut for fromNBit(16, ...) provided for convenience. */
+
139  static inline MonoOutput from16Bit(int16_t l) { return fromNBit(16, l); }
+
140  /** Construct an audio frame from a SFix type from FixMath. Mozzi will figure out how many bits are in there and performs appropriate shifting to match the output range. */
+
141  template<int8_t NI, int8_t NF, uint64_t RANGE>
+
142  static inline MonoOutput fromSFix(SFix<NI,NF,RANGE> l) { return MonoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF+1))) ;}
+
143  /** Construct an audio frame a zero-centered value known to be above at almost but not quite the N bit range, e.g. at N=8 bits and a litte. On most platforms, this is
+
144  * exactly the same as fromNBit(), shifting up or down to the platforms' available resolution.
+
145  *
+
146  * However, on AVR, MOZZI_OUTPUT_PWM mode (where about 8.5 bits are usable), the value will be shifted to the (almost) 9 bit range, instead of to the 8 bit range. allowing to
+
147  * make use of that extra half bit of resolution. In many cases it is useful to follow up this call with clip(). E.g.:
+
148  *
+
149  * @code
+
150  * return MonoOutput::fromAlmostNBit(10, oscilA.next() + oscilB.next() + oscilC.next()).clip();
+
151  * @endcode
+
152  */
+
153  template<typename A, typename B> static inline MonoOutput fromAlmostNBit(A bits, B l) { return MonoOutput(SCALE_AUDIO_NEAR(l, bits)); }
+
154 
+
155 private:
+ +
157 };
+
158 
+
159 /** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to two int values, but the struct provides
+
160  * useful API an top of that. For more detail see @ref MonoOutput . */
+
161 struct StereoOutput {
+
162  /** Construct an audio frame from raw values (zero-centered) */
+ +
164  /** Default constructor. Does not initialize the sample! */
+ + +
167  /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning).
+
168  This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
+
169  using StereoOutput in a mono config, is not intended. */
+
170  inline AudioOutput portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; };
+
171 # if GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO
+
172  inline operator AudioOutput() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; };
+
173 # endif
+
174 #endif
+
175  AudioOutputStorage_t l() const { return _l; };
+
176  AudioOutputStorage_t r() const { return _r; };
+
177  /** See @ref MonoOutput::clip(). Clips both channels. */
+
178  StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; };
+
179 
+
180  /** See @ref MonoOutput::fromNBit(), stereo variant */
+
181 template<typename T> static inline StereoOutput fromNBit(uint8_t bits, T l, T r) { return StereoOutput(SCALE_AUDIO(l, bits), SCALE_AUDIO(r, bits)); }
+
182  /** See @ref MonoOutput::from8Bit(), stereo variant */
+
183  static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); }
+
184  /** See @ref MonoOutput::from16Bit(), stereo variant */
+
185  static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); }
+
186 /** See @ref MonoOutput::fromSFix(), stereo variant. Note that the two channels do not need to have the same number of bits. */
+
187  template<int8_t NI, int8_t NF, uint64_t RANGE, int8_t _NI, int8_t _NF, uint64_t _RANGE>
+
188  static inline StereoOutput fromSFix(SFix<NI,NF,RANGE> l, SFix<_NI,_NF,_RANGE> r) { return StereoOutput(SCALE_AUDIO(l.asRaw(), (NI+NF+1)), SCALE_AUDIO(r.asRaw(), (_NI+_NF+1))); }
+
189  /** See @ref MonoOutput::fromAlmostNBit(), stereo variant */
+
190  template<typename A, typename B> static inline StereoOutput fromAlmostNBit(A bits, B l, B r) { return StereoOutput(SCALE_AUDIO_NEAR(l, bits), SCALE_AUDIO_NEAR(r, bits)); }
+
191 private:
+ + +
194 };
+
195 
+
196 #if MOZZI_AUDIO_CHANNELS > 1
+
197 StereoOutput MonoOutput::portable() const { return StereoOutput(_l, _l); };
+
198 #endif
+
199 
+ +
201 /** When setting using one of the external output modes (@ref MOZZI_OUTPUT_EXTERNAL_TIMED or @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM) implement this function to take care of writing samples to the hardware.
+
202  * In all otther cases, it will be provided by the platform implementation. You should never call this function, directly, in your sketch. */
+
203 void audioOutput(const AudioOutput f);
+
204 #endif
+
205 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
206 /** For @ref MOZZI_OUTPUT_EXTERNAL_CUSTOM implement this function to return true, if and only if your hardware (or custom buffer) is ready to accept the next sample. */
+
207 inline bool canBufferAudioOutput();
+
208 #endif
+
209 
+
210 /** Perform one step of (fast) pdm encoding, returning 8 "bits" (i.e. 8 ones and zeros).
+
211  * You will usually call this at least four or eight times, and possibly much more often
+
212  * for a single input sample.
+
213  *
+
214  * The return type is defined as uint32_t to avoid conversion steps. Actually, only the 8 lowest
+
215  * bits of the return value are set. */
+
216 inline uint32_t pdmCode8(uint16_t sample) {
+
217  // lookup table for fast pdm coding on 8 output bits at a time
+
218  static const byte fast_pdm_table[]{0, 0b00010000, 0b01000100,
+
219  0b10010010, 0b10101010, 0b10110101,
+
220  0b11011101, 0b11110111, 0b11111111};
+
221 
+
222  static uint32_t lastwritten = 0;
+
223  static uint32_t nexttarget = 0;
+
224  // in each iteration, code the highest 3-and-a-little bits.
+
225  // Note that sample only has 16 bits, while the
+
226  // highest bit we consider for writing is bit 17.
+
227  // Thus, if the highest bit is set, the next
+
228  // three bits cannot be. (highest possible values:
+
229  // nexttarget-lastwritten == 0b00001111111111111,
+
230  // sample == 0b01111111111111111)
+
231  nexttarget += sample;
+
232  nexttarget -= lastwritten;
+
233  lastwritten = nexttarget & 0b11110000000000000;
+
234  return fast_pdm_table[lastwritten >> 13];
+
235 }
+
236 
+
237 /** Convenience function to perform four iterations of pdmCode8() */
+
238 inline uint32_t pdmCode32(uint16_t sample) {
+
239  uint32_t outbits = 0;
+
240  for (uint8_t i = 0; i < 4; ++i) {
+
241  outbits = outbits << 8;
+
242  outbits |= pdmCode8(sample);
+
243  }
+
244  return outbits;
+
245 }
+
246 
+
247 #endif
diff --git a/extras/doc/html/_auto_map_8h_source.html b/extras/doc/html/_auto_map_8h_source.html index e38417982..6f4ca9d1f 100644 --- a/extras/doc/html/_auto_map_8h_source.html +++ b/extras/doc/html/_auto_map_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: AutoMap.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,22 +99,90 @@
AutoMap.h
-
1 /*
2  * AutoMap.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef AUTOMAP_H_
13 #define AUTOMAP_H_
14 
15 // for map - maybe rewrite my own templated map for better efficiency
16 #include <Arduino.h> // for map
17 
18 #include "AutoRange.h"
19 
20 /** @defgroup sensortools Automatic range adjustment
21 */
22 
23 /** @ingroup sensortools
24 Automatically map an input value to an output range without knowing the precise range of inputs beforehand.
25 */
26 
27 class AutoMap : public AutoRange<int>
28 {
29 public:
30  /** Constructor.
31  @param min_expected the minimum possible input value.
32  @param max_expected the maximum possible input value.
33  */
34  AutoMap(int min_expected, int max_expected, int map_to_min, int map_to_max)
35  : inherited(min_expected,max_expected),map_min(map_to_min), map_max(map_to_max)
36  {
37  }
38 
39 
40  /** Process the next value and return it mapped to the range which was set in the constructor.
41  Can use the operator instead if you prefer, eg. myMap(n) instead of myMap.next(n).
42  @param n the next value to process.
43  @return the input value mapped to the range which was set in the constructor.
44  */
45  inline
46  int next(int n)
47  {
48  inherited::next(n);
49  return map(n,inherited::getMin(),inherited::getMax(),map_min,map_max);
50  }
51 
52  /** Process the next value and return it mapped to the range which was set in the constructor.
53  This is an alternative to next() if you prefer, eg. myMap(n) instead of myMap.next(n).
54  @param n the next value to process.
55  @return the input value mapped to the range which was set in the constructor.
56  */
57  inline
58  int operator()(int n)
59  {
60  return next(n);
61  }
62 
63 
64 private:
65  typedef AutoRange <int> inherited;
66  int map_min, map_max;
67 };
68 
69 
70 /**
71 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
72 This example demonstrates the AutoMap class.
73 */
74 
75 #endif // #ifndef AUTOMAP_H_
AutoRange(T min_expected, T max_expected)
Constructor.
Definition: AutoRange.h:27
-
void next(T n)
Updates the current range.
Definition: AutoRange.h:35
-
int next(int n)
Process the next value and return it mapped to the range which was set in the constructor.
Definition: AutoMap.h:46
-
Keeps a running calculation of the range of the input values it receives.
Definition: AutoRange.h:18
-
AutoMap(int min_expected, int max_expected, int map_to_min, int map_to_max)
Constructor.
Definition: AutoMap.h:34
-
Automatically map an input value to an output range without knowing the precise range of inputs befor...
Definition: AutoMap.h:27
-
int operator()(int n)
Process the next value and return it mapped to the range which was set in the constructor.
Definition: AutoMap.h:58
+
1 /*
+
2  * AutoMap.h
+
3 /*
+
4  * AutoMap.h
+
5  *
+
6  * This file is part of Mozzi.
+
7  *
+
8  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
9  *
+
10  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
11  *
+
12  */
+
13 
+
14 #ifndef AUTOMAP_H_
+
15 #define AUTOMAP_H_
+
16 
+
17 // for map - maybe rewrite my own templated map for better efficiency
+
18 #include <Arduino.h> // for map
+
19 
+
20 #include "AutoRange.h"
+
21 
+
22 /** @defgroup sensortools Automatic range adjustment
+
23 */
+
24 
+
25 /** @ingroup sensortools
+
26 Automatically map an input value to an output range without knowing the precise range of inputs beforehand.
+
27 */
+
28 
+
29 class AutoMap : public AutoRange<int>
+
30 {
+
31 public:
+
32  /** Constructor.
+
33  @param min_expected the minimum possible input value.
+
34  @param max_expected the maximum possible input value.
+
35  */
+
36  AutoMap(int min_expected, int max_expected, int map_to_min, int map_to_max)
+
37  : inherited(min_expected,max_expected),map_min(map_to_min), map_max(map_to_max)
+
38  {
+
39  }
+
40 
+
41 
+
42  /** Process the next value and return it mapped to the range which was set in the constructor.
+
43  Can use the operator instead if you prefer, eg. myMap(n) instead of myMap.next(n).
+
44  @param n the next value to process.
+
45  @return the input value mapped to the range which was set in the constructor.
+
46  */
+
47  inline
+
48  int next(int n)
+
49  {
+
50  inherited::next(n);
+
51  return map(n,inherited::getMin(),inherited::getMax(),map_min,map_max);
+
52  }
+
53 
+
54  /** Process the next value and return it mapped to the range which was set in the constructor.
+
55  This is an alternative to next() if you prefer, eg. myMap(n) instead of myMap.next(n).
+
56  @param n the next value to process.
+
57  @return the input value mapped to the range which was set in the constructor.
+
58  */
+
59  inline
+
60  int operator()(int n)
+
61  {
+
62  return next(n);
+
63  }
+
64 
+
65 
+
66 private:
+
67  typedef AutoRange <int> inherited;
+
68  int map_min, map_max;
+
69 };
+
70 
+
71 
+
72 /**
+
73 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
+
74 This example demonstrates the AutoMap class.
+
75 */
+
76 
+
77 #endif // #ifndef AUTOMAP_H_
diff --git a/extras/doc/html/_auto_range_8h_source.html b/extras/doc/html/_auto_range_8h_source.html index 07657ca82..c7560d016 100644 --- a/extras/doc/html/_auto_range_8h_source.html +++ b/extras/doc/html/_auto_range_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: AutoRange.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,21 +99,97 @@
AutoRange.h
-
1 /*
2  * AutoRange.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 #ifndef AUTORANGE_H
12 #define AUTORANGE_H
13 
14 /** @ingroup sensortools
15 Keeps a running calculation of the range of the input values it receives.
16 */
17 template <class T>
18 class
19  AutoRange {
20 
21 public:
22  /** Constructor.
23  @tparam T the type of numbers to to use, eg. int, unsigned int, float etc.
24  @param min_expected the minimum possible input value.
25  @param max_expected the maximum possible input value.
26  */
27  AutoRange(T min_expected, T max_expected):range_min(max_expected),range_max(min_expected),range(0)
28  {
29  }
30 
31 
32  /** Updates the current range.
33  @param n the next value to include in the range calculation.
34  */
35  void next(T n)
36  {
37  if (n > range_max)
38  {
39  range_max = n;
40  range = range_max - range_min;
41  }
42  else
43  {
44  if (n< range_min)
45  {
46  range_min = n;
47  range = range_max - range_min;
48  }
49  }
50  }
51 
52  /** Returns the current minimum.
53  @return minimum
54  */
55  T getMin()
56  {
57  return range_min;
58  }
59 
60 
61  /** Returns the current maximum.
62  @return maximum
63  */
64  T getMax()
65  {
66  return range_max;
67  }
68 
69 
70  /** Returns the current range.
71  @return range
72  */
74  {
75  return range;
76  }
77 
78 private:
79  T range_max, range_min, range;
80 
81 };
82 
83 #endif // #ifndef AUTORANGE_H
T getMax()
Returns the current maximum.
Definition: AutoRange.h:64
-
AutoRange(T min_expected, T max_expected)
Constructor.
Definition: AutoRange.h:27
-
T getRange()
Returns the current range.
Definition: AutoRange.h:73
-
void next(T n)
Updates the current range.
Definition: AutoRange.h:35
-
Keeps a running calculation of the range of the input values it receives.
Definition: AutoRange.h:18
-
T getMin()
Returns the current minimum.
Definition: AutoRange.h:55
+
1 /*
+
2  * AutoRange.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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 AUTORANGE_H
+
13 #define AUTORANGE_H
+
14 
+
15 /** @ingroup sensortools
+
16 Keeps a running calculation of the range of the input values it receives.
+
17 */
+
18 template <class T>
+
19 class
+
20  AutoRange {
+
21 
+
22 public:
+
23  /** Constructor.
+
24  @tparam T the type of numbers to to use, eg. int, unsigned int, float etc.
+
25  @param min_expected the minimum possible input value.
+
26  @param max_expected the maximum possible input value.
+
27  */
+
28  AutoRange(T min_expected, T max_expected):range_min(max_expected),range_max(min_expected),range(0)
+
29  {
+
30  }
+
31 
+
32 
+
33  /** Updates the current range.
+
34  @param n the next value to include in the range calculation.
+
35  */
+
36  void next(T n)
+
37  {
+
38  if (n > range_max)
+
39  {
+
40  range_max = n;
+
41  range = range_max - range_min;
+
42  }
+
43  else
+
44  {
+
45  if (n< range_min)
+
46  {
+
47  range_min = n;
+
48  range = range_max - range_min;
+
49  }
+
50  }
+
51  }
+
52 
+
53  /** Returns the current minimum.
+
54  @return minimum
+
55  */
+
56  T getMin()
+
57  {
+
58  return range_min;
+
59  }
+
60 
+
61 
+
62  /** Returns the current maximum.
+
63  @return maximum
+
64  */
+
65  T getMax()
+
66  {
+
67  return range_max;
+
68  }
+
69 
+
70 
+
71  /** Returns the current range.
+
72  @return range
+
73  */
+ +
75  {
+
76  return range;
+
77  }
+
78 
+
79 private:
+
80  T range_max, range_min, range;
+
81 
+
82 };
+
83 
+
84 #endif // #ifndef AUTORANGE_H
diff --git a/extras/doc/html/_cap_poll_8h_source.html b/extras/doc/html/_cap_poll_8h_source.html index afb60e1c9..ded7c36ca 100644 --- a/extras/doc/html/_cap_poll_8h_source.html +++ b/extras/doc/html/_cap_poll_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: CapPoll.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,18 +99,79 @@
CapPoll.h
-
1 #ifndef RCPOLL_H
2 #define RCPOLL_H
3 
4 
5 /**
6 A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.
7 This is designed to be used in updateControl(). Each time it is called, it checks if a capacitor has charged,
8 and returns an output reflecting how long it took for the most recent charge.
9 */
10 
11 template <unsigned char SENSOR_PIN, unsigned char SEND_PIN>
12 class CapPoll
13 {
14 
15 public:
16  /** Constructor.
17  */
18  CapPoll():result(0),rc_cued(true), output(0)
19  {
20  ;
21  }
22 
23  /** Checks whether the capacitor has charged, and returns how long it took for the most recent charge.
24  This would preferably be called in updateControl(), but if the resolution isn't fine enough or the
25  pin charges too fast for updateControl() to catch, try it in updateAudio().
26  @return the sensor value, reflected in how many checking cycles it took to charge the capacitor.
27  */
28  inline
29  unsigned int next(){
30  if (rc_cued){
31  pinMode(SENSOR_PIN, INPUT); // turn pin into an input and time till pin goes low
32  digitalWrite(SENSOR_PIN, LOW); // turn pullups off - or it won't work
33  rc_cued = false;
34  }
35  if(digitalRead(SENSOR_PIN)){ // wait for pin to go low
36  result++;
37  }
38  else{
39  output = result;
40  result = 0;
41  pinMode(SENSOR_PIN, OUTPUT); // make pin OUTPUT
42  digitalWrite(SENSOR_PIN, HIGH); // make pin HIGH to discharge capacitor - see the schematic
43  rc_cued = true;
44  }
45  return output;
46  }
47 
48 private:
49  unsigned int result;
50  boolean rc_cued;
51  unsigned int output;
52 
53 };
54 
55 #endif // #ifndef RCPOLL_H
CapPoll()
Constructor.
Definition: CapPoll.h:18
-
A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.
Definition: CapPoll.h:12
-
unsigned int next()
Checks whether the capacitor has charged, and returns how long it took for the most recent charge...
Definition: CapPoll.h:29
+
1 /*
+
2  * CapPoll.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2015-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 RCPOLL_H
+
13 #define RCPOLL_H
+
14 
+
15 
+
16 /**
+
17 A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.
+
18 This is designed to be used in updateControl(). Each time it is called, it checks if a capacitor has charged,
+
19 and returns an output reflecting how long it took for the most recent charge.
+
20 */
+
21 
+
22 template <unsigned char SENSOR_PIN, unsigned char SEND_PIN>
+
23 class CapPoll
+
24 {
+
25 
+
26 public:
+
27  /** Constructor.
+
28  */
+
29  CapPoll():result(0),rc_cued(true), output(0)
+
30  {
+
31  ;
+
32  }
+
33 
+
34  /** Checks whether the capacitor has charged, and returns how long it took for the most recent charge.
+
35  This would preferably be called in updateControl(), but if the resolution isn't fine enough or the
+
36  pin charges too fast for updateControl() to catch, try it in updateAudio().
+
37  @return the sensor value, reflected in how many checking cycles it took to charge the capacitor.
+
38  */
+
39  inline
+
40  unsigned int next(){
+
41  if (rc_cued){
+
42  pinMode(SENSOR_PIN, INPUT); // turn pin into an input and time till pin goes low
+
43  digitalWrite(SENSOR_PIN, LOW); // turn pullups off - or it won't work
+
44  rc_cued = false;
+
45  }
+
46  if(digitalRead(SENSOR_PIN)){ // wait for pin to go low
+
47  result++;
+
48  }
+
49  else{
+
50  output = result;
+
51  result = 0;
+
52  pinMode(SENSOR_PIN, OUTPUT); // make pin OUTPUT
+
53  digitalWrite(SENSOR_PIN, HIGH); // make pin HIGH to discharge capacitor - see the schematic
+
54  rc_cued = true;
+
55  }
+
56  return output;
+
57  }
+
58 
+
59 private:
+
60  unsigned int result;
+
61  boolean rc_cued;
+
62  unsigned int output;
+
63 
+
64 };
+
65 
+
66 #endif // #ifndef RCPOLL_H
diff --git a/extras/doc/html/_circular_buffer_8h_source.html b/extras/doc/html/_circular_buffer_8h_source.html index 44811ba9a..f1c828e19 100644 --- a/extras/doc/html/_circular_buffer_8h_source.html +++ b/extras/doc/html/_circular_buffer_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: CircularBuffer.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,18 +99,107 @@
CircularBuffer.h
-
1 /*
2 Modified from https://en.wikipedia.org/wiki/Circular_buffer
3 Mirroring version
4 On 18 April 2014, the simplified version on the Wikipedia page for power of 2 sized buffers
5 doesn't work - cbIsEmpty() returns true whether the buffer is full or empty.
6 */
7 
8 #define MOZZI_BUFFER_SIZE 256 // do not expect to change and it to work.
9  // just here for forward compatibility if one day
10  // the buffer size might be editable
11 
12 /** Circular buffer object. Has a fixed number of cells, set to 256.
13 @tparam ITEM_TYPE the kind of data to store, eg. int, int8_t etc.
14 */
15 template <class ITEM_TYPE>
17 {
18 
19 public:
20  /** Constructor
21  */
23  {
24  }
25 
26  inline
27  bool isFull() {
28  return end == start && e_msb != s_msb;
29  }
30 
31  inline
32  bool isEmpty() {
33  return end == start && e_msb == s_msb;
34  }
35 
36  inline
37  void write(ITEM_TYPE in) {
38  items[end] = in;
39  //if (isFull()) cbIncrStart(); /* full, overwrite moves start pointer */
40  cbIncrEnd();
41  }
42 
43  inline
44  ITEM_TYPE read() {
45  ITEM_TYPE out = items[start];
46  cbIncrStart();
47  return out;
48  }
49 
50  inline
51  unsigned long count() {
52  return (num_buffers_read << 8) + start;
53  }
54  inline
55  ITEM_TYPE * address() {
56  return items;
57  }
58 
59 private:
60  ITEM_TYPE items[MOZZI_BUFFER_SIZE];
61  uint8_t start; /* index of oldest itement */
62  uint8_t end; /* index at which to write new itement */
63  uint8_t s_msb;
64  uint8_t e_msb;
65  unsigned long num_buffers_read;
66 
67 
68  inline
69  void cbIncrStart() {
70  start++;
71  if (start == 0) {
72  s_msb ^= 1;
73  num_buffers_read++;
74  }
75  }
76 
77  inline
78  void cbIncrEnd() {
79  end++;
80  if (end == 0) e_msb ^= 1;
81  }
82 
83 };
CircularBuffer()
Constructor.
-
#define MOZZI_BUFFER_SIZE
Definition: CircularBuffer.h:8
-
Circular buffer object.
+
1 /*
+
2  * CircularBuffer.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2014-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 /*
+
13 Modified from https://en.wikipedia.org/wiki/Circular_buffer
+
14 Mirroring version
+
15 On 18 April 2014, the simplified version on the Wikipedia page for power of 2 sized buffers
+
16 doesn't work - cbIsEmpty() returns true whether the buffer is full or empty.
+
17 */
+
18 
+
19 #define MOZZI_BUFFER_SIZE 256 // do not expect to change and it to work.
+
20  // just here for forward compatibility if one day
+
21  // the buffer size might be editable
+
22 
+
23 /** Circular buffer object. Has a fixed number of cells, set to 256.
+
24 @tparam ITEM_TYPE the kind of data to store, eg. int, int8_t etc.
+
25 */
+
26 template <class ITEM_TYPE>
+ +
28 {
+
29 
+
30 public:
+
31  /** Constructor
+
32  */
+ +
34  {
+
35  }
+
36 
+
37  inline
+
38  bool isFull() {
+
39  return end == start && e_msb != s_msb;
+
40  }
+
41 
+
42  inline
+
43  bool isEmpty() {
+
44  return end == start && e_msb == s_msb;
+
45  }
+
46 
+
47  inline
+
48  void write(ITEM_TYPE in) {
+
49  items[end] = in;
+
50  //if (isFull()) cbIncrStart(); /* full, overwrite moves start pointer */
+
51  cbIncrEnd();
+
52  }
+
53 
+
54  inline
+
55  ITEM_TYPE read() {
+
56  ITEM_TYPE out = items[start];
+
57  cbIncrStart();
+
58  return out;
+
59  }
+
60 
+
61  inline
+
62  unsigned long count() {
+
63  return (num_buffers_read << 8) + start;
+
64  }
+
65  inline
+
66  ITEM_TYPE * address() {
+
67  return items;
+
68  }
+
69 
+
70 private:
+
71  ITEM_TYPE items[MOZZI_BUFFER_SIZE];
+
72  uint8_t start; /* index of oldest itement */
+
73  uint8_t end; /* index at which to write new itement */
+
74  uint8_t s_msb;
+
75  uint8_t e_msb;
+
76  unsigned long num_buffers_read;
+
77 
+
78 
+
79  inline
+
80  void cbIncrStart() {
+
81  start++;
+
82  if (start == 0) {
+
83  s_msb ^= 1;
+
84  num_buffers_read++;
+
85  }
+
86  }
+
87 
+
88  inline
+
89  void cbIncrEnd() {
+
90  end++;
+
91  if (end == 0) e_msb ^= 1;
+
92  }
+
93 
+
94 };
diff --git a/extras/doc/html/_control_delay_8h_source.html b/extras/doc/html/_control_delay_8h_source.html index 9af09598b..e13b3d641 100644 --- a/extras/doc/html/_control_delay_8h_source.html +++ b/extras/doc/html/_control_delay_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: ControlDelay.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,51 @@
ControlDelay.h
-
1 /*
2  * ControlDelay.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef CONTROLDELAY_H_
13 #define CONTROLDELAY_H_
14 
15 #include "AudioDelay.h"
16 
17 /**
18 @brief Control-rate delay line for delaying control signals.
19 For example, this could be used to produce echo-like effects using multiple
20 instances of the same voice, when AudioDelay would be too short for an actual
21 audio echo. This is in fact just a wrapper of the AudioDelay code.
22 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples. This should
23 be a power of two.
24 @tparam the type of numbers to use for the signal in the delay. The default is int8_t, but int could be useful
25 when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
26 */
27 
28 template <unsigned int NUM_BUFFER_SAMPLES, class T = int>
29 class ControlDelay: public AudioDelay<NUM_BUFFER_SAMPLES, T>
30 {
31 };
32 
33 /**
34 @example 02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino
35 This is an example of how to use the ControlDelay class.
36 */
37 
38 #endif // #ifndef CONTROLDELAY_H_
Control-rate delay line for delaying control signals.
Definition: ControlDelay.h:29
-
Audio delay line for comb filter, flange, chorus and short echo effects.
Definition: AudioDelay.h:27
+
1 /*
+
2  * ControlDelay.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 CONTROLDELAY_H_
+
13 #define CONTROLDELAY_H_
+
14 
+
15 #include "AudioDelay.h"
+
16 
+
17 /**
+
18 @brief Control-rate delay line for delaying control signals.
+
19 For example, this could be used to produce echo-like effects using multiple
+
20 instances of the same voice, when AudioDelay would be too short for an actual
+
21 audio echo. This is in fact just a wrapper of the AudioDelay code.
+
22 @tparam NUM_BUFFER_SAMPLES is the length of the delay buffer in samples. This should
+
23 be a power of two.
+
24 @tparam the type of numbers to use for the signal in the delay. The default is int8_t, but int could be useful
+
25 when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
+
26 */
+
27 
+
28 template <unsigned int NUM_BUFFER_SAMPLES, class T = int>
+
29 class ControlDelay: public AudioDelay<NUM_BUFFER_SAMPLES, T>
+
30 {
+
31 };
+
32 
+
33 /**
+
34 @example 02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino
+
35 This is an example of how to use the ControlDelay class.
+
36 */
+
37 
+
38 #endif // #ifndef CONTROLDELAY_H_
diff --git a/extras/doc/html/_d_cfilter_8h_source.html b/extras/doc/html/_d_cfilter_8h_source.html index 1ede27b34..693e57610 100644 --- a/extras/doc/html/_d_cfilter_8h_source.html +++ b/extras/doc/html/_d_cfilter_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: DCfilter.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,18 +99,102 @@
DCfilter.h
-
1 /*
2  * DCfilter.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef DCFILTER_H
13 #define DCFILTER_H
14 
15 /*
16 tb2010 adapted from:
17 robert bristow-johnson, DSP Trick: Fixed-Point DC Blocking Filter with Noise-Shaping
18 http://www.dspguru.com/book/export/html/126
19 
20 y[n] = x[n] - x[n-1] + a * y[n-1]
21 
22 Where y[n] is the output at the current time n, and x[n] is the input at the current time n.
23 
24 also, see DC Blocker Algorithms, http://www.ingelec.uns.edu.ar/pds2803/materiales/articulos/04472252.pdf
25  */
26 
27 /**
28 A DC-blocking filter useful for highlighting changes in control signals.
29 The output of the filter settles to 0 if the incoming signal stays constant. If the input changes, the
30 filter output swings to track the change and eventually settles back to 0.
31 */
32 class DCfilter
33 {
34 public:
35 /**
36 Instantiate a DC-blocking filter.
37 @param pole sets the responsiveness of the filter,
38 how long it takes to settle to 0 if the input signal levels out at a constant value.
39 */
40  DCfilter(float pole):acc(0),prev_x(0),prev_y(0)
41  {
42  A = (int)(32768.0*(1.0 - pole));
43  }
44 
45 /* almost original
46  // timing: 20us
47  int next(int x)
48  {
49  setPin13High();
50  acc -= prev_x;
51  prev_x = (long)x<<15;
52  acc += prev_x;
53  acc -= A*prev_y;
54  prev_y = acc>>15; // quantization happens here
55  int filtered = (int)prev_y;
56  // acc has y[n] in upper 17 bits and -e[n] in lower 15 bits
57  setPin13Low();
58  return filtered;
59  }
60  */
61 
62  /**
63  Filter the incoming value and return the result.
64  @param x the value to filter
65  @return filtered signal
66  */
67  // timing :8us
68  inline
69  int next(int x)
70  {
71  acc += ((long)(x-prev_x)<<16)>>1;
72  prev_x = x;
73  acc -= (long)A*prev_y; // acc has y[n] in upper 17 bits and -e[n] in lower 15 bits
74  prev_y = (acc>>16)<<1; // faster than >>15 but loses bit 0
75  if (acc & 32784) prev_y += 1; // adds 1 if it was in the 0 bit position lost in the shifts above
76  return prev_y;
77  }
78 
79 private:
80  long acc;
81  int prev_x, prev_y,A;
82 };
83 
84 /**
85 @example 05.Control_Filters/DCFilter/DCFilter.ino
86 This example demonstrates the DCFilter class.
87 */
88 
89 #endif // #ifndef DCFILTER_H
DCfilter(float pole)
Instantiate a DC-blocking filter.
Definition: DCfilter.h:40
-
int next(int x)
Filter the incoming value and return the result.
Definition: DCfilter.h:69
-
A DC-blocking filter useful for highlighting changes in control signals.
Definition: DCfilter.h:32
+
1 /*
+
2  * DCfilter.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 DCFILTER_H
+
13 #define DCFILTER_H
+
14 
+
15 /*
+
16 tb2010 adapted from:
+
17 robert bristow-johnson, DSP Trick: Fixed-Point DC Blocking Filter with Noise-Shaping
+
18 http://www.dspguru.com/book/export/html/126
+
19 
+
20 y[n] = x[n] - x[n-1] + a * y[n-1]
+
21 
+
22 Where y[n] is the output at the current time n, and x[n] is the input at the current time n.
+
23 
+
24 also, see DC Blocker Algorithms, http://www.ingelec.uns.edu.ar/pds2803/materiales/articulos/04472252.pdf
+
25  */
+
26 
+
27 /**
+
28 A DC-blocking filter useful for highlighting changes in control signals.
+
29 The output of the filter settles to 0 if the incoming signal stays constant. If the input changes, the
+
30 filter output swings to track the change and eventually settles back to 0.
+
31 */
+
32 class DCfilter
+
33 {
+
34 public:
+
35 /**
+
36 Instantiate a DC-blocking filter.
+
37 @param pole sets the responsiveness of the filter,
+
38 how long it takes to settle to 0 if the input signal levels out at a constant value.
+
39 */
+
40  DCfilter(float pole):acc(0),prev_x(0),prev_y(0)
+
41  {
+
42  A = (int)(32768.0*(1.0 - pole));
+
43  }
+
44 
+
45 /* almost original
+
46  // timing: 20us
+
47  int next(int x)
+
48  {
+
49  setPin13High();
+
50  acc -= prev_x;
+
51  prev_x = (long)x<<15;
+
52  acc += prev_x;
+
53  acc -= A*prev_y;
+
54  prev_y = acc>>15; // quantization happens here
+
55  int filtered = (int)prev_y;
+
56  // acc has y[n] in upper 17 bits and -e[n] in lower 15 bits
+
57  setPin13Low();
+
58  return filtered;
+
59  }
+
60  */
+
61 
+
62  /**
+
63  Filter the incoming value and return the result.
+
64  @param x the value to filter
+
65  @return filtered signal
+
66  */
+
67  // timing :8us
+
68  inline
+
69  int next(int x)
+
70  {
+
71  acc += ((long)(x-prev_x)<<16)>>1;
+
72  prev_x = x;
+
73  acc -= (long)A*prev_y; // acc has y[n] in upper 17 bits and -e[n] in lower 15 bits
+
74  prev_y = (acc>>16)<<1; // faster than >>15 but loses bit 0
+
75  if (acc & 32784) prev_y += 1; // adds 1 if it was in the 0 bit position lost in the shifts above
+
76  return prev_y;
+
77  }
+
78 
+
79 private:
+
80  long acc;
+
81  int prev_x, prev_y,A;
+
82 };
+
83 
+
84 /**
+
85 @example 05.Control_Filters/DCFilter/DCFilter.ino
+
86 This example demonstrates the DCFilter class.
+
87 */
+
88 
+
89 #endif // #ifndef DCFILTER_H
diff --git a/extras/doc/html/_ead_8h_source.html b/extras/doc/html/_ead_8h_source.html index 7927716e6..a56977539 100644 --- a/extras/doc/html/_ead_8h_source.html +++ b/extras/doc/html/_ead_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Ead.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,28 +99,185 @@
Ead.h
-
1 /*
2  * Ead.h
3  *
4  * Adapted from ead~.c puredata external (creb library)
5  * Copyright (c) 2000-2003 by Tom Schouten
6  *
7  * Copyright 2012 Tim Barrass, 2000-2003 Tom Schouten
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 
15 #ifndef EAD_H_
16 #define EAD_H_
17 
18 #include "math.h"
19 #include "mozzi_fixmath.h"
20 
21 
22 /** Exponential attack decay envelope. This produces a natural sounding
23 envelope. It calculates a new value each time next() is called, which can be
24 mapped to other parameters to change the amplitude or timbre of a sound.
25 @note Currently doesn't work at audio rate... may need larger number
26 types for Q8n8attack and Q8n8decay ?
27 */
28 
29 class Ead
30 {
31 
32 public:
33 
34  /** Constructor
35  @param update_rate
36  Usually this will be MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE, unless you
37  design another scheme for updating. One such alternative scheme could take turns
38  for various control changes in a rotating schedule to spread out calculations
39  made in successive updateControl() routines.
40  */
41  Ead(unsigned int update_rate) : UPDATE_RATE(update_rate)
42  {
43  ;
44  }
45 
46  /** Set the attack time in milliseconds.
47  @param attack_ms The time taken for values returned by successive calls of
48  the next() method to change from 0 to 255.
49  */
50  inline
51  void setAttack(unsigned int attack_ms)
52  {
53  Q8n8attack = float_to_Q8n8(millisToOneMinusRealPole(attack_ms));
54  }
55 
56 
57  /** Set the decay time in milliseconds.
58  @param decay_ms The time taken for values returned by successive calls of
59  the next() method to change from 255 to 0.
60  */
61  inline
62  void setDecay(unsigned int decay_ms)
63  {
64  Q8n8decay = float_to_Q8n8(millisToOneMinusRealPole(decay_ms));
65  }
66 
67 
68  /** Set attack and decay times in milliseconds.
69  @param attack_ms The time taken for values returned by successive calls of
70  the next() method to change from 0 to 255.
71  @param decay_ms The time taken for values returned by successive calls of
72  the next() method to change from 255 to 0.
73  */
74  inline
75  void set(unsigned int attack_ms, unsigned int decay_ms)
76  {
77  setAttack(attack_ms);
78  setDecay(decay_ms);
79  }
80 
81 
82  /** Start the envelope from the beginning.
83  This can be used at any time, even if the previous envelope is not finished.
84  */
85  inline
86  void start()
87  {
88  Q8n24state = 0;
89  attack_phase = true;
90  }
91 
92 
93  /** Set attack and decay times in milliseconds, and start the envelope from the beginning.
94  This can be used at any time, even if the previous envelope is not finished.
95  @param attack_ms The time taken for values returned by successive calls of
96  the next() method to change from 0 to 255.
97  @param decay_ms The time taken for values returned by successive calls of
98  the next() method to change from 255 to 0.
99  */
100  inline
101  void start(unsigned int attack_ms, unsigned int decay_ms)
102  {
103  set(attack_ms, decay_ms);
104  //Q8n24state = 0; // don't restart from 0, just go from whatever the current level is, to avoid glitches
105  attack_phase = true;
106  }
107 
108 
109  /** Calculate and return the next envelope value, in the range -128 to 127
110  @note Timing: 5us
111  */
112 
113  inline
115  {
116  if(attack_phase)
117  {
118  // multiply A(a1,b1) * A(a2,b2) = A(a1+a2, b1+b2)
119  Q8n24state += (((Q8n24)(Q8n24_FIX1 - Q8n24state) * Q8n8attack)) >> 8; // Q8n24, shifts all back into n24
120  if (Q8n24state >= Q8n24_FIX1-256)
121  {
122  Q8n24state = Q8n24_FIX1-256;
123  attack_phase = false;
124  }
125  }else{ /* decay phase */
126  Q8n24state -= (Q8n24state * Q8n8decay)>>8;
127  }
128  return Q8n24_to_Q0n8(Q8n24state);
129  }
130 
131 
132 private:
133 
134  Q8n8 Q8n8attack;
135  Q8n8 Q8n8decay;
136  Q8n24 Q8n24state;
137  bool attack_phase;
138  const unsigned int UPDATE_RATE;
139 
140 
141  /* convert milliseconds to 1-p, with p a real pole */
142  inline
143  float millisToOneMinusRealPole(unsigned int milliseconds)
144  {
145  static const float NUMERATOR = 1000.0f * log(0.001f);
146  return -expm1(NUMERATOR / ((float)UPDATE_RATE * milliseconds));
147  }
148 
149 
150  // Compute exp(x) - 1 without loss of precision for small values of x.
151  inline
152  float expm1(float x)
153  {
154  if (fabs(x) < 1e-5)
155  {
156  return x + 0.5*x*x;
157  }
158  else
159  {
160  return exp(x) - 1.0;
161  }
162  }
163 
164 };
165 
166 /**
167 @example 07.Envelopes/Ead_Envelope/Ead_Envelope.ino
168 This is an example of how to use the Ead class.
169 */
170 
171 #endif /* EAD_H_ */
uint16_t Q8n8
unsigned fractional number using 8 integer bits and 8 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:33
-
void start(unsigned int attack_ms, unsigned int decay_ms)
Set attack and decay times in milliseconds, and start the envelope from the beginning.
Definition: Ead.h:101
-
void set(unsigned int attack_ms, unsigned int decay_ms)
Set attack and decay times in milliseconds.
Definition: Ead.h:75
-
Exponential attack decay envelope.
Definition: Ead.h:29
-
Ead(unsigned int update_rate)
Constructor.
Definition: Ead.h:41
-
void start()
Start the envelope from the beginning.
Definition: Ead.h:86
-
Q8n8 float_to_Q8n8(float a)
Convert float to Q8n8 fix.
-
void setAttack(unsigned int attack_ms)
Set the attack time in milliseconds.
Definition: Ead.h:51
-
void setDecay(unsigned int decay_ms)
Set the decay time in milliseconds.
Definition: Ead.h:62
-
uint8_t next()
Calculate and return the next envelope value, in the range -128 to 127.
Definition: Ead.h:114
-
uint32_t Q8n24
signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:42
-
#define Q8n24_FIX1
1 in Q8n24 format
Definition: mozzi_fixmath.h:62
-
Q0n8 Q8n24_to_Q0n8(Q8n24 a)
Convert Q8n24 fixed to Q0n8 uint8_t.
+
1 /*
+
2  * Ead.h
+
3  *
+
4  * Adapted from ead~.c puredata external (creb library)
+
5  *
+
6  * This file is part of Mozzi.
+
7  *
+
8  * Copyright (c) 2000-2003 by Tom Schouten
+
9  * Copyright 2012 Tim Barrass
+
10  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
11  *
+
12  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
13  *
+
14  */
+
15 
+
16 #ifndef EAD_H_
+
17 #define EAD_H_
+
18 
+
19 #include "math.h"
+
20 #include "mozzi_fixmath.h"
+
21 
+
22 
+
23 /** Exponential attack decay envelope. This produces a natural sounding
+
24 envelope. It calculates a new value each time next() is called, which can be
+
25 mapped to other parameters to change the amplitude or timbre of a sound.
+
26 @note Currently doesn't work at audio rate... may need larger number
+
27 types for Q8n8attack and Q8n8decay ?
+
28 */
+
29 
+
30 class Ead
+
31 {
+
32 
+
33 public:
+
34 
+
35  /** Constructor
+
36  @param update_rate
+
37  Usually this will be MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE, unless you
+
38  design another scheme for updating. One such alternative scheme could take turns
+
39  for various control changes in a rotating schedule to spread out calculations
+
40  made in successive updateControl() routines.
+
41  */
+
42  Ead(unsigned int update_rate) : UPDATE_RATE(update_rate)
+
43  {
+
44  ;
+
45  }
+
46 
+
47  /** Set the attack time in milliseconds.
+
48  @param attack_ms The time taken for values returned by successive calls of
+
49  the next() method to change from 0 to 255.
+
50  */
+
51  inline
+
52  void setAttack(unsigned int attack_ms)
+
53  {
+
54  Q8n8attack = float_to_Q8n8(millisToOneMinusRealPole(attack_ms));
+
55  }
+
56 
+
57 
+
58  /** Set the decay time in milliseconds.
+
59  @param decay_ms The time taken for values returned by successive calls of
+
60  the next() method to change from 255 to 0.
+
61  */
+
62  inline
+
63  void setDecay(unsigned int decay_ms)
+
64  {
+
65  Q8n8decay = float_to_Q8n8(millisToOneMinusRealPole(decay_ms));
+
66  }
+
67 
+
68 
+
69  /** Set attack and decay times in milliseconds.
+
70  @param attack_ms The time taken for values returned by successive calls of
+
71  the next() method to change from 0 to 255.
+
72  @param decay_ms The time taken for values returned by successive calls of
+
73  the next() method to change from 255 to 0.
+
74  */
+
75  inline
+
76  void set(unsigned int attack_ms, unsigned int decay_ms)
+
77  {
+
78  setAttack(attack_ms);
+
79  setDecay(decay_ms);
+
80  }
+
81 
+
82 
+
83  /** Start the envelope from the beginning.
+
84  This can be used at any time, even if the previous envelope is not finished.
+
85  */
+
86  inline
+
87  void start()
+
88  {
+
89  Q8n24state = 0;
+
90  attack_phase = true;
+
91  }
+
92 
+
93 
+
94  /** Set attack and decay times in milliseconds, and start the envelope from the beginning.
+
95  This can be used at any time, even if the previous envelope is not finished.
+
96  @param attack_ms The time taken for values returned by successive calls of
+
97  the next() method to change from 0 to 255.
+
98  @param decay_ms The time taken for values returned by successive calls of
+
99  the next() method to change from 255 to 0.
+
100  */
+
101  inline
+
102  void start(unsigned int attack_ms, unsigned int decay_ms)
+
103  {
+
104  set(attack_ms, decay_ms);
+
105  //Q8n24state = 0; // don't restart from 0, just go from whatever the current level is, to avoid glitches
+
106  attack_phase = true;
+
107  }
+
108 
+
109 
+
110  /** Calculate and return the next envelope value, in the range -128 to 127
+
111  @note Timing: 5us
+
112  */
+
113 
+
114  inline
+ +
116  {
+
117  if(attack_phase)
+
118  {
+
119  // multiply A(a1,b1) * A(a2,b2) = A(a1+a2, b1+b2)
+
120  Q8n24state += (((Q8n24)(Q8n24_FIX1 - Q8n24state) * Q8n8attack)) >> 8; // Q8n24, shifts all back into n24
+
121  if (Q8n24state >= Q8n24_FIX1-256)
+
122  {
+
123  Q8n24state = Q8n24_FIX1-256;
+
124  attack_phase = false;
+
125  }
+
126  }else{ /* decay phase */
+
127  Q8n24state -= (Q8n24state * Q8n8decay)>>8;
+
128  }
+
129  return Q8n24_to_Q0n8(Q8n24state);
+
130  }
+
131 
+
132 
+
133 private:
+
134 
+
135  Q8n8 Q8n8attack;
+
136  Q8n8 Q8n8decay;
+
137  Q8n24 Q8n24state;
+
138  bool attack_phase;
+
139  const unsigned int UPDATE_RATE;
+
140 
+
141 
+
142  /* convert milliseconds to 1-p, with p a real pole */
+
143  inline
+
144  float millisToOneMinusRealPole(unsigned int milliseconds)
+
145  {
+
146  static const float NUMERATOR = 1000.0f * log(0.001f);
+
147  return -expm1(NUMERATOR / ((float)UPDATE_RATE * milliseconds));
+
148  }
+
149 
+
150 
+
151  // Compute exp(x) - 1 without loss of precision for small values of x.
+
152  inline
+
153  float expm1(float x)
+
154  {
+
155  if (fabs(x) < 1e-5)
+
156  {
+
157  return x + 0.5*x*x;
+
158  }
+
159  else
+
160  {
+
161  return exp(x) - 1.0;
+
162  }
+
163  }
+
164 
+
165 };
+
166 
+
167 /**
+
168 @example 07.Envelopes/Ead_Envelope/Ead_Envelope.ino
+
169 This is an example of how to use the Ead class.
+
170 */
+
171 
+
172 #endif /* EAD_H_ */
diff --git a/extras/doc/html/_event_delay_8h_source.html b/extras/doc/html/_event_delay_8h_source.html index 22036d085..9f886d2d5 100644 --- a/extras/doc/html/_event_delay_8h_source.html +++ b/extras/doc/html/_event_delay_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: EventDelay.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,21 +99,106 @@
EventDelay.h
-
1 /*
2  * EventDelay.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef EVENTDELAY_H_
13 #define EVENTDELAY_H_
14 
15 
16 /** A non-blocking replacement for Arduino's delay() function.
17 EventDelay can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
18 Alternatively, start(milliseconds) will call set() and start() together.
19 */
21 {
22 
23 public:
24 
25  /** Constructor.
26  Declare an EventDelay object.
27  @param delay_milliseconds how long until ready() returns true, after calling start(). Defaults to 0 if no parameter is supplied.
28  */
29  EventDelay(unsigned int delay_milliseconds = 0): AUDIO_TICKS_PER_MILLISECOND((float)MOZZI_AUDIO_RATE/1000.0f)
30  {
31  set(delay_milliseconds);
32  }
33 
34 
35  /** Set the delay time. This setting is persistent, until you change it by using set() again.
36  @param delay_milliseconds delay time in milliseconds.
37  @note timing: 12us
38  */
39  inline
40  void set(unsigned int delay_milliseconds)
41  {
42  ticks = (unsigned long)(AUDIO_TICKS_PER_MILLISECOND*delay_milliseconds); // 12us
43  }
44 
45 
46  /** Start the delay.
47  @todo have a parameter to set whether it's single or repeating, so start doesn't have to be called for repeats.
48  Pro: simpler user programming. Con: would require an if..then every time ready() is called.
49  */
50  inline
51  void start()
52  {
53  deadline=audioTicks()+ticks;
54  }
55 
56 
57  /** Set the delay time and start the delay.
58  @param delay_milliseconds delay time in milliseconds.
59  */
60  inline
61  void start(unsigned int delay_milliseconds)
62  {
63  set(delay_milliseconds);
64  start();
65  }
66 
67 
68  /** Call this in updateControl() or updateAudio() to check if the delay time is up.
69  @return true if the time is up.
70  @note timing: 1us.
71  */
72  inline
73  bool ready()
74  {
75  return(audioTicks()>=deadline); // 1us
76  }
77 
78 
79 protected:
80  // Metronome accesses these
81  unsigned long deadline;
82  unsigned long ticks;
83 
84 private:
85  const float AUDIO_TICKS_PER_MILLISECOND;
86 };
87 
88 /**
89 @example 02.Control/EventDelay/EventDelay.ino
90 This example shows how to use the EventDelay class.
91 */
92 
93 #endif /* EVENTDELAY_H_ */
void start(unsigned int delay_milliseconds)
Set the delay time and start the delay.
Definition: EventDelay.h:61
-
EventDelay(unsigned int delay_milliseconds=0)
Constructor.
Definition: EventDelay.h:29
-
void start()
Start the delay.
Definition: EventDelay.h:51
-
A non-blocking replacement for Arduino&#39;s delay() function.
Definition: EventDelay.h:20
-
bool ready()
Call this in updateControl() or updateAudio() to check if the delay time is up.
Definition: EventDelay.h:73
-
void set(unsigned int delay_milliseconds)
Set the delay time.
Definition: EventDelay.h:40
+
1 /*
+
2  * EventDelay.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 EVENTDELAY_H_
+
13 #define EVENTDELAY_H_
+
14 
+
15 
+
16 /** A non-blocking replacement for Arduino's delay() function.
+
17 EventDelay can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
+
18 Alternatively, start(milliseconds) will call set() and start() together.
+
19 */
+ +
21 {
+
22 
+
23 public:
+
24 
+
25  /** Constructor.
+
26  Declare an EventDelay object.
+
27  @param delay_milliseconds how long until ready() returns true, after calling start(). Defaults to 0 if no parameter is supplied.
+
28  */
+
29  EventDelay(unsigned int delay_milliseconds = 0): AUDIO_TICKS_PER_MILLISECOND((float)MOZZI_AUDIO_RATE/1000.0f)
+
30  {
+
31  set(delay_milliseconds);
+
32  }
+
33 
+
34 
+
35  /** Set the delay time. This setting is persistent, until you change it by using set() again.
+
36  @param delay_milliseconds delay time in milliseconds.
+
37  @note timing: 12us
+
38  */
+
39  inline
+
40  void set(unsigned int delay_milliseconds)
+
41  {
+
42  ticks = (unsigned long)(AUDIO_TICKS_PER_MILLISECOND*delay_milliseconds); // 12us
+
43  }
+
44 
+
45 
+
46  /** Start the delay.
+
47  @todo have a parameter to set whether it's single or repeating, so start doesn't have to be called for repeats.
+
48  Pro: simpler user programming. Con: would require an if..then every time ready() is called.
+
49  */
+
50  inline
+
51  void start()
+
52  {
+
53  deadline=audioTicks()+ticks;
+
54  }
+
55 
+
56 
+
57  /** Set the delay time and start the delay.
+
58  @param delay_milliseconds delay time in milliseconds.
+
59  */
+
60  inline
+
61  void start(unsigned int delay_milliseconds)
+
62  {
+
63  set(delay_milliseconds);
+
64  start();
+
65  }
+
66 
+
67 
+
68  /** Call this in updateControl() or updateAudio() to check if the delay time is up.
+
69  @return true if the time is up.
+
70  @note timing: 1us.
+
71  */
+
72  inline
+
73  bool ready()
+
74  {
+
75  return(audioTicks()>=deadline); // 1us
+
76  }
+
77 
+
78 
+
79 protected:
+
80  // Metronome accesses these
+
81  unsigned long deadline;
+
82  unsigned long ticks;
+
83 
+
84 private:
+
85  const float AUDIO_TICKS_PER_MILLISECOND;
+
86 };
+
87 
+
88 /**
+
89 @example 02.Control/EventDelay/EventDelay.ino
+
90 This example shows how to use the EventDelay class.
+
91 */
+
92 
+
93 #endif /* EVENTDELAY_H_ */
diff --git a/extras/doc/html/_int_map_8h_source.html b/extras/doc/html/_int_map_8h_source.html index 1831c8da5..cdb95dbed 100644 --- a/extras/doc/html/_int_map_8h_source.html +++ b/extras/doc/html/_int_map_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: IntMap.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,18 +99,62 @@
IntMap.h
-
1 /*
2  * IntMap.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef INTMAP_H_
13 #define INTMAP_H_
14 
15 /** A faster version of Arduino's map() function.
16 This uses ints instead of longs internally and does some of the maths at compile time.
17 */
18 class IntMap {
19 
20 public:
21  /** Constructor.
22  @param in_min the minimum of the input range.
23  @param in_max the maximum of the input range.
24  @param out_min the minimum of the output range.
25  @param out_max the maximum of the output range.
26  */
27  IntMap(int in_min, int in_max, int out_min, int out_max)
28  : _IN_MIN(in_min),_IN_MAX(in_max),_OUT_MIN(out_min),_OUT_MAX(out_max),
29  _MULTIPLIER((256L * (out_max-out_min)) / (in_max-in_min))
30  {
31  ;
32  }
33 
34  /** Process the next input value.
35  @param n the next integer to process.
36  @return the input integer mapped to the output range.
37  */
38  int operator()(int n) const {
39  return (int) (((_MULTIPLIER*(n-_IN_MIN))>>8) + _OUT_MIN);
40  }
41 
42 
43 private:
44  const int _IN_MIN, _IN_MAX, _OUT_MIN, _OUT_MAX;
45  const long _MULTIPLIER;
46 };
47 
48 #endif /* INTMAP_H_ */
A faster version of Arduino&#39;s map() function.
Definition: IntMap.h:18
-
int operator()(int n) const
Process the next input value.
Definition: IntMap.h:38
-
IntMap(int in_min, int in_max, int out_min, int out_max)
Constructor.
Definition: IntMap.h:27
+
1 /*
+
2  * IntMap.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 
+
13 #ifndef INTMAP_H_
+
14 #define INTMAP_H_
+
15 
+
16 /** A faster version of Arduino's map() function.
+
17 This uses ints instead of longs internally and does some of the maths at compile time.
+
18 */
+
19 class IntMap {
+
20 
+
21 public:
+
22  /** Constructor.
+
23  @param in_min the minimum of the input range.
+
24  @param in_max the maximum of the input range.
+
25  @param out_min the minimum of the output range.
+
26  @param out_max the maximum of the output range.
+
27  */
+
28  IntMap(int in_min, int in_max, int out_min, int out_max)
+
29  : _IN_MIN(in_min),_IN_MAX(in_max),_OUT_MIN(out_min),_OUT_MAX(out_max),
+
30  _MULTIPLIER((256L * (out_max-out_min)) / (in_max-in_min))
+
31  {
+
32  ;
+
33  }
+
34 
+
35  /** Process the next input value.
+
36  @param n the next integer to process.
+
37  @return the input integer mapped to the output range.
+
38  */
+
39  int operator()(int n) const {
+
40  return (int) (((_MULTIPLIER*(n-_IN_MIN))>>8) + _OUT_MIN);
+
41  }
+
42 
+
43 
+
44 private:
+
45  const int _IN_MIN, _IN_MAX, _OUT_MIN, _OUT_MAX;
+
46  const long _MULTIPLIER;
+
47 };
+
48 
+
49 #endif /* INTMAP_H_ */
diff --git a/extras/doc/html/_integer_type_8h_source.html b/extras/doc/html/_integer_type_8h_source.html index 6c6a75ae7..2744ed9b4 100644 --- a/extras/doc/html/_integer_type_8h_source.html +++ b/extras/doc/html/_integer_type_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: IntegerType.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,60 @@
IntegerType.h
-
1 #ifndef INTTYPE_H_
2 #define INTTYPE_H_
3 
4 #include <Arduino.h>
5 
6 /** @ingroup util
7 Provides appropriate integer types that can bit the given number of bytes on this platform (at most 64).
8 */
9 template<uint8_t BYTES> struct IntegerType {
10  // at an odd value, such as 3 bytes? Add one more byte (up to at most 8 bytes)..
11  typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::unsigned_type unsigned_type;
12  typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::signed_type signed_type;
13 };
14 
15 // These are the specializations for the types that we actually assume to exist:
16 template<> struct IntegerType<1> {
17  typedef uint8_t unsigned_type;
18  typedef int8_t signed_type;
19 };
20 
21 template<> struct IntegerType<2> {
22  typedef uint16_t unsigned_type;
23  typedef int16_t signed_type;
24 };
25 
26 template<> struct IntegerType<4> {
27  typedef uint32_t unsigned_type;
28  typedef int32_t signed_type;
29 };
30 
31 template<> struct IntegerType<8> {
32  typedef uint64_t unsigned_type;
33  typedef int64_t signed_type;
34 };
35 
36 #endif /* INTTYPE_H_ */
Provides appropriate integer types that can bit the given number of bytes on this platform (at most 6...
Definition: IntegerType.h:9
+
1 /*
+
2  * IntegerType.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2021-2024 Thomas Friedrichsmeier 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 INTTYPE_H_
+
13 #define INTTYPE_H_
+
14 
+
15 #include <Arduino.h>
+
16 
+
17 /** @ingroup util
+
18 Provides appropriate integer types that can bit the given number of bytes on this platform (at most 64).
+
19 */
+
20 template<uint8_t BYTES> struct IntegerType {
+
21  // at an odd value, such as 3 bytes? Add one more byte (up to at most 8 bytes)..
+
22  typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::unsigned_type unsigned_type;
+
23  typedef typename IntegerType<(BYTES < 8) ? (BYTES+1) : 8>::signed_type signed_type;
+
24 };
+
25 
+
26 // These are the specializations for the types that we actually assume to exist:
+
27 template<> struct IntegerType<1> {
+
28  typedef uint8_t unsigned_type;
+
29  typedef int8_t signed_type;
+
30 };
+
31 
+
32 template<> struct IntegerType<2> {
+
33  typedef uint16_t unsigned_type;
+
34  typedef int16_t signed_type;
+
35 };
+
36 
+
37 template<> struct IntegerType<4> {
+
38  typedef uint32_t unsigned_type;
+
39  typedef int32_t signed_type;
+
40 };
+
41 
+
42 template<> struct IntegerType<8> {
+
43  typedef uint64_t unsigned_type;
+
44  typedef int64_t signed_type;
+
45 };
+
46 
+
47 #endif /* INTTYPE_H_ */
diff --git a/extras/doc/html/_line_8h_source.html b/extras/doc/html/_line_8h_source.html index f960981ab..df387e9b2 100644 --- a/extras/doc/html/_line_8h_source.html +++ b/extras/doc/html/_line_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Line.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,36 +99,506 @@
Line.h
-
1 /*
2  * Line.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef LINE_H_
13 #define LINE_H_
14 
15 #include <Arduino.h>
16 
17 /** For linear changes with a minimum of calculation at each step. For instance,
18 you can use Line to make an oscillator glide from one frequency to another,
19 pre-calculating the required phase increments for each end and then letting your
20 Line change the phase increment with only a simple addition at each step.
21 @tparam T the type of numbers to use. For example, Line <int> myline; makes a
22 Line which uses ints.
23 @note Watch out for underflows in the internal calcualtion of Line() if you're not
24 using floats (but on the other hand try to avoid lots of floats, they're too slow!).
25 If it seems like the Line() is not working, there's a good chance you need to
26 scale up the numbers you're using, so internal calculations don't get truncated
27 away. Use Mozzi's fixed-point number types in mozzi_fixmath.h, which enable you to
28 represent fractional numbers. Google "fixed point arithmetic" if this is new to
29 you.
30 */
31 
32 template <class T>
33 class Line
34 {
35 private:
36  volatile T current_value; // volatile because it could be set in control interrupt and updated in audio
37  volatile T step_size;
38 
39 public:
40  /** Constructor. Use the template parameter to set the type of numbers you
41  want to use. For example, Line <int> myline; makes a Line which uses ints.
42  */
43  Line ()
44  {
45  ;
46  }
47 
48 
49 
50  /** Increments one step along the line.
51  @return the next value.
52  */
53  inline
54  T next()
55  {
56  current_value += step_size;
57  //Serial.println(current_value);
58  return current_value;
59  }
60 
61 
62 
63  /** Set the current value of the line.
64  The Line will continue incrementing from this
65  value using any previously calculated step size.
66  @param value the number to set the Line's current_value to.
67  */
68  inline
69  void set(T value)
70  {
71  current_value=value;
72  }
73 
74 
75 
76  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
77  @param targetvalue the value to move towards.
78  @param num_steps how many steps to take to reach the target.
79  */
80  inline
81  void set(T targetvalue, T num_steps)
82  {
83  if(num_steps) {
84  T numerator = targetvalue-current_value;
85  step_size= numerator/num_steps;
86  } else {
87  step_size = 0;
88  current_value = targetvalue;
89  }
90  }
91 
92  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
93  @param startvalue the number to set the Line's current_value to.
94  @param targetvalue the value to move towards.
95  @param num_steps how many steps to take to reach the target.
96  */
97  inline
98  void set(T startvalue, T targetvalue, T num_steps)
99  {
100  set(startvalue);
101  set(targetvalue, num_steps);
102  }
103 };
104 
105 
106 /* unsigned char specialisation (probably not very useful because step size will likely = 0) */
107 template <>
108 class Line <unsigned char>
109 {
110 private:
111  volatile unsigned char current_value; // volatile because it could be set in control interrupt and updated in audio
112  char step_size;
113 
114 public:
115  /** Constructor. Use the template parameter to set the type of numbers you
116  want to use. For example, Line <int> myline; makes a Line which uses ints.
117  */
118  Line ()
119  {
120  ;
121  }
122 
123 
124 
125  /** Increments one step along the line.
126  @return the next value.
127  */
128  inline
129  unsigned char next()
130  {
131  current_value += step_size;
132  return current_value;
133  }
134 
135 
136 
137  /** Set the current value of the line.
138  The Line will continue incrementing from this
139  value using any previously calculated step size.
140  @param value the number to set the Line's current_value to.
141  */
142  inline
143  void set(unsigned char value)
144  {
145  current_value=value;
146  }
147 
148 
149 
150  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
151  @param targetvalue the value to move towards.
152  @param num_steps how many steps to take to reach the target.
153  */
154  inline
155  void set(unsigned char targetvalue, unsigned char num_steps)
156  {
157  step_size=(char)((((float)targetvalue-current_value)/num_steps));
158  }
159 
160  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
161  @param startvalue the number to set the Line's current_value to.
162  @param targetvalue the value to move towards.
163  @param num_steps how many steps to take to reach the target.
164  */
165  inline
166  void set(unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)
167  {
168  set(startvalue);
169  set(targetvalue, num_steps);
170  }
171 
172 };
173 
174 
175 /* unsigned int specialisation */
176 template <>
177 class Line <unsigned int>
178 {
179 private:
180  volatile unsigned int current_value; // volatile because it could be set in control interrupt and updated in audio
181  int step_size;
182 
183 public:
184  /** Constructor. Use the template parameter to set the type of numbers you
185  want to use. For example, Line <int> myline; makes a Line which uses ints.
186  */
187  Line ()
188  {
189  ;
190  }
191 
192 
193 
194  /** Increments one step along the line.
195  @return the next value.
196  */
197  inline
198  unsigned int next()
199  {
200  current_value += step_size;
201  return current_value;
202  }
203 
204 
205 
206  /** Set the current value of the line.
207  The Line will continue incrementing from this
208  value using any previously calculated step size.
209  @param value the number to set the Line's current_value to.
210  */
211  inline
212  void set(unsigned int value)
213  {
214  current_value=value;
215  }
216 
217 
218 
219  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
220  @param targetvalue the value to move towards.
221  @param num_steps how many steps to take to reach the target.
222  */
223  inline
224  void set(unsigned int targetvalue, unsigned int num_steps)
225  {
226  step_size=(int)((((float)targetvalue-current_value)/num_steps));
227  }
228 
229 
230  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
231  @param startvalue the number to set the Line's current_value to.
232  @param targetvalue the value to move towards.
233  @param num_steps how many steps to take to reach the target.
234  */
235  inline
236  void set(unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)
237  {
238  set(startvalue);
239  set(targetvalue, num_steps);
240  }
241 };
242 
243 
244 
245 
246 
247 /* unsigned long specialisation */
248 template <>
249 class Line <unsigned long>
250 {
251 private:
252  volatile unsigned long current_value; // volatile because it could be set in control interrupt and updated in audio
253  long step_size;
254 
255 public:
256  /** Constructor. Use the template parameter to set the type of numbers you
257  want to use. For example, Line <int> myline; makes a Line which uses ints.
258  */
259  Line ()
260  {
261  ;
262  }
263 
264 
265 
266  /** Increments one step along the line.
267  @return the next value.
268  */
269  inline
270  unsigned long next()
271  {
272  current_value += step_size;
273  return current_value;
274  }
275 
276 
277 
278  /** Set the current value of the line.
279  The Line will continue incrementing from this
280  value using any previously calculated step size.
281  @param value the number to set the Line's current_value to.
282  */
283  inline
284  void set(unsigned long value)
285  {
286  current_value=value;
287  }
288 
289 
290 
291  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
292  @param targetvalue the value to move towards.
293  @param num_steps how many steps to take to reach the target.
294  */
295  inline
296  void set(unsigned long targetvalue, unsigned long num_steps)
297  {
298  step_size=(long)((((float)targetvalue-current_value)/num_steps));
299  }
300 
301  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
302  @param startvalue the number to set the Line's current_value to.
303  @param targetvalue the value to move towards.
304  @param num_steps how many steps to take to reach the target.
305  */
306  inline
307  void set(unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)
308  {
309  set(startvalue);
310  set(targetvalue, num_steps);
311  }
312 };
313 
314 /**
315 @example 02.Control/Control_Tremelo/Control_Tremelo.ino
316 This example demonstrates the Line class.
317 */
318 
319 #endif /* LINE_H_ */
void set(T value)
Set the current value of the line.
Definition: Line.h:69
-
Line()
Constructor.
Definition: Line.h:187
-
void set(unsigned int targetvalue, unsigned int num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:224
-
void set(unsigned long value)
Set the current value of the line.
Definition: Line.h:284
-
void set(unsigned long targetvalue, unsigned long num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:296
-
unsigned char next()
Increments one step along the line.
Definition: Line.h:129
-
void set(unsigned int value)
Set the current value of the line.
Definition: Line.h:212
-
void set(unsigned char value)
Set the current value of the line.
Definition: Line.h:143
-
void set(T startvalue, T targetvalue, T num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:98
-
Line()
Constructor.
Definition: Line.h:43
-
For linear changes with a minimum of calculation at each step.
Definition: Line.h:33
-
Line()
Constructor.
Definition: Line.h:118
-
void set(unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:166
-
void set(T targetvalue, T num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:81
-
Line()
Constructor.
Definition: Line.h:259
-
void set(unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:307
-
void set(unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)
Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
Definition: Line.h:236
-
unsigned long next()
Increments one step along the line.
Definition: Line.h:270
-
unsigned int next()
Increments one step along the line.
Definition: Line.h:198
-
void set(unsigned char targetvalue, unsigned char num_steps)
Given a target value and the number of steps to take on the way, this calculates the step size needed...
Definition: Line.h:155
-
T next()
Increments one step along the line.
Definition: Line.h:54
+
1 /*
+
2  * Line.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 
+
13 #ifndef LINE_H_
+
14 #define LINE_H_
+
15 
+
16 #include <Arduino.h>
+
17 
+
18 #include<FixMath.h>
+
19 
+
20 /** For linear changes with a minimum of calculation at each step. For instance,
+
21 you can use Line to make an oscillator glide from one frequency to another,
+
22 pre-calculating the required phase increments for each end and then letting your
+
23 Line change the phase increment with only a simple addition at each step.
+
24 @tparam T the type of numbers to use. For example, Line <int> myline; makes a
+
25 Line which uses ints.
+
26 @note Watch out for underflows in the internal calcualtion of Line() if you're not
+
27 using floats (but on the other hand try to avoid lots of floats, they're too slow!).
+
28 If it seems like the Line() is not working, there's a good chance you need to
+
29 scale up the numbers you're using, so internal calculations don't get truncated
+
30 away. Use Mozzi's fixed-point number types in mozzi_fixmath.h, which enable you to
+
31 represent fractional numbers. Google "fixed point arithmetic" if this is new to
+
32 you.
+
33 */
+
34 
+
35 
+
36 
+
37 
+
38 template <class T>
+
39 class Line
+
40 {
+
41 private:
+
42  T current_value;
+
43  T step_size;
+
44 
+
45 public:
+
46  /** Constructor. Use the template parameter to set the type of numbers you
+
47  want to use. For example, Line <int> myline; makes a Line which uses ints.
+
48  */
+
49  Line ()
+
50  {
+
51  ;
+
52  }
+
53 
+
54 
+
55 
+
56  /** Increments one step along the line.
+
57  @return the next value.
+
58  */
+
59  inline
+
60  T next()
+
61  {
+
62  current_value += step_size;
+
63  //Serial.println(current_value);
+
64  return current_value;
+
65  }
+
66 
+
67 
+
68 
+
69  /** Set the current value of the line.
+
70  The Line will continue incrementing from this
+
71  value using any previously calculated step size.
+
72  @param value the number to set the Line's current_value to.
+
73  */
+
74  inline
+
75  void set(T value)
+
76  {
+
77  current_value=value;
+
78  }
+
79 
+
80 
+
81 
+
82  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
+
83  @param targetvalue the value to move towards.
+
84  @param num_steps how many steps to take to reach the target.
+
85  */
+
86  inline
+
87  void set(T targetvalue, T num_steps)
+
88  {
+
89  if(num_steps) {
+
90  T numerator = targetvalue-current_value;
+
91  step_size= numerator/num_steps;
+
92  } else {
+
93  step_size = 0;
+
94  current_value = targetvalue;
+
95  }
+
96  }
+
97 
+
98  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
+
99  @param startvalue the number to set the Line's current_value to.
+
100  @param targetvalue the value to move towards.
+
101  @param num_steps how many steps to take to reach the target.
+
102  */
+
103  inline
+
104  void set(T startvalue, T targetvalue, T num_steps)
+
105  {
+
106  set(startvalue);
+
107  set(targetvalue, num_steps);
+
108  }
+
109 };
+
110 
+
111 
+
112 /* unsigned char specialisation (probably not very useful because step size will likely = 0) */
+
113 template <>
+
114 class Line <unsigned char>
+
115 {
+
116 private:
+
117  unsigned char current_value;
+
118  char step_size;
+
119 
+
120 public:
+
121  /** Constructor. Use the template parameter to set the type of numbers you
+
122  want to use. For example, Line <int> myline; makes a Line which uses ints.
+
123  */
+
124  Line ()
+
125  {
+
126  ;
+
127  }
+
128 
+
129 
+
130 
+
131  /** Increments one step along the line.
+
132  @return the next value.
+
133  */
+
134  inline
+
135  unsigned char next()
+
136  {
+
137  current_value += step_size;
+
138  return current_value;
+
139  }
+
140 
+
141 
+
142 
+
143  /** Set the current value of the line.
+
144  The Line will continue incrementing from this
+
145  value using any previously calculated step size.
+
146  @param value the number to set the Line's current_value to.
+
147  */
+
148  inline
+
149  void set(unsigned char value)
+
150  {
+
151  current_value=value;
+
152  }
+
153 
+
154 
+
155 
+
156  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
+
157  @param targetvalue the value to move towards.
+
158  @param num_steps how many steps to take to reach the target.
+
159  */
+
160  inline
+
161  void set(unsigned char targetvalue, unsigned char num_steps)
+
162  {
+
163  step_size=(char)((((float)targetvalue-current_value)/num_steps));
+
164  }
+
165 
+
166  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
+
167  @param startvalue the number to set the Line's current_value to.
+
168  @param targetvalue the value to move towards.
+
169  @param num_steps how many steps to take to reach the target.
+
170  */
+
171  inline
+
172  void set(unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)
+
173  {
+
174  set(startvalue);
+
175  set(targetvalue, num_steps);
+
176  }
+
177 
+
178 };
+
179 
+
180 
+
181 /* unsigned int specialisation */
+
182 template <>
+
183 class Line <unsigned int>
+
184 {
+
185 private:
+
186  unsigned int current_value;
+
187  int step_size;
+
188 
+
189 public:
+
190  /** Constructor. Use the template parameter to set the type of numbers you
+
191  want to use. For example, Line <int> myline; makes a Line which uses ints.
+
192  */
+
193  Line ()
+
194  {
+
195  ;
+
196  }
+
197 
+
198 
+
199 
+
200  /** Increments one step along the line.
+
201  @return the next value.
+
202  */
+
203  inline
+
204  unsigned int next()
+
205  {
+
206  current_value += step_size;
+
207  return current_value;
+
208  }
+
209 
+
210 
+
211 
+
212  /** Set the current value of the line.
+
213  The Line will continue incrementing from this
+
214  value using any previously calculated step size.
+
215  @param value the number to set the Line's current_value to.
+
216  */
+
217  inline
+
218  void set(unsigned int value)
+
219  {
+
220  current_value=value;
+
221  }
+
222 
+
223 
+
224 
+
225  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
+
226  @param targetvalue the value to move towards.
+
227  @param num_steps how many steps to take to reach the target.
+
228  */
+
229  inline
+
230  void set(unsigned int targetvalue, unsigned int num_steps)
+
231  {
+
232  step_size=(int)((((float)targetvalue-current_value)/num_steps));
+
233  }
+
234 
+
235 
+
236  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
+
237  @param startvalue the number to set the Line's current_value to.
+
238  @param targetvalue the value to move towards.
+
239  @param num_steps how many steps to take to reach the target.
+
240  */
+
241  inline
+
242  void set(unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)
+
243  {
+
244  set(startvalue);
+
245  set(targetvalue, num_steps);
+
246  }
+
247 };
+
248 
+
249 
+
250 
+
251 
+
252 
+
253 /* unsigned long specialisation */
+
254 template <>
+
255 class Line <unsigned long>
+
256 {
+
257 private:
+
258  unsigned long current_value;
+
259  long step_size;
+
260 
+
261 public:
+
262  /** Constructor. Use the template parameter to set the type of numbers you
+
263  want to use. For example, Line <int> myline; makes a Line which uses ints.
+
264  */
+
265  Line ()
+
266  {
+
267  ;
+
268  }
+
269 
+
270 
+
271 
+
272  /** Increments one step along the line.
+
273  @return the next value.
+
274  */
+
275  inline
+
276  unsigned long next()
+
277  {
+
278  current_value += step_size;
+
279  return current_value;
+
280  }
+
281 
+
282 
+
283 
+
284  /** Set the current value of the line.
+
285  The Line will continue incrementing from this
+
286  value using any previously calculated step size.
+
287  @param value the number to set the Line's current_value to.
+
288  */
+
289  inline
+
290  void set(unsigned long value)
+
291  {
+
292  current_value=value;
+
293  }
+
294 
+
295 
+
296 
+
297  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
+
298  @param targetvalue the value to move towards.
+
299  @param num_steps how many steps to take to reach the target.
+
300  */
+
301  inline
+
302  void set(unsigned long targetvalue, unsigned long num_steps)
+
303  {
+
304  step_size=(long)((((float)targetvalue-current_value)/num_steps));
+
305  }
+
306 
+
307  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
+
308  @param startvalue the number to set the Line's current_value to.
+
309  @param targetvalue the value to move towards.
+
310  @param num_steps how many steps to take to reach the target.
+
311  */
+
312  inline
+
313  void set(unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)
+
314  {
+
315  set(startvalue);
+
316  set(targetvalue, num_steps);
+
317  }
+
318 };
+
319 
+
320 
+
321 /* UFix specialisation */
+
322 template<int8_t NI, int8_t NF>
+
323 class Line<UFix<NI, NF>>
+
324 {
+
325 private:
+
326  typedef UFix<NI, NF> internal_type;
+
327  internal_type current_value;
+
328  SFix<NI,NF> step_size;
+
329 
+
330 public:
+
331  /** Constructor. Use the template parameter to set the type of numbers you
+
332  want to use. For example, Line <int> myline; makes a Line which uses ints.
+
333  */
+
334  Line (){;}
+
335 
+
336  /** Increments one step along the line.
+
337  @return the next value.
+
338  */
+
339  inline
+
340  internal_type next()
+
341  {
+
342  current_value = current_value + step_size;
+
343  return current_value;
+
344  }
+
345 
+
346  /** Set the current value of the line.
+
347  The Line will continue incrementing from this
+
348  value using any previously calculated step size.
+
349  @param value the number to set the Line's current_value to.
+
350  */
+
351  inline
+
352  void set(internal_type value)
+
353  {
+
354  current_value=value;
+
355  }
+
356 
+
357  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
+
358  @param targetvalue the value to move towards.
+
359  @param num_steps how many steps to take to reach the target as a UFix<_NI,0>
+
360  */
+
361  template<int8_t _NI>
+
362  void set(internal_type targetvalue, UFix<_NI,0> num_steps)
+
363  {
+
364  if(num_steps.asRaw()) {
+
365  auto numerator = targetvalue-current_value;
+
366  step_size = numerator*num_steps.invAccurate();
+
367  } else {
+
368  step_size = 0;
+
369  current_value = targetvalue;
+
370  }
+
371  }
+
372 
+
373 
+
374  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
+
375  @param targetvalue the value to move towards.
+
376  @param num_steps how many steps to take to reach the target.
+
377  */
+
378  template<typename T>
+
379  void set(internal_type targetvalue, T num_steps)
+
380  {
+
381  if(num_steps) {
+
382  auto numerator = targetvalue-current_value;
+
383  step_size = internal_type(numerator.asRaw()/num_steps,true);
+
384  } else {
+
385  step_size = 0;
+
386  current_value = targetvalue;
+
387  }
+
388  }
+
389 
+
390  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
+
391  @param startvalue the number to set the Line's current_value to.
+
392  @param targetvalue the value to move towards.
+
393  @param num_steps how many steps to take to reach the target.
+
394  */
+
395  template<typename T>
+
396  void set(internal_type startvalue, internal_type targetvalue, T num_steps)
+
397  {
+
398  set(startvalue);
+
399  set(targetvalue, num_steps);
+
400  }
+
401 };
+
402 
+
403 
+
404 /* SFix specialisation (if someone has an idea to avoid duplication with UFix) */
+
405 template<int8_t NI, int8_t NF>
+
406 class Line<SFix<NI, NF>>
+
407 {
+
408 private:
+
409  typedef SFix<NI, NF> internal_type;
+
410  internal_type current_value;
+
411  SFix<NI+1, NF> step_size;
+
412 
+
413 public:
+
414  /** Constructor. Use the template parameter to set the type of numbers you
+
415  want to use. For example, Line <int> myline; makes a Line which uses ints.
+
416  */
+
417  Line (){;}
+
418 
+
419  /** Increments one step along the line.
+
420  @return the next value.
+
421  */
+
422  inline
+
423  internal_type next()
+
424  {
+
425  current_value = current_value + step_size;
+
426  return current_value;
+
427  }
+
428 
+
429  /** Set the current value of the line.
+
430  The Line will continue incrementing from this
+
431  value using any previously calculated step size.
+
432  @param value the number to set the Line's current_value to.
+
433  */
+
434  inline
+
435  void set(internal_type value)
+
436  {
+
437  current_value=value;
+
438  }
+
439 
+
440  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
+
441  @param targetvalue the value to move towards.
+
442  @param num_steps how many steps to take to reach the target as a UFix<_NI,0>
+
443  */
+
444  template<int8_t _NI>
+
445  void set(internal_type targetvalue, UFix<_NI,0> num_steps)
+
446  {
+
447  if(num_steps.asRaw()) {
+
448  auto numerator = targetvalue-current_value;
+
449  step_size = numerator*num_steps.invAccurate();
+
450  } else {
+
451  step_size = 0;
+
452  current_value = targetvalue;
+
453  }
+
454  }
+
455 
+
456 
+
457  /** Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
+
458  @param targetvalue the value to move towards.
+
459  @param num_steps how many steps to take to reach the target.
+
460  */
+
461  template<typename T>
+
462  void set(internal_type targetvalue, T num_steps)
+
463  {
+
464  if(num_steps) {
+
465  auto numerator = targetvalue-current_value;
+
466  step_size = internal_type(numerator.asRaw()/num_steps,true);
+
467  } else {
+
468  step_size = 0;
+
469  current_value = targetvalue;
+
470  }
+
471  }
+
472 
+
473  /** Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
+
474  @param startvalue the number to set the Line's current_value to.
+
475  @param targetvalue the value to move towards.
+
476  @param num_steps how many steps to take to reach the target.
+
477  */
+
478  template<typename T>
+
479  void set(internal_type startvalue, internal_type targetvalue, T num_steps)
+
480  {
+
481  set(startvalue);
+
482  set(targetvalue, num_steps);
+
483  }
+
484 };
+
485 
+
486 
+
487 
+
488 /**
+
489 @example 02.Control/Control_Tremelo/Control_Tremelo.ino
+
490 This example demonstrates the Line class.
+
491 */
+
492 
+
493 #endif /* LINE_H_ */
diff --git a/extras/doc/html/_low_pass_filter_8h_source.html b/extras/doc/html/_low_pass_filter_8h_source.html index ce3946a25..289648a67 100644 --- a/extras/doc/html/_low_pass_filter_8h_source.html +++ b/extras/doc/html/_low_pass_filter_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: LowPassFilter.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,32 @@
LowPassFilter.h
-
1 /*
2  * LowPassFilter.h
3  *
4  * Copyright 2012 Tim Barrass
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #ifndef LOWPASS_H_
14 #define LOWPASS_H_
15 
16 #include<ResonantFilter.h>
17 #warning This header is deprecated, please use ResonantFilter.h instead.
18 
19 #endif /* LOWPASS_H_ */
+
1 /*
+
2  * LowPassfilter.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 
+
13 #ifndef LOWPASS_H_
+
14 #define LOWPASS_H_
+
15 
+
16 #include<ResonantFilter.h>
+
17 #warning This header is deprecated, please use ResonantFilter.h instead.
+
18 
+
19 #endif /* LOWPASS_H_ */
+
diff --git a/extras/doc/html/_meta_oscil_8h_source.html b/extras/doc/html/_meta_oscil_8h_source.html index fa8ac078d..bfe9e5dc7 100644 --- a/extras/doc/html/_meta_oscil_8h_source.html +++ b/extras/doc/html/_meta_oscil_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MetaOscil.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,36 +99,246 @@
MetaOscil.h
-
1 /*
2  * MetaOscil.h
3  *
4  * A wrap-up to swap between different oscillators seemlessly, allowing to produce non-aliased sounds by automatically switching between oscillators.
5  *
6  * This file is part of Mozzi.
7  */
8 
9 #ifndef META_OSCIL_H
10 #define META_OSCIL_H
11 
12 
13 #include <Arduino.h>
14 
15 #include "Oscil.h"
16 #include "mozzi_fixmath.h"
17 
18 
19 /**
20  MetaOscil is a wrapper for several Oscil. Once constructed it will behave exactly as an Oscil except that it will automatically switch between Oscil depending on the asked frequency. This allows to produce non-aliased sounds by switching between tables with less and less harmonics as the frequency increases.
21 */
22 
23 
24 template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE, byte N_OSCIL>
25  class MetaOscil
26 
27 {
28  public:
29  /** Constructor
30  Declare a MetaOscil containing any number of Oscil pointers. Every Oscil should have the same TABLE_NUM_CELLS and UPDATE_RATE which are also passed in the MetaOscil constructor.
31  @param N_OSCIL is the number of Oscil contained in the MetaOscil. This cannot be changed after construction. */
32  template<class... T> MetaOscil(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* first, T*... elements):oscillators{first, elements...} {
34 
35  MetaOscil(){};
36 
37  /* Add one oscil to the MetaOscil.
38  @param osc is a pointer toward an Oscil
39  @param cutoff_freq is the cutoff frequency of this Oscil
40  void addOscil(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* osc, int cutoff_freq)
41  {
42  oscillators[current_rank] = osc;
43  cutoff_freqs[current_rank] = cutoff_freq;
44  if (current_rank == 0) current_osc=oscillators[0];
45  current_rank += 1;
46  }*/
47 
48 
49  /** Set all Oscil of a MetaOscil.
50  @param first... is a list of pointers towards several Oscil */
51  template<typename ... T > void setOscils(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* first,T... elements)
52  {
53  oscillators[current_rank]=first;
54  if (current_rank == 0) current_osc=oscillators[0];
55  current_rank+=1;
56  setOscils(elements...);
57  current_rank = 0;
58  }
59 
60  void setOscils(){};
61 
62 
63  /** Set all the cutoff frequencies for changing between Oscil. They have to be sorted in increasing values and contain at least N_OSCIL-1 values. Note that the last Oscil will be used by default for frequencies higher than the higher cutoff, hence the last value can be discarded.
64  @param first, elements... a set of int cutoff frequencies.*/
65  template<typename ... T > void setCutoffFreqs(int first,T... elements)
66  {
67  cutoff_freqs[current_rank]=first;
68  current_rank+=1;
69  setCutoffFreqs(elements...);
70  current_rank = 0;
71  }
72 
73  void setCutoffFreqs() {};
74 
75  /** Set or change the cutoff frequency of one Oscil.
76  @param rank is the rank of the Oscil.
77  @param freq is the cutoff frequency. */
78  void setCutoffFreq(int freq, byte rank)
79  {
80  cutoff_freqs[rank] = freq;
81  }
82 
83  /** Updates the phase according to the current frequency and returns the sample at the new phase position.
84  @return the next sample.
85  */
86  inline
87  int8_t next() {return current_osc->next();}
88 
89  /** Change the sound table which will be played by the Oscil of rank.
90  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
91  @param rank is the Oscil.*/
92  void setTable(const int8_t * TABLE_NAME, byte rank) {oscillators[rank]->setTable(TABLE_NAME);}
93 
94 
95  /** Set the phase of the currently playing Oscil.
96  @param phase a position in the wavetable.*/
97  void setPhase(unsigned int phase) {current_osc->setPhase(phase);}
98 
99 
100  /** Set the phase of the currently playing Oscil in fractional format.
101  @param phase a position in the wavetable.*/
102  void setPhaseFractional(unsigned long phase) {current_osc->setPhaseFractional(phase);}
103 
104 
105  /** Get the phase of the currently playin Oscil in fractional format.
106  @return position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
107  */
108  unsigned long getPhaseFractional() {return current_osc->getPhaseFractional();}
109 
110 
111 
112  /** Returns the next sample given a phase modulation value.
113  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
114  phmod_proportion parameter is a Q15n16 fixed-point number where the fractional
115  n16 part represents almost -1 to almost 1, modulating the phase by one whole table length in
116  each direction.
117  @return a sample from the table.*/
118  inline
119  int8_t phMod(Q15n16 phmod_proportion) {return current_osc->phMod(phmod_proportion);}
120 
121 
122  /** Set the MetaOsc frequency with an unsigned int.
123  @param frequency to play the wave table.*/
124  inline
125  void setFreq(int frequency, bool apply = true)
126  {
127  if (frequency < cutoff_freqs[0]) //getting out the extreme cases
128  {
129  oscillators[0]->setPhaseFractional(current_osc->getPhaseFractional());
130  current_osc = oscillators[0];
131  current_osc->setFreq(frequency);
132  }
133 
134  else if (frequency > cutoff_freqs[N_OSCIL-1])
135  {
136  oscillators[N_OSCIL-1]->setPhaseFractional(current_osc->getPhaseFractional());
137  current_osc = oscillators[N_OSCIL-1];
138  current_osc->setFreq(frequency);
139  }
140  else // dichotomic search
141  {
142  byte low_point = 0, high_point = N_OSCIL-1, mid_point = (N_OSCIL-1)>>1;
143  while(low_point != high_point)
144  {
145  if (frequency > cutoff_freqs[mid_point]) low_point = mid_point+1;
146  else if (frequency < cutoff_freqs[mid_point]) high_point = mid_point;
147  else
148  {
149  break;
150  }
151  mid_point = (low_point + high_point)>>1;
152  }
153  oscillators[mid_point]->setPhaseFractional(current_osc->getPhaseFractional());
154  current_osc = oscillators[mid_point];
155  if (apply) current_osc->setFreq(frequency);
156  }
157 
158  }
159 
160 
161  /** Set the MetaOsc frequency with a float.
162  @param frequency to play the wave table.*/
163  inline
164  void setFreq(float frequency)
165  {
166  setFreq((int) frequency, false);
167  current_osc->setFreq(frequency);
168  }
169 
170 
171  /** Set the MetaOsc frequency with a Q24n8 fixed-point number format.
172  @param frequency to play the wave table.*/
173  inline
174  void setFreq_Q24n8(Q24n8 frequency)
175  {
176  setFreq((int) (frequency>>8), false);
177  current_osc->setFreq_Q24n8(frequency);
178  }
179 
180 
181  /** Set the MetaOsc frequency with a Q16n16 fixed-point number format.
182  @param frequency to play the wave table.*/
183  inline
184  void setFreq_Q16n16(Q16n16 frequency)
185  {
186  setFreq((int) (frequency>>16), false);
187  current_osc->setFreq_Q16n16(frequency);
188  }
189 
190 
191  /** Returns the sample at the given table index of the current Oscil.
192  @param index between 0 and the table size.The
193  index rolls back around to 0 if it's larger than the table size.
194  @return the sample at the given table index.
195  */
196  inline
197  int8_t atIndex(unsigned int index) {return current_osc->atIndex(index);}
198 
199 
200  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
201  @param frequency for which you want to calculate a phase increment value.
202  @return the phase increment value which will produce a given frequency.*/
203  inline
204  unsigned long phaseIncFromFreq(int frequency) {return current_osc->phaseIncFromFreq(frequency);}
205 
206  /** Set a specific phase increment.
207  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
208  */
209  inline
210  void setPhaseInc(unsigned long phaseinc_fractional) {current_osc->setPhaseInc(phaseinc_fractional);}
211 
212 
213 
214  private:
215  Oscil<NUM_TABLE_CELLS, UPDATE_RATE> * oscillators[N_OSCIL];
216  Oscil<NUM_TABLE_CELLS, UPDATE_RATE> * current_osc = NULL;
217  int cutoff_freqs[N_OSCIL];
218  byte current_rank = 0;
219 
220 };
221 
222 /**
223 @example 06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino
224 This example demonstrates the Meta_Oscil class.
225 */
226 
227 #endif /* META_OSCIL_H */
void setPhaseInc(unsigned long phaseinc_fractional)
Set a specific phase increment.
Definition: MetaOscil.h:210
-
void setFreq(int frequency, bool apply=true)
Set the MetaOsc frequency with an unsigned int.
Definition: MetaOscil.h:125
-
void setFreq(float frequency)
Set the MetaOsc frequency with a float.
Definition: MetaOscil.h:164
-
void setFreq_Q24n8(Q24n8 frequency)
Set the MetaOsc frequency with a Q24n8 fixed-point number format.
Definition: MetaOscil.h:174
-
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:59
-
void setCutoffFreqs(int first, T... elements)
Set all the cutoff frequencies for changing between Oscil.
Definition: MetaOscil.h:65
-
void setCutoffFreq(int freq, byte rank)
Set or change the cutoff frequency of one Oscil.
Definition: MetaOscil.h:78
-
int8_t atIndex(unsigned int index)
Returns the sample at the given table index of the current Oscil.
Definition: MetaOscil.h:197
-
void setOscils(Oscil< NUM_TABLE_CELLS, UPDATE_RATE > *first, T... elements)
Set all Oscil of a MetaOscil.
Definition: MetaOscil.h:51
-
unsigned long getPhaseFractional()
Get the phase of the currently playin Oscil in fractional format.
Definition: MetaOscil.h:108
-
int8_t phMod(Q15n16 phmod_proportion)
Returns the next sample given a phase modulation value.
Definition: MetaOscil.h:119
-
void setPhaseFractional(unsigned long phase)
Set the phase of the currently playing Oscil in fractional format.
Definition: MetaOscil.h:102
-
MetaOscil(Oscil< NUM_TABLE_CELLS, UPDATE_RATE > *first, T *... elements)
Constructor Declare a MetaOscil containing any number of Oscil pointers.
Definition: MetaOscil.h:32
-
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:43
-
void setPhase(unsigned int phase)
Set the phase of the currently playing Oscil.
Definition: MetaOscil.h:97
-
unsigned long phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: MetaOscil.h:204
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:44
-
void setTable(const int8_t *TABLE_NAME, byte rank)
Change the sound table which will be played by the Oscil of rank.
Definition: MetaOscil.h:92
-
MetaOscil is a wrapper for several Oscil.
Definition: MetaOscil.h:25
-
int8_t next()
Updates the phase according to the current frequency and returns the sample at the new phase position...
Definition: MetaOscil.h:87
-
void setFreq_Q16n16(Q16n16 frequency)
Set the MetaOsc frequency with a Q16n16 fixed-point number format.
Definition: MetaOscil.h:184
+
1 /*
+
2  * MetaOscil.h
+
3  *
+
4  * A wrap-up to swap between different oscillators seemlessly, allowing to produce non-aliased sounds by automatically switching between oscillators.
+
5  *
+
6  * This file is part of Mozzi.
+
7  *
+
8  * Copyright 2021-2024 T. Combriat and the Mozzi Team
+
9  *
+
10  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
11  *
+
12  */
+
13 
+
14 
+
15 #ifndef META_OSCIL_H
+
16 #define META_OSCIL_H
+
17 
+
18 
+
19 #include <Arduino.h>
+
20 
+
21 #include "Oscil.h"
+
22 #include "mozzi_fixmath.h"
+
23 
+
24 
+
25 /**
+
26  MetaOscil is a wrapper for several Oscil. Once constructed it will behave exactly as an Oscil except that it will automatically switch between Oscil depending on the asked frequency. This allows to produce non-aliased sounds by switching between tables with less and less harmonics as the frequency increases.
+
27 */
+
28 
+
29 
+
30 template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE, byte N_OSCIL>
+
31  class MetaOscil
+
32 
+
33 {
+
34  public:
+
35  /** Constructor
+
36  Declare a MetaOscil containing any number of Oscil pointers. Every Oscil should have the same TABLE_NUM_CELLS and UPDATE_RATE which are also passed in the MetaOscil constructor.
+
37  @param N_OSCIL is the number of Oscil contained in the MetaOscil. This cannot be changed after construction. */
+
38  template<class... T> MetaOscil(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* first, T*... elements):oscillators{first, elements...} {
+
39  current_osc=oscillators[0];};
+
40 
+
41  MetaOscil(){};
+
42 
+
43  /* Add one oscil to the MetaOscil.
+
44  @param osc is a pointer toward an Oscil
+
45  @param cutoff_freq is the cutoff frequency of this Oscil
+
46  void addOscil(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* osc, int cutoff_freq)
+
47  {
+
48  oscillators[current_rank] = osc;
+
49  cutoff_freqs[current_rank] = cutoff_freq;
+
50  if (current_rank == 0) current_osc=oscillators[0];
+
51  current_rank += 1;
+
52  }*/
+
53 
+
54 
+
55  /** Set all Oscil of a MetaOscil.
+
56  @param first... is a list of pointers towards several Oscil */
+
57  template<typename ... T > void setOscils(Oscil<NUM_TABLE_CELLS, UPDATE_RATE>* first,T... elements)
+
58  {
+
59  oscillators[current_rank]=first;
+
60  if (current_rank == 0) current_osc=oscillators[0];
+
61  current_rank+=1;
+
62  setOscils(elements...);
+
63  current_rank = 0;
+
64  }
+
65 
+
66  void setOscils(){};
+
67 
+
68 
+
69  /** Set all the cutoff frequencies for changing between Oscil. They have to be sorted in increasing values and contain at least N_OSCIL-1 values. Note that the last Oscil will be used by default for frequencies higher than the higher cutoff, hence the last value can be discarded.
+
70  @param first, elements... a set of int cutoff frequencies.*/
+
71  template<typename ... T > void setCutoffFreqs(int first,T... elements)
+
72  {
+
73  cutoff_freqs[current_rank]=first;
+
74  current_rank+=1;
+
75  setCutoffFreqs(elements...);
+
76  current_rank = 0;
+
77  }
+
78 
+
79  void setCutoffFreqs() {};
+
80 
+
81  /** Set or change the cutoff frequency of one Oscil.
+
82  @param rank is the rank of the Oscil.
+
83  @param freq is the cutoff frequency. */
+
84  void setCutoffFreq(int freq, byte rank)
+
85  {
+
86  cutoff_freqs[rank] = freq;
+
87  }
+
88 
+
89  /** Updates the phase according to the current frequency and returns the sample at the new phase position.
+
90  @return the next sample.
+
91  */
+
92  inline
+
93  int8_t next() {return current_osc->next();}
+
94 
+
95  /** Change the sound table which will be played by the Oscil of rank.
+
96  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
+
97  @param rank is the Oscil.*/
+
98  void setTable(const int8_t * TABLE_NAME, byte rank) {oscillators[rank]->setTable(TABLE_NAME);}
+
99 
+
100 
+
101  /** Set the phase of the currently playing Oscil.
+
102  @param phase a position in the wavetable.*/
+
103  void setPhase(unsigned int phase) {current_osc->setPhase(phase);}
+
104 
+
105 
+
106  /** Set the phase of the currently playing Oscil in fractional format.
+
107  @param phase a position in the wavetable.*/
+
108  void setPhaseFractional(unsigned long phase) {current_osc->setPhaseFractional(phase);}
+
109 
+
110 
+
111  /** Get the phase of the currently playin Oscil in fractional format.
+
112  @return position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
+
113  */
+
114  unsigned long getPhaseFractional() {return current_osc->getPhaseFractional();}
+
115 
+
116 
+
117 
+
118  /** Returns the next sample given a phase modulation value.
+
119  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
+
120  phmod_proportion parameter is a Q15n16 fixed-point number where the fractional
+
121  n16 part represents almost -1 to almost 1, modulating the phase by one whole table length in
+
122  each direction.
+
123  @return a sample from the table.*/
+
124  inline
+
125  int8_t phMod(Q15n16 phmod_proportion) {return current_osc->phMod(phmod_proportion);}
+
126 
+
127 
+
128  /** Set the MetaOsc frequency with an unsigned int.
+
129  @param frequency to play the wave table.*/
+
130  inline
+
131  void setFreq(int frequency, bool apply = true)
+
132  {
+
133  if (frequency < cutoff_freqs[0]) //getting out the extreme cases
+
134  {
+
135  oscillators[0]->setPhaseFractional(current_osc->getPhaseFractional());
+
136  current_osc = oscillators[0];
+
137  current_osc->setFreq(frequency);
+
138  }
+
139 
+
140  else if (frequency > cutoff_freqs[N_OSCIL-1])
+
141  {
+
142  oscillators[N_OSCIL-1]->setPhaseFractional(current_osc->getPhaseFractional());
+
143  current_osc = oscillators[N_OSCIL-1];
+
144  current_osc->setFreq(frequency);
+
145  }
+
146  else // dichotomic search
+
147  {
+
148  byte low_point = 0, high_point = N_OSCIL-1, mid_point = (N_OSCIL-1)>>1;
+
149  while(low_point != high_point)
+
150  {
+
151  if (frequency > cutoff_freqs[mid_point]) low_point = mid_point+1;
+
152  else if (frequency < cutoff_freqs[mid_point]) high_point = mid_point;
+
153  else
+
154  {
+
155  break;
+
156  }
+
157  mid_point = (low_point + high_point)>>1;
+
158  }
+
159  oscillators[mid_point]->setPhaseFractional(current_osc->getPhaseFractional());
+
160  current_osc = oscillators[mid_point];
+
161  if (apply) current_osc->setFreq(frequency);
+
162  }
+
163 
+
164  }
+
165 
+
166 
+
167  /** Set the MetaOsc frequency with a float.
+
168  @param frequency to play the wave table.*/
+
169  inline
+
170  void setFreq(float frequency)
+
171  {
+
172  setFreq((int) frequency, false);
+
173  current_osc->setFreq(frequency);
+
174  }
+
175 
+
176 
+
177  /** Set the MetaOsc frequency with a Q24n8 fixed-point number format.
+
178  @param frequency to play the wave table.*/
+
179  inline
+
180  void setFreq_Q24n8(Q24n8 frequency)
+
181  {
+
182  setFreq((int) (frequency>>8), false);
+
183  current_osc->setFreq_Q24n8(frequency);
+
184  }
+
185 
+
186 
+
187  /** Set the MetaOsc frequency with a Q16n16 fixed-point number format.
+
188  @param frequency to play the wave table.*/
+
189  inline
+
190  void setFreq_Q16n16(Q16n16 frequency)
+
191  {
+
192  setFreq((int) (frequency>>16), false);
+
193  current_osc->setFreq_Q16n16(frequency);
+
194  }
+
195 
+
196 
+
197  /** Returns the sample at the given table index of the current Oscil.
+
198  @param index between 0 and the table size.The
+
199  index rolls back around to 0 if it's larger than the table size.
+
200  @return the sample at the given table index.
+
201  */
+
202  inline
+
203  int8_t atIndex(unsigned int index) {return current_osc->atIndex(index);}
+
204 
+
205 
+
206  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
+
207  @param frequency for which you want to calculate a phase increment value.
+
208  @return the phase increment value which will produce a given frequency.*/
+
209  inline
+
210  unsigned long phaseIncFromFreq(int frequency) {return current_osc->phaseIncFromFreq(frequency);}
+
211 
+
212  /** Set a specific phase increment.
+
213  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
+
214  */
+
215  inline
+
216  void setPhaseInc(unsigned long phaseinc_fractional) {current_osc->setPhaseInc(phaseinc_fractional);}
+
217 
+
218 
+
219 
+
220  private:
+
221  Oscil<NUM_TABLE_CELLS, UPDATE_RATE> * oscillators[N_OSCIL];
+
222  Oscil<NUM_TABLE_CELLS, UPDATE_RATE> * current_osc = NULL;
+
223  int cutoff_freqs[N_OSCIL];
+
224  byte current_rank = 0;
+
225 
+
226 };
+
227 
+
228 /**
+
229 @example 06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino
+
230 This example demonstrates the Meta_Oscil class.
+
231 */
+
232 
+
233 #endif /* META_OSCIL_H */
diff --git a/extras/doc/html/_metronome_8h_source.html b/extras/doc/html/_metronome_8h_source.html index 604d64022..48a6e7175 100644 --- a/extras/doc/html/_metronome_8h_source.html +++ b/extras/doc/html/_metronome_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Metronome.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,24 +99,116 @@
Metronome.h
-
1 /*
2  * Metronome.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef METRO_H_
13 #define METRO_H_
14 
15 #include "EventDelay.h"
16 
17 /** A metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat.
18 Metronome can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
19 Alternatively, start(milliseconds) will call set() and start() together.
20 This is called Metronome to avoid conflict with the Arduino Metro library.
21 */
22 class Metronome: public EventDelay
23 {
24 
25 public:
26 
27  /** Constructor.
28  Declare a Metronome object.
29  @param delay_milliseconds how long between each occasion when ready() returns true.
30  */
31  Metronome(unsigned int delay_milliseconds = 0): EventDelay(delay_milliseconds), stopped(false) {
32  }
33 
34 
35  /** Start the metronome.
36  @todo have a parameter to set whether it's single or repeating, so start doesn't have to be called for repeats.
37  Pro: simpler user programming. Con: would require an if..then every time ready() is called.
38  */
39  inline
40  void start()
41  {
42  deadline=audioTicks()+ticks;
43  stopped = false;
44  }
45 
46 
47  /** Set the time between beats and start the metronome.
48  @param delay_milliseconds delay time in milliseconds.
49  */
50  inline
51  void start(unsigned int delay_milliseconds)
52  {
53  set(delay_milliseconds);
54  start();
55  }
56 
57 
58 
59  /** Set the beats per minute.
60  @param bpm beats per minute
61  */
62  inline
63  void setBPM(float bpm)
64  {
65  set((unsigned int) (60000.f/bpm));
66  }
67 
68 
69 
70 
71  /** Call this in updateControl() or updateAudio() to check if it is time for a beat.
72  @return true if the time for one is up.
73  */
74  inline
75  bool ready()
76  {
77  unsigned long now = audioTicks();
78  if ((now<deadline) || stopped) return false;
79 
80  deadline=now-(now-deadline)+ticks; // subtract overrun so the timing doesn't slip
81  return true;
82  }
83 
84 
85  inline
86  void stop(){
87  stopped = true;
88  }
89 
90 private:
91  bool stopped;
92 };
93 
94 
95 
96 
97 /**
98 @example 02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino
99 This example shows how to use the Metronome class.
100 */
101 
102 #endif /* METRO_H_ */
Metronome(unsigned int delay_milliseconds=0)
Constructor.
Definition: Metronome.h:31
-
EventDelay(unsigned int delay_milliseconds=0)
Constructor.
Definition: EventDelay.h:29
-
void setBPM(float bpm)
Set the beats per minute.
Definition: Metronome.h:63
-
bool ready()
Call this in updateControl() or updateAudio() to check if it is time for a beat.
Definition: Metronome.h:75
-
A metronome class which is like an EventDelay which retriggers itself when the delay time is up...
Definition: Metronome.h:22
-
void start(unsigned int delay_milliseconds)
Set the time between beats and start the metronome.
Definition: Metronome.h:51
-
A non-blocking replacement for Arduino&#39;s delay() function.
Definition: EventDelay.h:20
-
void start()
Start the metronome.
Definition: Metronome.h:40
-
void set(unsigned int delay_milliseconds)
Set the delay time.
Definition: EventDelay.h:40
+
1 /*
+
2  * Metronome.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 
+
13 #ifndef METRO_H_
+
14 #define METRO_H_
+
15 
+
16 #include "EventDelay.h"
+
17 
+
18 /** A metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat.
+
19 Metronome can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
+
20 Alternatively, start(milliseconds) will call set() and start() together.
+
21 This is called Metronome to avoid conflict with the Arduino Metro library.
+
22 */
+
23 class Metronome: public EventDelay
+
24 {
+
25 
+
26 public:
+
27 
+
28  /** Constructor.
+
29  Declare a Metronome object.
+
30  @param delay_milliseconds how long between each occasion when ready() returns true.
+
31  */
+
32  Metronome(unsigned int delay_milliseconds = 0): EventDelay(delay_milliseconds), stopped(false) {
+
33  }
+
34 
+
35 
+
36  /** Start the metronome.
+
37  @todo have a parameter to set whether it's single or repeating, so start doesn't have to be called for repeats.
+
38  Pro: simpler user programming. Con: would require an if..then every time ready() is called.
+
39  */
+
40  inline
+
41  void start()
+
42  {
+
43  deadline=audioTicks()+ticks;
+
44  stopped = false;
+
45  }
+
46 
+
47 
+
48  /** Set the time between beats and start the metronome.
+
49  @param delay_milliseconds delay time in milliseconds.
+
50  */
+
51  inline
+
52  void start(unsigned int delay_milliseconds)
+
53  {
+
54  set(delay_milliseconds);
+
55  start();
+
56  }
+
57 
+
58 
+
59 
+
60  /** Set the beats per minute.
+
61  @param bpm beats per minute
+
62  */
+
63  inline
+
64  void setBPM(float bpm)
+
65  {
+
66  set((unsigned int) (60000.f/bpm));
+
67  }
+
68 
+
69 
+
70 
+
71 
+
72  /** Call this in updateControl() or updateAudio() to check if it is time for a beat.
+
73  @return true if the time for one is up.
+
74  */
+
75  inline
+
76  bool ready()
+
77  {
+
78  unsigned long now = audioTicks();
+
79  if ((now<deadline) || stopped) return false;
+
80 
+
81  deadline=now-(now-deadline)+ticks; // subtract overrun so the timing doesn't slip
+
82  return true;
+
83  }
+
84 
+
85 
+
86  inline
+
87  void stop(){
+
88  stopped = true;
+
89  }
+
90 
+
91 private:
+
92  bool stopped;
+
93 };
+
94 
+
95 
+
96 
+
97 
+
98 /**
+
99 @example 02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino
+
100 This example shows how to use the Metronome class.
+
101 */
+
102 
+
103 #endif /* METRO_H_ */
diff --git a/extras/doc/html/_mozzi_8h.html b/extras/doc/html/_mozzi_8h.html index 5a134855e..d58bc81c4 100644 --- a/extras/doc/html/_mozzi_8h.html +++ b/extras/doc/html/_mozzi_8h.html @@ -1,9 +1,9 @@ - + - + Mozzi: Mozzi.h File Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -121,9 +117,7 @@ diff --git a/extras/doc/html/_mozzi_8h_source.html b/extras/doc/html/_mozzi_8h_source.html index dcb71fc38..ae77e6a78 100644 --- a/extras/doc/html/_mozzi_8h_source.html +++ b/extras/doc/html/_mozzi_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Mozzi.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -103,15 +99,41 @@
Mozzi.h
-Go to the documentation of this file.
1 /*
2  * Mozzi.h
3  *
4  * Copyright 2024, Tim Barrass and the Mozzi team
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 /** @ingroup core
14  * @file Mozzi.h
15  *
16  * This is the main include file in Mozzi. Almost all sketches using Mozzi will want to include this file @em exactly once.
17  *
18  * Should your sketch require \ref core Mozzi functions in more than one translation unit (i.e. you have more than one .cpp-file
19  * in your sketch itself), only *one* of these shall include this file, while any others shall include \ref MozziHeadersOnly instead.
20  * (Failing to heed this advice will lead to "duplicate definition" errors.)
21  */
22 
23 #ifndef MOZZI_H_
24 #define MOZZI_H_
25 
26 #include "MozziGuts.h"
27 
28 #endif
+Go to the documentation of this file.
1 /*
+
2  * Mozzi.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 
+
13 /** @ingroup core
+
14  * @file Mozzi.h
+
15  *
+
16  * This is the main include file in Mozzi. Almost all sketches using Mozzi will want to include this file @em exactly once.
+
17  *
+
18  * Should your sketch require \ref core Mozzi functions in more than one translation unit (i.e. you have more than one .cpp-file
+
19  * in your sketch itself), only *one* of these shall include this file, while any others shall include \ref MozziHeadersOnly instead.
+
20  * (Failing to heed this advice will lead to "duplicate definition" errors.)
+
21  */
+
22 
+
23 #ifndef MOZZI_H_
+
24 #define MOZZI_H_
+
25 
+
26 #include "MozziGuts.h"
+
27 
+
28 #endif
+
diff --git a/extras/doc/html/_mozzi_config_values_8h_source.html b/extras/doc/html/_mozzi_config_values_8h_source.html index 228378cec..622771015 100644 --- a/extras/doc/html/_mozzi_config_values_8h_source.html +++ b/extras/doc/html/_mozzi_config_values_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziConfigValues.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,67 @@
MozziConfigValues.h
-
1 /** This file keeps a list of named configuration values.
2 
3 Note that these are all given as defines, instead of e.g. const ints or enum values, because they need to be usable at preprocessor level, in order to control conditional compilation.
4 
5 TODO: Fix documentation
6 */
7 
8 #ifndef MOZZICONFIG_VALUES_H
9 #define MOZZICONFIG_VALUES_H
10 
11 
12 
13 #define MOZZI_MONO 1
14 #define MOZZI_STEREO 2
15 
16 // We try to use distinct values as much as possible so we can catch semantic errors like "#define MOZZI_AUDIO_MODE MOZZI_STEREO"
17 #define MOZZI_OUTPUT_PWM 101
18 #define MOZZI_OUTPUT_2PIN_PWM 102
19 #define MOZZI_OUTPUT_EXTERNAL_TIMED 103
20 #define MOZZI_OUTPUT_EXTERNAL_CUSTOM 104
21 #define MOZZI_OUTPUT_PDM_VIA_I2S 105
22 #define MOZZI_OUTPUT_PDM_VIA_SERIAL 106
23 #define MOZZI_OUTPUT_I2S_DAC 107
24 #define MOZZI_OUTPUT_INTERNAL_DAC 108
25 
26 #define MOZZI_AUDIO_INPUT_NONE 201
27 #define MOZZI_AUDIO_INPUT_STANDARD 202
28 
29 #define MOZZI_ANALOG_READ_NONE 301
30 #define MOZZI_ANALOG_READ_STANDARD 302
31 
32 #define MOZZI_I2S_FORMAT_PLAIN 401
33 #define MOZZI_I2S_FORMAT_LSBJ 402
34 
35 // defined with some space in between, just in case. This should be numerically ordered.
36 #define MOZZI_COMPATIBILITY_1_1 1100
37 #define MOZZI_COMPATIBILITY_2_0 2000
38 #define MOZZI_COMPATIBILITY_LATEST 9000 // May be upped, arbitrarily
39 
40 // For convenience
41 #include "hardware_defines.h"
42 
43 
44 #endif
+Go to the documentation of this file.
1 /*
+
2  * MozziConfigValues.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 /** @file MozziConfigValues.h
+
13  * This file keeps a list of named configuration values.
+
14  *
+
15  * Note that these are all given as defines, instead of e.g. const ints or enum values, because they need to be usable at preprocessor level, in order to control conditional compilation.
+
16 */
+
17 
+
18 #ifndef MOZZICONFIG_VALUES_H
+
19 #define MOZZICONFIG_VALUES_H
+
20 
+
21 
+
22 
+
23 #define MOZZI_MONO 1
+
24 #define MOZZI_STEREO 2
+
25 
+
26 // We try to use distinct values as much as possible so we can catch semantic errors like "#define MOZZI_AUDIO_MODE MOZZI_STEREO"
+
27 #define MOZZI_OUTPUT_PWM 101
+
28 #define MOZZI_OUTPUT_2PIN_PWM 102
+
29 #define MOZZI_OUTPUT_EXTERNAL_TIMED 103
+
30 #define MOZZI_OUTPUT_EXTERNAL_CUSTOM 104
+
31 #define MOZZI_OUTPUT_PDM_VIA_I2S 105
+
32 #define MOZZI_OUTPUT_PDM_VIA_SERIAL 106
+
33 #define MOZZI_OUTPUT_I2S_DAC 107
+
34 #define MOZZI_OUTPUT_INTERNAL_DAC 108
+
35 
+
36 #define MOZZI_AUDIO_INPUT_NONE 201
+
37 #define MOZZI_AUDIO_INPUT_STANDARD 202
+
38 
+
39 #define MOZZI_ANALOG_READ_NONE 301
+
40 #define MOZZI_ANALOG_READ_STANDARD 302
+
41 
+
42 #define MOZZI_I2S_FORMAT_PLAIN 401
+
43 #define MOZZI_I2S_FORMAT_LSBJ 402
+
44 
+
45 // defined with some space in between, just in case. This should be numerically ordered.
+
46 #define MOZZI_COMPATIBILITY_1_1 1100
+
47 #define MOZZI_COMPATIBILITY_2_0 2000
+
48 #define MOZZI_COMPATIBILITY_LATEST 9000 // May be upped, arbitrarily
+
49 
+
50 // For convenience
+
51 #include "hardware_defines.h"
+
52 
+
53 
+
54 #endif
+
diff --git a/extras/doc/html/_mozzi_guts_8h_source.html b/extras/doc/html/_mozzi_guts_8h_source.html index 0375a4d2b..adc049244 100644 --- a/extras/doc/html/_mozzi_guts_8h_source.html +++ b/extras/doc/html/_mozzi_guts_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,32 +99,219 @@
MozziGuts.h
-
1 /*
2  * MozziGuts.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef MOZZIGUTS_H_
13 #define MOZZIGUTS_H_
14 
15 #include "Arduino.h"
16 
17 #include "MozziConfigValues.h"
18 
19 #if !(defined(MOZZI_H_) || defined(MOZZI_HEADERS_ONLY_H_))
20 #warning Direct inclusion of MozziGuts.h is deprecated. Use Mozzi.h, instead, and read about porting to Mozzi 2.0
21 #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_1_1
22 #endif
23 
24 #include "hardware_defines.h"
25 
26 #if IS_TEENSY3() || IS_TEENSY4()
27 // required from http://github.com/pedvide/ADC for Teensy 3.*
28 #include <ADC.h>
29 #endif
30 
31 #include "internal/config_checks_generic.h"
32 
33 #include "mozzi_analog.h"
34 #include "AudioOutput.h"
35 
36 // TODO Mozzi 2.0: These typedef probably obsolete?
37 // common numeric types
38 typedef unsigned char uchar;
39 typedef unsigned int uint;
40 typedef unsigned long ulong;
41 
42 #if defined(__AVR__)
43 typedef unsigned char byte; // for arduino ide
44 typedef unsigned char uint8_t;
45 typedef signed char int8_t;
46 typedef unsigned int uint16_t;
47 typedef signed int int16_t;
48 typedef unsigned long uint32_t;
49 typedef signed long int32_t;
50 #else
51 // Other supported arches add typedefs, here, unless already defined for that platform needed
52 #endif
53 
54 /*! @defgroup core Mozzi Core Functions
55 
56 @ingroup core
57 Sets up the timers for audio and control rate processes, storing the timer
58 registers so they can be restored when Mozzi stops. startMozzi() goes in your sketch's
59 setup() routine.
60 
61 This function intializes the timer(s) needed to move audio samples to the output according to the
62 configured @ref MOZZI_AUDIO_MODE .
63 
64 @param control_rate_hz Sets how often updateControl() is called. It must be a power of 2.
65 If no parameter is provided, control_rate_hz is set to MOZZI_CONTROL_RATE,
66 which has a default value of 64 (you can re-\#define it in your sketch).
67 The practical upper limit for control rate depends on how busy the processor is,
68 and you might need to do some tests to find the best setting.
69 
70 @note startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(),
71 which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack).
72 They are all called automatically and hidden away because it keeps things simple for a STANDARD_PLUS set up,
73 but if it turns out to be confusing, they might need to become visible again.
74 */
75 void startMozzi(int control_rate_hz = MOZZI_CONTROL_RATE);
76 
77 
78 
79 /** @ingroup core
80 Stops audio and control interrupts and restores the timers to the values they
81 had before Mozzi was started. This could be useful when using sensor libraries
82 which depend on the same timers as Mozzi.
83 
84 A potentially better option for resolving timer conflicts involves using
85 non-blocking methods, such as demonstrated by the twowire_nonblock code in the
86 forked version of Mozzi on github, so sound production can continue while
87 reading sensors.
88 
89 As it is, stopMozzi restores all the Timers used by Mozzi to their previous
90 settings. Another scenario which could be easily hacked in MozziGuts.hpp could
91 involve individually saving and restoring particular Timer registers depending
92 on which one(s) are required for other tasks.
93 
94 @note This function is not actually implemented on all platforms.
95 */
96 void stopMozzi();
97 
98 
100 AudioOutput_t updateAudio();
101 #else
102 /** @ingroup core
103 This is where you put your audio code. updateAudio() has to keep up with the
104 MOZZI_AUDIO_RATE of 16384 or 32768 Hz, so to keep things running smoothly, avoid doing any
105 calculations here which could be done in setup() or updateControl().
106 @return an audio sample.
107 
108 While is possible (in mono sketches) to return a plain unscaled int, it is generally best to return
109 auto-scaled samples using MonoOutput::from8Bit(), MonoOutput::from16Bit(), MonoOutput::fromNbit(), or
110 their StereoOutput equivalents.
111 */
112 AudioOutput updateAudio();
113 #endif
114 
115 /** @ingroup core
116 This is where you put your control code. You need updateControl() somewhere in
117 your sketch, even if it's empty. updateControl() is called at the control rate
118 you set in startMozzi(). To save processor load, avoid any calculations here
119 which could be done in setup().
120 */
121 void updateControl();
122 
123 
124 /** @ingroup core
125 This is required in Arduino's loop(). If there is room in Mozzi's output buffer,
126 audioHook() calls updateAudio() once and puts the result into the output
127 buffer. Also, if \@ref MOZZI_AUDIO_INPUT is enabled in the config,
128 audioHook() takes care of moving audio input from the input buffer so it can be
129 accessed with getAudioInput() in your updateAudio() routine.
130 If other functions are called in loop() along with audioHook(), see if
131 they can be called less often by moving them into updateControl(),
132 to save processing power. Otherwise it may be most efficient to
133 calculate a block of samples at a time by putting audioHook() in a loop of its
134 own, rather than calculating only 1 sample for each time your other functions
135 are called.
136 */
137 void audioHook();
138 
139 
140 
141 /** @ingroup analog
142 This returns audio input from the input buffer, if
143 \@ref MOZZI_AUDIO_INPUT is enabled in the config (see also the related option MOZZI_AUDIO_INPUT_PIN).
144 
145 The audio signal needs to be in the range 0 to VCC volts (i.e. 5 volts on Arduino Uno R3).
146 Circuits and discussions about biasing a signal
147 in the middle of this range can be found at
148 http://electronics.stackexchange.com/questions/14404/dc-biasing-audio-signal
149 and
150 http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/ .
151 A circuit and instructions for amplifying and biasing a microphone signal can be found at
152 http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS
153 @return audio data from the input buffer
154 */
156 int getAudioInput();
157 #endif
158 
159 
160 /** @ingroup core
161 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
162 and also it is synchronized with the currently processed audio sample (which, due to the audio
163 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
164 audioTicks() is updated each time an audio sample
165 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
166 16384 Hz).
167 @return the number of audio ticks since the program began.
168 */
169 unsigned long audioTicks();
170 
171 
172 
173 /** @ingroup core
174 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
175 and also it is synchronized with the currently processed audio sample (which, due to the audio
176 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
177 audioTicks() is updated each time an audio sample
178 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
179 16384 Hz).
180 @return the approximate number of microseconds since the program began.
181 @todo incorporate mozziMicros() in a more accurate EventDelay()?
182 */
183 unsigned long mozziMicros();
184 
185 #ifndef _MOZZI_HEADER_ONLY
186 #include "internal/MozziGuts.hpp"
187 #endif
188 
189 #endif /* MOZZIGUTS_H_ */
unsigned long mozziMicros()
An alternative for Arduino time functions like micros() and millis().
Definition: MozziGuts.hpp:255
-
#define MOZZI_CONTROL_RATE
Control rate setting.
-
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
Definition: MozziGuts.hpp:291
-
#define MOZZI_AUDIO_INPUT_NONE
-
#define IS_TEENSY4()
-
void updateControl()
This is where you put your control code.
-
void audioHook()
This is required in Arduino&#39;s loop().
Definition: MozziGuts.hpp:218
-
#define MOZZI_IS(X,...)
Definition: mozzi_macros.h:51
-
#define IS_TEENSY3()
-
AudioOutput_t updateAudio()
This is where you put your audio code.
-
#define MOZZI_MONO
This file keeps a list of named configuration values.
-
#define MOZZI_COMPATIBILITY_1_1
-
#define MOZZI_AUDIO_CHANNELS
-
unsigned long audioTicks()
An alternative for Arduino time functions like micros() and millis().
Definition: MozziGuts.hpp:245
-
#define MOZZI_AUDIO_INPUT
Whether to enable built in audio input feature.
-
#define MOZZI_COMPATIBILITY_LEVEL
Mozzi generally tries to keep your old sketches working, but we continue to find new (and hopefully b...
-
#define _MOZZI_HEADER_ONLY
+
1 /*
+
2  * MozziGuts.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 MOZZIGUTS_H_
+
13 #define MOZZIGUTS_H_
+
14 
+
15 #include "Arduino.h"
+
16 
+
17 #include "MozziConfigValues.h"
+
18 
+
19 #if !(defined(MOZZI_H_) || defined(MOZZI_HEADERS_ONLY_H_))
+
20 #warning Direct inclusion of MozziGuts.h is deprecated. Use Mozzi.h, instead, and read about porting to Mozzi 2.0
+
21 #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_1_1
+
22 #endif
+
23 
+
24 #include "hardware_defines.h"
+
25 
+
26 #if IS_TEENSY3() || IS_TEENSY4()
+
27 // required from http://github.com/pedvide/ADC for Teensy 3.*
+
28 #include <ADC.h>
+
29 #endif
+
30 
+
31 #include "internal/config_checks_generic.h"
+
32 
+
33 #include "mozzi_analog.h"
+
34 #include "AudioOutput.h"
+
35 
+
36 // TODO Mozzi 2.0: These typedef probably obsolete?
+
37 // common numeric types
+
38 typedef unsigned char uchar;
+
39 typedef unsigned int uint;
+
40 typedef unsigned long ulong;
+
41 
+
42 #if defined(__AVR__)
+
43 typedef unsigned char byte; // for arduino ide
+
44 typedef unsigned char uint8_t;
+
45 typedef signed char int8_t;
+
46 typedef unsigned int uint16_t;
+
47 typedef signed int int16_t;
+
48 typedef unsigned long uint32_t;
+
49 typedef signed long int32_t;
+
50 #else
+
51 // Other supported arches add typedefs, here, unless already defined for that platform needed
+
52 #endif
+
53 
+
54 /*! @defgroup core Mozzi Core Functions
+
55 
+
56 @ingroup core
+
57 Sets up the timers for audio and control rate processes, storing the timer
+
58 registers so they can be restored when Mozzi stops. startMozzi() goes in your sketch's
+
59 setup() routine.
+
60 
+
61 This function intializes the timer(s) needed to move audio samples to the output according to the
+
62 configured @ref MOZZI_AUDIO_MODE .
+
63 
+
64 @param control_rate_hz Sets how often updateControl() is called. It must be a power of 2.
+
65 If no parameter is provided, control_rate_hz is set to MOZZI_CONTROL_RATE,
+
66 which has a default value of 64 (you can re-\#define it in your sketch).
+
67 The practical upper limit for control rate depends on how busy the processor is,
+
68 and you might need to do some tests to find the best setting.
+
69 
+
70 @note startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(),
+
71 which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack).
+
72 They are all called automatically and hidden away because it keeps things simple for a STANDARD_PLUS set up,
+
73 but if it turns out to be confusing, they might need to become visible again.
+
74 */
+
75 void startMozzi(int control_rate_hz = MOZZI_CONTROL_RATE);
+
76 
+
77 
+
78 
+
79 /** @ingroup core
+
80 Stops audio and control interrupts and restores the timers to the values they
+
81 had before Mozzi was started. This could be useful when using sensor libraries
+
82 which depend on the same timers as Mozzi.
+
83 
+
84 A potentially better option for resolving timer conflicts involves using
+
85 non-blocking methods, such as demonstrated by the twowire_nonblock code in the
+
86 forked version of Mozzi on github, so sound production can continue while
+
87 reading sensors.
+
88 
+
89 As it is, stopMozzi restores all the Timers used by Mozzi to their previous
+
90 settings. Another scenario which could be easily hacked in MozziGuts.hpp could
+
91 involve individually saving and restoring particular Timer registers depending
+
92 on which one(s) are required for other tasks.
+
93 
+
94 @note This function is not actually implemented on all platforms.
+
95 */
+
96 void stopMozzi();
+
97 
+
98 
+ +
100 AudioOutput_t updateAudio();
+
101 #else
+
102 /** @ingroup core
+
103 This is where you put your audio code. updateAudio() has to keep up with the
+
104 MOZZI_AUDIO_RATE of 16384 or 32768 Hz, so to keep things running smoothly, avoid doing any
+
105 calculations here which could be done in setup() or updateControl().
+
106 @return an audio sample.
+
107 
+
108 While is possible (in mono sketches) to return a plain unscaled int, it is generally best to return
+
109 auto-scaled samples using MonoOutput::from8Bit(), MonoOutput::from16Bit(), MonoOutput::fromNbit(), or
+
110 their StereoOutput equivalents.
+
111 */
+
112 AudioOutput updateAudio();
+
113 #endif
+
114 
+
115 /** @ingroup core
+
116 This is where you put your control code. You need updateControl() somewhere in
+
117 your sketch, even if it's empty. updateControl() is called at the control rate
+
118 you set in startMozzi(). To save processor load, avoid any calculations here
+
119 which could be done in setup().
+
120 */
+
121 void updateControl();
+
122 
+
123 
+
124 /** @ingroup core
+
125 This is required in Arduino's loop(). If there is room in Mozzi's output buffer,
+
126 audioHook() calls updateAudio() once and puts the result into the output
+
127 buffer. Also, if \@ref MOZZI_AUDIO_INPUT is enabled in the config,
+
128 audioHook() takes care of moving audio input from the input buffer so it can be
+
129 accessed with getAudioInput() in your updateAudio() routine.
+
130 If other functions are called in loop() along with audioHook(), see if
+
131 they can be called less often by moving them into updateControl(),
+
132 to save processing power. Otherwise it may be most efficient to
+
133 calculate a block of samples at a time by putting audioHook() in a loop of its
+
134 own, rather than calculating only 1 sample for each time your other functions
+
135 are called.
+
136 */
+
137 void audioHook();
+
138 
+
139 /** @ingroup analog
+
140 
+
141 See getAudioInput(). The template parameter specifies the desired value range in bits. */
+
142 template<byte RES> uint16_t getAudioInput();
+
143 
+
144 /** @ingroup analog
+
145 
+
146 See getAudioInput(). Equivalent to getAudioInput<16>(). */
+
147 template<byte RES> inline uint16_t getAudioInput16() { return getAudioInput<16>(); }
+
148 
+
149 /** @ingroup analog
+
150 This returns audio input from the input buffer, if
+
151 \@ref MOZZI_AUDIO_INPUT is enabled in the config (see also the related option MOZZI_AUDIO_INPUT_PIN).
+
152 
+
153 The audio signal needs to be in the range 0 to VCC volts (i.e. 5 volts on Arduino Uno R3).
+
154 Circuits and discussions about biasing a signal
+
155 in the middle of this range can be found at
+
156 http://electronics.stackexchange.com/questions/14404/dc-biasing-audio-signal
+
157 and
+
158 http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/ .
+
159 A circuit and instructions for amplifying and biasing a microphone signal can be found at
+
160 http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS
+
161 
+
162 @note The value range returned by this function follows the same rules as detailed in the documentation
+
163  for mozziAnalogRead(): For portable code, define MOZZI_ANALGO_READ_RESOLUTION at the top of your
+
164  sketch, or use the templated version of this function.
+
165 
+
166 @return audio data from the input buffer
+
167 */
+
168 #if defined(FOR_DOXYGEN_ONLY) || (!MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE))
+
169 #if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION)
+
170 inline uint16_t getAudioInput() { return getAudioInput<MOZZI_ANALOG_READ_RESOLUTION>(); };
+
171 #else
+
172 MOZZI_DEPRECATED("2.0", "This use of getAudioInput() is not portable. Refer to the API documentation for suggested alternatives") inline uint16_t getAudioInput() { return getAudioInput<MOZZI__INTERNAL_ANALOG_READ_RESOLUTION>(); };
+
173 #endif
+
174 #endif
+
175 
+
176 
+
177 /** @ingroup core
+
178 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
+
179 and also it is synchronized with the currently processed audio sample (which, due to the audio
+
180 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
+
181 audioTicks() is updated each time an audio sample
+
182 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
+
183 16384 Hz).
+
184 @return the number of audio ticks since the program began.
+
185 */
+
186 unsigned long audioTicks();
+
187 
+
188 
+
189 
+
190 /** @ingroup core
+
191 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
+
192 and also it is synchronized with the currently processed audio sample (which, due to the audio
+
193 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
+
194 audioTicks() is updated each time an audio sample
+
195 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
+
196 16384 Hz).
+
197 @return the approximate number of microseconds since the program began.
+
198 @todo incorporate mozziMicros() in a more accurate EventDelay()?
+
199 */
+
200 unsigned long mozziMicros();
+
201 
+
202 #ifndef _MOZZI_HEADER_ONLY
+
203 #include "internal/MozziGuts.hpp"
+
204 #endif
+
205 
+
206 #endif /* MOZZIGUTS_H_ */
diff --git a/extras/doc/html/_mozzi_guts_8hpp_source.html b/extras/doc/html/_mozzi_guts_8hpp_source.html index 9daf9d181..7713ec293 100644 --- a/extras/doc/html/_mozzi_guts_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,34 +99,329 @@
MozziGuts.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 #include <Arduino.h>
13 
14 #include "CircularBuffer.h"
15 #include "mozzi_analog.h"
16 #include "internal/mozzi_rand_p.h"
17 #include "AudioOutput.h"
18 
19 namespace MozziPrivate {
20 
21 // Forward declarations of functions to be provided by platform specific implementations
22 #if (!BYPASS_MOZZI_OUTPUT_BUFFER)
23 static void CACHED_FUNCTION_ATTR defaultAudioOutput();
24 #endif
25 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
26 static void advanceADCStep(); // to be provided by platform implementation
27 static void startSecondADCReadOnCurrentChannel(); // to be provided by platform implementation
28 static uint8_t adc_count = 0; // needed below
29 #endif
30 }
31 
32 // Include the appropriate implementation
33 #if IS_AVR()
34 # include "MozziGuts_impl_AVR.hpp"
35 #elif IS_STM32MAPLE()
36 # include "MozziGuts_impl_STM32.hpp"
37 #elif IS_STM32DUINO()
38 # include "MozziGuts_impl_STM32duino.hpp"
39 #elif IS_ESP32()
40 # include "MozziGuts_impl_ESP32.hpp"
41 #elif IS_ESP8266()
42 # include "MozziGuts_impl_ESP8266.hpp"
43 #elif (IS_TEENSY3() || IS_TEENSY4())
44 # include "MozziGuts_impl_TEENSY.hpp"
45 #elif (IS_SAMD21())
46 # include "MozziGuts_impl_SAMD.hpp"
47 #elif (IS_RP2040())
48 # include "MozziGuts_impl_RP2040.hpp"
49 #elif (IS_MBED())
50 # include "MozziGuts_impl_MBED.hpp"
51 #elif (IS_RENESAS())
52 # include "MozziGuts_impl_RENESAS.hpp"
53 #else
54 # error "Platform not (yet) supported. Check MozziGuts_impl_template.hpp and existing implementations for a blueprint for adding your favorite MCU."
55 #endif
56 
57 /* Retro-compatibility with "legacy" boards which use the async
58  ADC for getting AUDIO_INPUT
59 */
60 #if !defined(MOZZI__LEGACY_AUDIO_INPUT_IMPL)
61 # if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
62 # define MOZZI__LEGACY_AUDIO_INPUT_IMPL 1
63 # else
64 # define MOZZI__LEGACY_AUDIO_INPUT_IMPL 0
65 # endif
66 #endif
67 
68 namespace MozziPrivate {
69 ////// BEGIN Output buffering /////
70 #if BYPASS_MOZZI_OUTPUT_BUFFER == true
71 uint64_t samples_written_to_buffer = 0;
72 
73 inline void bufferAudioOutput(const AudioOutput_t f) {
74  audioOutput(f);
75  ++samples_written_to_buffer;
76 }
77 #else
78 CircularBuffer<AudioOutput> output_buffer; // fixed size 256
79 # define canBufferAudioOutput() (!output_buffer.isFull())
80 # define bufferAudioOutput(f) output_buffer.write(f)
81 static void CACHED_FUNCTION_ATTR defaultAudioOutput() {
82 
83 #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // in that case, we rely on asynchroneous ADC reads implemented for mozziAnalogRead to get the audio in samples
84  MOZZI_ASSERT_NOTEQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE);
85  adc_count = 0;
86  startSecondADCReadOnCurrentChannel(); // the current channel is the AUDIO_INPUT pin
87 # endif
88  audioOutput(output_buffer.read());
89 }
90 #endif // #if (AUDIO_INPUT_MODE == AUDIO_INPUT_LEGACY)
91 ////// END Output buffering ///////
92 
93 
94 ////// BEGIN Analog input code ////////
95 /* Analog input code was informed initially by a discussion between
96 jRaskell, bobgardner, theusch, Koshchi, and code by jRaskell.
97 http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=789581
98 */
99 
100 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
101 
102 #include "Stack.h"
103 static volatile int analog_readings[NUM_ANALOG_INPUTS];
104 static Stack <volatile int8_t,NUM_ANALOG_INPUTS> adc_channels_to_read;
105 volatile static int8_t current_channel = -1; // volatile because accessed in control and adc ISRs
106 
107 /* gets the next channel to read off the stack, and if there is a channel there, it changes to that channel and starts a conversion.
108 */
109 void adcReadSelectedChannels() {
110  // ugly syntax below saves a few bytes/instructions (as current_channel is declared volatile)
111  if((current_channel = adc_channels_to_read.pop()) >= 0) adcStartConversion(current_channel);
112 }
113 
114 /* Called each time in updateControlWithAutoADC(), after updateControl()
115  Forbidding inline, here, saves a wholesome 16 bytes flash on AVR (without USE_AUDIO_INPUT). No idea, why.
116 */
117 __attribute__((noinline)) void adcStartReadCycle() {
118  if (current_channel < 0) // last read of adc_channels_to_read stack was empty, ie. all channels from last time have been read
119  {
120 #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // use of async ADC for audio input
121  adc_channels_to_read.push(MOZZI_AUDIO_INPUT_PIN); // for audio
122 #else
123  adcReadSelectedChannels();
124  adc_count = 0;
125 #endif
126  }
127 }
128 
129 int mozziAnalogRead(uint8_t pin) {
130  pin = adcPinToChannelNum(pin); // allow for channel or pin numbers; on most platforms other than AVR this has no effect. See note on pins/channels
131  adc_channels_to_read.push(pin);
132  return analog_readings[channelNumToIndex(pin)];
133 }
134 
135 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
136 static AudioOutputStorage_t audio_input; // holds the latest audio from input_buffer
137 AudioOutputStorage_t getAudioInput() { return audio_input; }
138 #endif
139 
140 #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1)
141 // ring buffer for audio input
142 CircularBuffer<unsigned int> input_buffer; // fixed size 256
143 #define audioInputAvailable() (!input_buffer.isEmpty())
144 #define readAudioInput() (input_buffer.read())
145 /** NOTE: Triggered at MOZZI_AUDIO_RATE via defaultAudioOutput(). In addition to the AUDIO_INPUT_PIN, at most one reading is taken for mozziAnalogRead(). */
146 inline void advanceADCStep() {
147  switch (adc_count) {
148  case 0:
149  // 6us
150  // the input pin was the last thing we read
151  input_buffer.write(getADCReading());
152  adcReadSelectedChannels(); // TODO: doesn't this stop the cycle, in case no pins to read?
153  break;
154 
155  case 1:
156  // <2us, <1us w/o receive
157  // receiveFirstControlADC();
158  startSecondADCReadOnCurrentChannel();
159  break;
160 
161  case 2:
162  // 3us
163  analog_readings[channelNumToIndex(current_channel)] = getADCReading();
164  adcStartConversion(adcPinToChannelNum(AUDIO_INPUT_PIN)); // -> result is ignored, but first thing in the next cycle, a second reading is taken.
165  break;
166 
167  }
168  adc_count++;
169 }
170 #else // no (legacy) audio input
171 /** NOTE: Triggered at CONTROL_RATE via advanceControlLoop().
172 
173 This interrupt handler cycles through all analog inputs on the adc_channels_to_read Stack,
174 doing 2 conversions on each channel but only keeping the second conversion each time,
175 because the first conversion after changing channels is often inaccurate (on atmel-based arduinos).*/
176 inline void advanceADCStep() {
177  if (!adc_count) { // i.e. first step
178  //<1us
179  startSecondADCReadOnCurrentChannel(); // discard fist - noisy - reading, start another on same pin
180  adc_count=1;
181  } else {
182  // 3us
183  analog_readings[channelNumToIndex(current_channel)] = getADCReading(); // register second reading
184  adcReadSelectedChannels(); // start first reading on next pin (if any)
185  adc_count=0;
186  }
187 }
188 #endif
189 
190 #else
191 MOZZI_ASSERT_EQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
192 
193 int mozziAnalogRead(uint8_t pin) {
194  return analogRead(pin);
195 }
196 
197 #endif // MOZZI_ANALOG_READ
198 
199 ////// END analog input code ////////
200 
201 
202 ////// BEGIN audio/control hook /////
203 static uint16_t update_control_timeout;
204 static uint16_t update_control_counter;
205 
206 inline void advanceControlLoop() {
207  if (!update_control_counter) {
208  update_control_counter = update_control_timeout;
209  updateControl();
210 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
211  adcStartReadCycle();
212 #endif
213  } else {
214  --update_control_counter;
215  }
216 }
217 
218 void audioHook() // 2us on AVR excluding updateAudio()
219 {
220 // setPin13High();
221  if (canBufferAudioOutput()) {
222  advanceControlLoop();
223  bufferAudioOutput(updateAudio());
224 
225 #if defined(LOOP_YIELD)
226  LOOP_YIELD
227 #endif
228 
229 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
230  if (audioInputAvailable()) audio_input = readAudioInput();
231 #endif
232  }
233 // Like LOOP_YIELD, but running every cycle of audioHook(), not just once per sample
234 #if defined(AUDIO_HOOK_HOOK)
235  AUDIO_HOOK_HOOK
236 #endif
237  // setPin13Low();
238 }
239 
240 // NOTE: This function counts the ticks of audio _output_, corresponding to real time elapsed.
241 // It does _not_ provide the count of the current audio frame to be generated by updateAudio(). These two things will differ, slightly,
242 // depending on the fill state of the buffer.
243 // TODO: In many - but not all - use cases, it might be more useful to provide a count of the current audio frame to be generated, however,
244 // the existing semantics have always been in place, so far.
245 unsigned long audioTicks() {
246 #if (BYPASS_MOZZI_OUTPUT_BUFFER != true)
247  return output_buffer.count();
248 #elif defined(AUDIOTICK_ADJUSTMENT)
249  return samples_written_to_buffer - (AUDIOTICK_ADJUSTMENT);
250 #else
251  return samples_written_to_buffer;
252 #endif
253 }
254 
255 unsigned long mozziMicros() { return audioTicks() * MICROS_PER_AUDIO_TICK; }
256 
257 ////// END audio/control hook /////
258 
259 ////// BEGIN initialization ///////
260 void startMozzi(int control_rate_hz) {
261 #if !MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
262  MozziPrivate::setupMozziADC(FAST_ADC); // you can use setupFastAnalogRead() with FASTER_ADC or FASTEST_ADC
263  // in setup() if desired (not for Teensy 3.* )
264 #endif
265  // delay(200); // so AutoRange doesn't read 0 to start with
266  update_control_timeout = MOZZI_AUDIO_RATE / control_rate_hz;
267  startAudio();
268 }
269 
270 uint32_t MozziRandPrivate::x=132456789;
271 uint32_t MozziRandPrivate::y=362436069;
272 uint32_t MozziRandPrivate::z=521288629;
273 
274 ////// END initialization ///////
275 }
276 
277 // reduce Macro leakage
278 #undef LOOP_YIELD
279 #undef BYPASS_MOZZI_OUTPUT_BUFFER
280 #undef AUDIO_HOOK_HOOK
281 #undef AUDIOTICK_ADJUSTMENT
282 #undef MOZZI__LEGACY_AUDIO_INPUT_IMPL
283 
284 // "export" publicly accessible functions defined in this file
285 // NOTE: unfortunately, we cannot just write using MozziPrivate::mozziMicros(), and that will conflict with, rather than define mozziMicros()
286 // we might want to rethink how this is done. What matters is that these functions are user accessible, though, while most of what we
287 // now keep in MozziPrivate is hidden away.
288 //unsigned long mozziMicros() { return MozziPrivate::mozziMicros(); };
289 unsigned long audioTicks() { return MozziPrivate::audioTicks(); };
290 void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); };
291 void stopMozzi() { MozziPrivate::stopMozzi(); };
292 int mozziAnalogRead(uint8_t pin) { return MozziPrivate::mozziAnalogRead(pin); };
293 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
294 AudioOutputStorage_t getAudioInput() { return MozziPrivate::getAudioInput(); };
295 #endif
296 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
297 void setupMozziADC(int8_t speed) { MozziPrivate::setupMozziADC(speed); };
298 void setupFastAnalogRead(int8_t speed) { MozziPrivate::setupFastAnalogRead(speed); };
299 uint8_t adcPinToChannelNum(uint8_t pin) { return MozziPrivate::adcPinToChannelNum(pin); };
300 #endif
301 void audioHook() { MozziPrivate::audioHook(); };
302 
303 // This is not strictly needed, but we want it to throw an error, if users have audioOutput() in their sketch without external output configured
304 #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
305 MOZZI_DEPRECATED("n/a", "Sketch has audioOutput() function, although external output is not configured.") void audioOutput(const AudioOutput) {};
306 #endif
307 #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
308 // TODO: This won't work without a rename:
309 //MOZZI_DEPRECATED("n/a", "Sketch has canBufferAudioOutput() function, although custom external output is not configured.") bool canBufferAudioOutput() {};
310 #endif
unsigned long mozziMicros()
An alternative for Arduino time functions like micros() and millis().
Definition: MozziGuts.hpp:255
-
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
Definition: MozziGuts.hpp:291
-
int mozziAnalogRead(uint8_t pin)
Reads the analog input of a chosen channel, without blocking other operations from running...
Definition: MozziGuts.hpp:193
-
#define IS_SAMD21()
-
#define IS_TEENSY4()
-
Circular buffer object.
-
void audioHook()
This is required in Arduino&#39;s loop().
Definition: MozziGuts.hpp:218
-
#define IS_STM32DUINO()
-
#define IS_STM32MAPLE()
-
#define IS_AVR()
- -
#define IS_TEENSY3()
-
#define IS_RP2040()
-
#define IS_MBED()
-
#define IS_RENESAS()
-
unsigned long audioTicks()
An alternative for Arduino time functions like micros() and millis().
Definition: MozziGuts.hpp:245
-
#define CACHED_FUNCTION_ATTR
-
#define IS_ESP8266()
-
#define IS_ESP32()
+
1 /*
+
2  * MozziGuts.hpp
+
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 #include <Arduino.h>
+
13 
+
14 #include "CircularBuffer.h"
+
15 #include "mozzi_analog.h"
+
16 #include "internal/mozzi_rand_p.h"
+
17 #include "AudioOutput.h"
+
18 
+
19 namespace MozziPrivate {
+
20 
+
21 // Forward declarations of functions to be provided by platform specific implementations
+
22 #if (!BYPASS_MOZZI_OUTPUT_BUFFER)
+
23 static void CACHED_FUNCTION_ATTR defaultAudioOutput();
+
24 #endif
+
25 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
26 static void advanceADCStep(); // to be provided by platform implementation
+
27 static void startSecondADCReadOnCurrentChannel(); // to be provided by platform implementation
+
28 static uint8_t adc_count = 0; // needed below
+
29 #endif
+
30 
+
31 // TODO: make this helper public?
+
32 template<byte BITS_IN, byte BITS_OUT, typename T> constexpr T smartShift(T value) {
+
33  return (BITS_IN > BITS_OUT) ? value >> (BITS_IN - BITS_OUT) : (BITS_IN < BITS_OUT) ? value << (BITS_OUT - BITS_IN) : value;
+
34 }
+
35 }
+
36 
+
37 // Include the appropriate implementation
+
38 #if IS_AVR()
+
39 # include "MozziGuts_impl_AVR.hpp"
+
40 #elif IS_STM32MAPLE()
+
41 # include "MozziGuts_impl_STM32.hpp"
+
42 #elif IS_STM32DUINO()
+
43 # include "MozziGuts_impl_STM32duino.hpp"
+
44 #elif IS_ESP32()
+
45 # include "MozziGuts_impl_ESP32.hpp"
+
46 #elif IS_ESP8266()
+
47 # include "MozziGuts_impl_ESP8266.hpp"
+
48 #elif (IS_TEENSY3() || IS_TEENSY4())
+
49 # include "MozziGuts_impl_TEENSY.hpp"
+
50 #elif (IS_SAMD21())
+
51 # include "MozziGuts_impl_SAMD.hpp"
+
52 #elif (IS_RP2040())
+
53 # include "MozziGuts_impl_RP2040.hpp"
+
54 #elif (IS_MBED())
+
55 # include "MozziGuts_impl_MBED.hpp"
+
56 #elif (IS_RENESAS())
+
57 # include "MozziGuts_impl_RENESAS.hpp"
+
58 #else
+
59 # error "Platform not (yet) supported. Check MozziGuts_impl_template.hpp and existing implementations for a blueprint for adding your favorite MCU."
+
60 #endif
+
61 
+
62 /* Retro-compatibility with "legacy" boards which use the async
+
63  ADC for getting AUDIO_INPUT
+
64 */
+
65 #if !defined(MOZZI__LEGACY_AUDIO_INPUT_IMPL)
+
66 # if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
+
67 # define MOZZI__LEGACY_AUDIO_INPUT_IMPL 1
+
68 # else
+
69 # define MOZZI__LEGACY_AUDIO_INPUT_IMPL 0
+
70 # endif
+
71 #endif
+
72 
+
73 namespace MozziPrivate {
+
74 ////// BEGIN Output buffering /////
+
75 #if BYPASS_MOZZI_OUTPUT_BUFFER == true
+ +
77 
+
78 inline void bufferAudioOutput(const AudioOutput_t f) {
+
79  audioOutput(f);
+ +
81 }
+
82 #else
+
83 CircularBuffer<AudioOutput> output_buffer; // fixed size 256
+
84 # define canBufferAudioOutput() (!output_buffer.isFull())
+
85 # define bufferAudioOutput(f) output_buffer.write(f)
+
86 static void CACHED_FUNCTION_ATTR defaultAudioOutput() {
+
87 
+
88 #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // in that case, we rely on asynchroneous ADC reads implemented for mozziAnalogRead to get the audio in samples
+
89  MOZZI_ASSERT_NOTEQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE);
+
90  adc_count = 0;
+
91  startSecondADCReadOnCurrentChannel(); // the current channel is the AUDIO_INPUT pin
+
92 # endif
+
93  audioOutput(output_buffer.read());
+
94 }
+
95 #endif // #if (AUDIO_INPUT_MODE == AUDIO_INPUT_LEGACY)
+
96 ////// END Output buffering ///////
+
97 
+
98 
+
99 ////// BEGIN Analog input code ////////
+
100 /* Analog input code was informed initially by a discussion between
+
101 jRaskell, bobgardner, theusch, Koshchi, and code by jRaskell.
+
102 http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=789581
+
103 */
+
104 
+
105 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
106 
+
107 #include "Stack.h"
+ + +
110 volatile static int8_t current_channel = -1; // volatile because accessed in control and adc ISRs
+
111 
+
112 /* gets the next channel to read off the stack, and if there is a channel there, it changes to that channel and starts a conversion.
+
113 */
+ +
115  // ugly syntax below saves a few bytes/instructions (as current_channel is declared volatile)
+ +
117 }
+
118 
+
119 /* Called each time in updateControlWithAutoADC(), after updateControl()
+
120  Forbidding inline, here, saves a wholesome 16 bytes flash on AVR (without USE_AUDIO_INPUT). No idea, why.
+
121 */
+
122 __attribute__((noinline)) void adcStartReadCycle() {
+
123  if (current_channel < 0) // last read of adc_channels_to_read stack was empty, ie. all channels from last time have been read
+
124  {
+
125 #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1) // use of async ADC for audio input
+ +
127 #else
+ +
129  adc_count = 0;
+
130 #endif
+
131  }
+
132 }
+
133 
+ +
135  pin = adcPinToChannelNum(pin); // allow for channel or pin numbers; on most platforms other than AVR this has no effect. See note on pins/channels
+ + +
138 }
+
139 
+
140 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
+
141 static uint16_t audio_input; // holds the latest audio from input_buffer
+
142 uint16_t getAudioInput() { return audio_input; }
+
143 #endif
+
144 
+
145 #if MOZZI_IS(MOZZI__LEGACY_AUDIO_INPUT_IMPL, 1)
+
146 // ring buffer for audio input
+
147 CircularBuffer<uint16_t> input_buffer; // fixed size 256
+
148 #define audioInputAvailable() (!input_buffer.isEmpty())
+
149 #define readAudioInput() (input_buffer.read())
+
150 /** NOTE: Triggered at MOZZI_AUDIO_RATE via defaultAudioOutput(). In addition to the AUDIO_INPUT_PIN, at most one reading is taken for mozziAnalogRead(). */
+
151 inline void advanceADCStep() {
+
152  switch (adc_count) {
+
153  case 0:
+
154  // 6us
+
155  // the input pin was the last thing we read
+ +
157  adcReadSelectedChannels(); // TODO: doesn't this stop the cycle, in case no pins to read?
+
158  break;
+
159 
+
160  case 1:
+
161  // <2us, <1us w/o receive
+
162  // receiveFirstControlADC();
+ +
164  break;
+
165 
+
166  case 2:
+
167  // 3us
+ +
169  adcStartConversion(adcPinToChannelNum(AUDIO_INPUT_PIN)); // -> result is ignored, but first thing in the next cycle, a second reading is taken.
+
170  break;
+
171 
+
172  }
+
173  adc_count++;
+
174 }
+
175 #else // no (legacy) audio input
+
176 /** NOTE: Triggered at CONTROL_RATE via advanceControlLoop().
+
177 
+
178 This interrupt handler cycles through all analog inputs on the adc_channels_to_read Stack,
+
179 doing 2 conversions on each channel but only keeping the second conversion each time,
+
180 because the first conversion after changing channels is often inaccurate (on atmel-based arduinos).*/
+
181 inline void advanceADCStep() {
+
182  if (!adc_count) { // i.e. first step
+
183  //<1us
+
184  startSecondADCReadOnCurrentChannel(); // discard fist - noisy - reading, start another on same pin
+
185  adc_count=1;
+
186  } else {
+
187  // 3us
+
188  analog_readings[channelNumToIndex(current_channel)] = getADCReading(); // register second reading
+
189  adcReadSelectedChannels(); // start first reading on next pin (if any)
+
190  adc_count=0;
+
191  }
+
192 }
+
193 #endif
+
194 
+
195 #else
+ +
197 
+ +
199  return analogRead(pin);
+
200 }
+
201 
+
202 #endif // MOZZI_ANALOG_READ
+
203 
+
204 ////// END analog input code ////////
+
205 
+
206 
+
207 ////// BEGIN audio/control hook /////
+ +
209 static uint16_t update_control_counter;
+
210 
+
211 inline void advanceControlLoop() {
+
212  if (!update_control_counter) {
+
213  update_control_counter = update_control_timeout;
+
214  updateControl();
+
215 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
216  adcStartReadCycle();
+
217 #endif
+
218  } else {
+
219  --update_control_counter;
+
220  }
+
221 }
+
222 
+
223 void audioHook() // 2us on AVR excluding updateAudio()
+
224 {
+
225 // setPin13High();
+
226  if (canBufferAudioOutput()) {
+
227  advanceControlLoop();
+
228  bufferAudioOutput(updateAudio());
+
229 
+
230 #if defined(LOOP_YIELD)
+
231  LOOP_YIELD
+
232 #endif
+
233 
+
234 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
+
235  if (audioInputAvailable()) audio_input = readAudioInput();
+
236 #endif
+
237  }
+
238 // Like LOOP_YIELD, but running every cycle of audioHook(), not just once per sample
+
239 #if defined(AUDIO_HOOK_HOOK)
+
240  AUDIO_HOOK_HOOK
+
241 #endif
+
242  // setPin13Low();
+
243 }
+
244 
+
245 // NOTE: This function counts the ticks of audio _output_, corresponding to real time elapsed.
+
246 // It does _not_ provide the count of the current audio frame to be generated by updateAudio(). These two things will differ, slightly,
+
247 // depending on the fill state of the buffer.
+
248 // TODO: In many - but not all - use cases, it might be more useful to provide a count of the current audio frame to be generated, however,
+
249 // the existing semantics have always been in place, so far.
+
250 unsigned long audioTicks() {
+
251 #if (BYPASS_MOZZI_OUTPUT_BUFFER != true)
+
252  return output_buffer.count();
+
253 #elif defined(AUDIOTICK_ADJUSTMENT)
+
254  return samples_written_to_buffer - (AUDIOTICK_ADJUSTMENT);
+
255 #else
+
256  return samples_written_to_buffer;
+
257 #endif
+
258 }
+
259 
+
260 unsigned long mozziMicros() { return audioTicks() * MICROS_PER_AUDIO_TICK; }
+
261 
+
262 ////// END audio/control hook /////
+
263 
+
264 ////// BEGIN initialization ///////
+
265 void startMozzi(int control_rate_hz) {
+
266 #if !MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
+
267  MozziPrivate::setupMozziADC(FAST_ADC); // you can use setupFastAnalogRead() with FASTER_ADC or FASTEST_ADC
+
268  // in setup() if desired (not for Teensy 3.* )
+
269 #endif
+
270  // delay(200); // so AutoRange doesn't read 0 to start with
+
271  update_control_timeout = MOZZI_AUDIO_RATE / control_rate_hz;
+
272  startAudio();
+
273 }
+
274 
+
275 uint32_t MozziRandPrivate::x=132456789;
+
276 uint32_t MozziRandPrivate::y=362436069;
+
277 uint32_t MozziRandPrivate::z=521288629;
+
278 
+
279 ////// END initialization ///////
+
280 }
+
281 
+
282 // reduce Macro leakage
+
283 #undef LOOP_YIELD
+
284 #undef BYPASS_MOZZI_OUTPUT_BUFFER
+
285 #undef AUDIO_HOOK_HOOK
+
286 #undef AUDIOTICK_ADJUSTMENT
+
287 #undef MOZZI__LEGACY_AUDIO_INPUT_IMPL
+
288 
+
289 // "export" publicly accessible functions defined in this file
+
290 // NOTE: unfortunately, we cannot just write "using MozziPrivate::mozziMicros()", etc. as that would conflict with, rather than define mozziMicros().
+
291 // Instead, for now, we forward the global-scope functions to their implementations inside MozziPrivate.
+
292 // We might want to rethink how this is done. What matters is that these functions are user accessible, though, while most of what we
+
293 // now keep in MozziPrivate is hidden away.
+
294 unsigned long mozziMicros() { return MozziPrivate::mozziMicros(); };
+
295 unsigned long audioTicks() { return MozziPrivate::audioTicks(); };
+
296 void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); };
+
297 void stopMozzi() { MozziPrivate::stopMozzi(); };
+
298 template<byte RES> uint16_t mozziAnalogRead(uint8_t pin) { return MozziPrivate::smartShift<MOZZI__INTERNAL_ANALOG_READ_RESOLUTION, RES>(MozziPrivate::mozziAnalogRead(pin));};
+
299 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
+
300 template<byte RES> uint16_t getAudioInput() { return MozziPrivate::smartShift<MOZZI__INTERNAL_ANALOG_READ_RESOLUTION, RES>(MozziPrivate::getAudioInput()); };
+
301 #endif
+
302 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
303 void setupMozziADC(int8_t speed) { MozziPrivate::setupMozziADC(speed); };
+
304 void setupFastAnalogRead(int8_t speed) { MozziPrivate::setupFastAnalogRead(speed); };
+
305 uint8_t adcPinToChannelNum(uint8_t pin) { return MozziPrivate::adcPinToChannelNum(pin); };
+
306 #endif
+
307 void audioHook() { MozziPrivate::audioHook(); };
+
308 
+
309 // This is not strictly needed, but we want it to throw an error, if users have audioOutput() in their sketch without external output configured
+
310 #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
311 MOZZI_DEPRECATED("n/a", "Sketch has audioOutput() function, although external output is not configured.") void audioOutput(const AudioOutput) {};
+
312 #endif
+
313 #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
314 // TODO: This won't work without a rename:
+
315 //MOZZI_DEPRECATED("n/a", "Sketch has canBufferAudioOutput() function, although custom external output is not configured.") bool canBufferAudioOutput() {};
+
316 #endif
diff --git a/extras/doc/html/_mozzi_guts__impl___a_v_r_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___a_v_r_8hpp_source.html index d01fc886d..09c29fb4a 100644 --- a/extras/doc/html/_mozzi_guts__impl___a_v_r_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___a_v_r_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_AVR.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,460 @@
MozziGuts_impl_AVR.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #include "utility/FrequencyTimer2.h"
14 #include "utility/TimerOne.h"
15 
16 #if (F_CPU != 16000000)
17 #warning
18  "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino! Results may vary with other speeds."
19 #endif
20 
21 ////// BEGIN analog input code ////////
22 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
23 extern uint8_t analog_reference;
24 
25 ISR(ADC_vect, ISR_BLOCK)
26 {
27  MozziPrivate::advanceADCStep();
28 }
29 
30 namespace MozziPrivate {
31 #define getADCReading() ADC /* officially (ADCL | (ADCH << 8)) but the compiler works it out */
32 #define channelNumToIndex(channel) channel
33 uint8_t adcPinToChannelNum(uint8_t pin) {
34 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
35  if (pin >= 54) pin -= 54; // allow for channel or pin numbers
36 #elif defined(__AVR_ATmega32U4__)
37  if (pin >= 18) pin -= 18; // allow for channel or pin numbers
38 # if defined(CORE_TEENSY) // special handling for Teensy2, which does not (did not?) have an analogPinToChannel() define (see https://github.com/sensorium/Mozzi/issues/10)
39  static const uint8_t PROGMEM adc_mapping[] = {
40  // 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8
41  0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8, 10, 11, 12, 13, 7, 6, 5, 4, 1, 0, 8
42  };
43  pin = pgm_read_byte(adc_mapping + (P));
44 # else
45  pin = analogPinToChannel(pin);
46 # endif
47 #elif defined(__AVR_ATmega1284__)
48  if (pin >= 24) pin -= 24; // allow for channel or pin numbers
49 #else
50  if (pin >= 14) pin -= 14; // allow for channel or pin numbers
51 #endif
52  return pin;
53 }
54 
55 void adcStartConversion(uint8_t channel) {
56 #if defined(__AVR_ATmega32U4__)
57  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((channel >> 3) & 0x01) << MUX5);
58 #elif defined(ADCSRB) && defined(MUX5)
59  // the MUX5 bit of ADCSRB selects whether we're reading from channels
60  // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
61  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((channel >> 3) & 0x01) << MUX5);
62 #endif
63 
64 // from wiring_analog.c:
65 // set the analog reference (high two bits of ADMUX) and select the
66 // channel (low 4 bits). this also sets ADLAR (left-adjust result)
67 // to 0 (the default).
68 #if defined(ADMUX)
69 # if defined(TEENSYDUINO) // analog_reference is not part TEENSY 2.0 codebase
70  ADMUX = (1 << REFS0) | (channel & 0x07); // TB2017 this overwrote analog_reference
71 # else
72  ADMUX = (analog_reference << 6) | (channel & 0x07);
73 # endif
74 #endif
75 #if defined(ADCSRA) && defined(ADCL)
76  // start the conversion
77  ADCSRA |= (1 << ADSC);
78 #endif
79 }
80 
81 static void startSecondADCReadOnCurrentChannel() {
82  ADCSRA |= (1 << ADSC); // start a second conversion on the current channel
83 }
84 
85 /*
86 void adcEnableInterrupt(){
87  ADCSRA |= (1 << ADIE);
88 }
89 */
90 
91 void setupMozziADC(int8_t speed) {
92  ADCSRA |= (1 << ADIE); // adc Enable Interrupt
93  adcDisconnectAllDigitalIns();
94  setupFastAnalogRead(speed);
95 }
96 
97 void setupFastAnalogRead(int8_t speed) {
98  if (speed == FAST_ADC){ // divide by 16
99  ADCSRA |= (1 << ADPS2);
100  ADCSRA &= ~(1 << ADPS1);
101  ADCSRA &= ~(1 << ADPS0);
102  } else if(speed == FASTER_ADC){ // divide by 8
103  ADCSRA &= ~(1 << ADPS2);
104  ADCSRA |= (1 << ADPS1);
105  ADCSRA |= (1 << ADPS0);
106  } else if(speed == FASTEST_ADC){ // divide by 4
107  ADCSRA &= ~(1 << ADPS2);
108  ADCSRA |= (1 << ADPS1);
109  ADCSRA &= ~(1 << ADPS0);
110  }
111 }
112 }
113 
114 #endif
115 
116 ////// END analog input code ////////
117 
118 
119 namespace MozziPrivate {
120 //// BEGIN AUDIO OUTPUT code ///////
121 /*
122 ATmega328 technical manual, Section 12.7.4:
123 The dual-slope operation [of phase correct pwm] has lower maximum operation
124 frequency than single slope operation. However, due to the symmetric feature
125 of the dual-slope PWM modes, these modes are preferred for motor control
126 applications.
127 Due to the single-slope operation, the operating frequency of the
128 fast PWM mode can be twice as high as the phase correct PWM mode that use
129 dual-slope operation. This high frequency makes the fast PWM mode well suited
130 for power regulation, rectification, and DAC applications. High frequency allows
131 physically small sized external components (coils, capacitors)..
132 
133 DAC, that's us! Fast PWM.
134 
135 PWM frequency tests
136 62500Hz, single 8 or dual 16 bits, bad aliasing
137 125000Hz dual 14 bits, sweet
138 250000Hz dual 12 bits, gritty, if you're gonna have 2 pins, have 14 bits
139 500000Hz dual 10 bits, grittier
140 16384Hz single nearly 9 bits (original mode) not bad for a single pin, but
141 carrier freq noise can be an issue
142 */
143 
144 // to store backups of timer registers so Mozzi can be stopped and pre_mozzi
145 // timer values can be restored
146 static uint8_t pre_mozzi_TCCR1A, pre_mozzi_TCCR1B, pre_mozzi_OCR1A,
147  pre_mozzi_TIMSK1;
148 
149 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
150 #if defined(TCCR2A)
151 static uint8_t pre_mozzi_TCCR2A, pre_mozzi_TCCR2B, pre_mozzi_OCR2A,
152  pre_mozzi_TIMSK2;
153 #elif defined(TCCR2)
154 static uint8_t pre_mozzi_TCCR2, pre_mozzi_OCR2, pre_mozzi_TIMSK;
155 #elif defined(TCCR4A)
156 static uint8_t pre_mozzi_TCCR4A, pre_mozzi_TCCR4B, pre_mozzi_TCCR4C,
157  pre_mozzi_TCCR4D, pre_mozzi_TCCR4E, pre_mozzi_OCR4C, pre_mozzi_TIMSK4;
158 #endif
159 #endif
160 
161 static void backupPreMozziTimer1() {
162  // backup pre-mozzi register values for pausing later
163  pre_mozzi_TCCR1A = TCCR1A;
164  pre_mozzi_TCCR1B = TCCR1B;
165  pre_mozzi_OCR1A = OCR1A;
166  pre_mozzi_TIMSK1 = TIMSK1;
167 }
168 
169 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
170 #if defined(TCCR2A)
171 static uint8_t mozzi_TCCR2A, mozzi_TCCR2B, mozzi_OCR2A, mozzi_TIMSK2;
172 #elif defined(TCCR2)
173 static uint8_t mozzi_TCCR2, mozzi_OCR2, mozzi_TIMSK;
174 #elif defined(TCCR4A)
175 static uint8_t mozzi_TCCR4A, mozzi_TCCR4B, mozzi_TCCR4C, mozzi_TCCR4D,
176  mozzi_TCCR4E, mozzi_OCR4C, mozzi_TIMSK4;
177 #endif
178 #endif
179 
180 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
181 static void startAudio() {
182  backupPreMozziTimer1();
183  Timer1.initializeCPUCycles(
184  (F_CPU/MOZZI_AUDIO_RATE)-1, // the -1 here is a result of empirical tests
185  // that showed that it brings the resulting frequency
186  // closer to what is expected.
187  // see: https://github.com/sensorium/Mozzi/pull/202
188 
189  PHASE_FREQ_CORRECT); // set period, phase and frequency correct
190  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using
191  // Timer1.attachInterrupt())
192 }
193 
194 } // namespace MozziPrivate
195 
196 ISR(TIMER1_OVF_vect, ISR_BLOCK) {
197  MozziPrivate::defaultAudioOutput();
198 }
199 
200 namespace MozziPrivate {
201 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
202 static void startAudio() {}
203 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
204 inline void audioOutput(const AudioOutput f)
205 {
206  MOZZI_AUDIO_PIN_1_REGISTER = f.l()+MOZZI_AUDIO_BIAS;
207 # if (MOZZI_AUDIO_CHANNELS > 1)
208  MOZZI_AUDIO_PIN_2_REGISTER = f.r()+MOZZI_AUDIO_BIAS;
209 # endif
210 }
211 
212 static void startAudio() {
213  backupPreMozziTimer1();
214 
215  pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); // set pin to output for audio
216 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) && (MOZZI_PWM_RATE < 32768) // Formerly known as the - long since deprecated - "STANDARD" mode
217  Timer1.initializeCPUCycles(
218  (F_CPU/MOZZI_AUDIO_RATE)-1,// the -1 here is a result of empirical tests
219  // that showed that it brings the resulting frequency
220  // closer to what is expected.
221  // see: https://github.com/sensorium/Mozzi/pull/202
222  PHASE_FREQ_CORRECT); // set period, phase and frequency correct
223 # else // Formerly known as "STANDARD_PLUS" mode
224  Timer1.initializeCPUCycles((F_CPU/MOZZI_PWM_RATE)-1, // the -1 here is a result of empirical tests
225  // that showed that it brings the resulting frequency
226  // closer to what is expected.
227  // see: https://github.com/sensorium/Mozzi/pull/202
228  FAST); // fast mode enables higher PWM rate
229 # endif
230  Timer1.pwm(MOZZI_AUDIO_PIN_1,
231  MOZZI_AUDIO_BIAS); // pwm pin, 50% of Mozzi's duty cycle, ie. 0 signal
232 # if (MOZZI_AUDIO_CHANNELS > 1)
233  pinMode(MOZZI_AUDIO_PIN_2, OUTPUT); // set pin to output for audio
234  Timer1.pwm(MOZZI_AUDIO_PIN_2, MOZZI_AUDIO_BIAS);
235 # endif
236  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using
237  // Timer1.attachInterrupt())
238 }
239 
240 } // namespace MozziPrivate
241 
242 /* Interrupt service routine moves sound data from the output buffer to the
243 Arduino output register, running at MOZZI_AUDIO_RATE. */
244 ISR(TIMER1_OVF_vect, ISR_BLOCK) {
245 # if (MOZZI_AUDIO_RATE < MOZZI_PWM_RATE) // only update every second ISR, if lower audio rate
246  static_assert(2l*MOZZI_AUDIO_RATE == MOZZI_PWM_RATE, "audio rate must the same, or exactly half of the pwm rate!");
247  static boolean alternate;
248  alternate = !alternate;
249  if (alternate) return;
250 # endif
251 
252  MozziPrivate::defaultAudioOutput();
253 }
254 
255 namespace MozziPrivate {
256 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
257 inline void audioOutput(const AudioOutput f) {
258  // read about dual pwm at
259  // http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/
260  // sketches at http://wiki.openmusiclabs.com/wiki/PWMDAC,
261  // http://wiki.openmusiclabs.com/wiki/MiniArDSP
262  // if (!output_buffer.isEmpty()){
263  //unsigned int out = output_buffer.read();
264  // 14 bit, 7 bits on each pin
265  // MOZZI_AUDIO_PIN_1_REGISTER = out >> 7; // B00111111 10000000 becomes
266  // B1111111
267  // try to avoid looping over 7 shifts - need to check timing or disassemble to
268  // see what really happens unsigned int out_high = out<<1; // B00111111
269  // 10000000 becomes B01111111 00000000
270  // MOZZI_AUDIO_PIN_1_REGISTER = out_high >> 8; // B01111111 00000000
271  // produces B01111111 MOZZI_AUDIO_PIN_1_LOW_REGISTER = out & 127;
272  /* Atmega manual, p123
273  The high byte (OCR1xH) has to be written first.
274  When the high byte I/O location is written by the CPU,
275  the TEMP Register will be updated by the value written.
276  Then when the low byte (OCR1xL) is written to the lower eight bits,
277  the high byte will be copied into the upper 8-bits of
278  either the OCR1x buffer or OCR1x Compare Register in
279  the same system clock cycle.
280  */
281  MOZZI_AUDIO_PIN_1_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_CHANNEL;
282  MOZZI_AUDIO_PIN_1_LOW_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1);
283 }
284 
285 static void setupTimer2();
286 static void startAudio() {
287  backupPreMozziTimer1();
288  // pwm on timer 1
289  pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); // set pin to output for audio, use 3.9k resistor
290  pinMode(MOZZI_AUDIO_PIN_1_LOW, OUTPUT); // set pin to output for audio, use 499k resistor
291  Timer1.initializeCPUCycles(
292  F_CPU/125000,
293  FAST); // set period for 125000 Hz fast pwm carrier frequency = 14 bits
294  Timer1.pwm(MOZZI_AUDIO_PIN_1, 0); // pwm pin, 0% duty cycle, ie. 0 signal
295  Timer1.pwm(MOZZI_AUDIO_PIN_1_LOW, 0);
296  // audio output interrupt on timer 2, sets the pwm levels of timer 1
297  setupTimer2();
298 }
299 
300 /* set up Timer 2 using modified FrequencyTimer2 library */
301 void dummy() {}
302 
303 static void backupPreMozziTimer2() {
304  // backup Timer2 register values
305 #if defined(TCCR2A)
306  pre_mozzi_TCCR2A = TCCR2A;
307  pre_mozzi_TCCR2B = TCCR2B;
308  pre_mozzi_OCR2A = OCR2A;
309  pre_mozzi_TIMSK2 = TIMSK2;
310 #elif defined(TCCR2)
311  pre_mozzi_TCCR2 = TCCR2;
312  pre_mozzi_OCR2 = OCR2;
313  pre_mozzi_TIMSK = TIMSK;
314 #elif defined(TCCR4A)
315  pre_mozzi_TCCR4B = TCCR4A;
316  pre_mozzi_TCCR4B = TCCR4B;
317  pre_mozzi_TCCR4B = TCCR4C;
318  pre_mozzi_TCCR4B = TCCR4D;
319  pre_mozzi_TCCR4B = TCCR4E;
320  pre_mozzi_OCR4C = OCR4C;
321  pre_mozzi_TIMSK4 = TIMSK4;
322 #endif
323 }
324 
325 // audio output interrupt on timer 2 (or 4 on ATMEGA32U4 cpu), sets the pwm
326 // levels of timer 2
327 static void setupTimer2() {
328  backupPreMozziTimer2(); // to reset while pausing
329  unsigned long period = F_CPU / MOZZI_AUDIO_RATE;
330  FrequencyTimer2::setPeriodCPUCycles(period);
331  FrequencyTimer2::setOnOverflow(dummy);
332  FrequencyTimer2::enable();
333 }
334 
335 } // namespace MozziPrivate
336 
337 #if defined(TIMER2_COMPA_vect)
338 ISR(TIMER2_COMPA_vect)
339 #elif defined(TIMER2_COMP_vect)
340 ISR(TIMER2_COMP_vect)
341 #elif defined(TIMER4_COMPA_vect)
342 ISR(TIMER4_COMPA_vect)
343 #else
344 #error
345  "This board does not have a hardware timer which is compatible with FrequencyTimer2"
346 void dummy_function(void)
347 #endif
348 {
349  MozziPrivate::defaultAudioOutput();
350 }
351 
352 // end of HIFI
353 
354 namespace MozziPrivate {
355 
356 #endif
357 
358 //-----------------------------------------------------------------------------------------------------------------
359 
360 
361 void stopMozzi() {
362  noInterrupts();
363 
364  // restore backed up register values
365  TCCR1A = pre_mozzi_TCCR1A;
366  TCCR1B = pre_mozzi_TCCR1B;
367  OCR1A = pre_mozzi_OCR1A;
368 
369  TIMSK1 = pre_mozzi_TIMSK1;
370 
371 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
372 #if defined(TCCR2A)
373  TCCR2A = pre_mozzi_TCCR2A;
374  TCCR2B = pre_mozzi_TCCR2B;
375  OCR2A = pre_mozzi_OCR2A;
376  TIMSK2 = pre_mozzi_TIMSK2;
377 #elif defined(TCCR2)
378  TCCR2 = pre_mozzi_TCCR2;
379  OCR2 = pre_mozzi_OCR2;
380  TIMSK = pre_mozzi_TIMSK;
381 #elif defined(TCCR4A)
382  TCCR4B = pre_mozzi_TCCR4A;
383  TCCR4B = pre_mozzi_TCCR4B;
384  TCCR4B = pre_mozzi_TCCR4C;
385  TCCR4B = pre_mozzi_TCCR4D;
386  TCCR4B = pre_mozzi_TCCR4E;
387  OCR4C = pre_mozzi_OCR4C;
388  TIMSK4 = pre_mozzi_TIMSK4;
389 #endif
390 #endif
391  interrupts();
392 }
393 
394 // Unmodified TimerOne.cpp has TIMER3_OVF_vect.
395 // Watch out if you update the library file.
396 // The symptom will be no sound.
397 // ISR(TIMER1_OVF_vect)
398 // {
399 // Timer1.isrCallback();
400 // }
401 //// END AUDIO OUTPUT code ///////
402 
403 //// BEGIN Random seeding ////////
404 #if defined (__AVR_ATmega644P__)
405 
406 // a less fancy version for gizduino (__AVR_ATmega644P__) which doesn't know INTERNAL
407 static long longRandom()
408 {
409  return ((long)analogRead(0)+63)*(analogRead(1)+97); // added offsets in case analogRead is 0
410 }
411 
412 #else
413 
414 /*
415 longRandom(), used as a seed generator, comes from:
416 http://arduino.cc/forum/index.php/topic,38091.0.html
417 // AUTHOR: Rob Tillaart
418 // PURPOSE: Simple Random functions based upon unreliable internal temp sensor
419 // VERSION: 0.1
420 // DATE: 2011-05-01
421 //
422 // Released to the public domain, use at own risk
423 //
424 */
425 static long longRandom()
426 {
427  //analogReference(INTERNAL);
428  unsigned long rv = 0;
429  for (uint8_t i=0; i< 32; i++) rv |= ((analogRead(8)+1171) & 1L) << i; // added 1171 in case analogRead is 0
430  return rv;
431 }
432 #endif
433 
434 void MozziRandPrivate::autoSeed() {
435  ADCSRA &= ~ (1 << ADIE); // adc Disable Interrupt, re-enable at end
436  // this attempt at remembering analog_reference stops it working
437  // maybe needs a delay after changing analog reference in longRandom (Arduino reference suggests this)
438  // because the analog reads return 0
439  //uint8_t analog_reference_orig = ADMUX&192; // analog_reference is high 2 bits of ADMUX, store this because longRandom sets it to internal
440  x = longRandom();
441  y = longRandom();
442  z = longRandom();
443  //analogReference(analog_reference_orig); // change back to original
444  ADCSRA |= (1 << ADIE); // adc re-Enable Interrupt
445 }
446 
447 //// END Random seeding ////////
448 }
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_AVR.hpp
+
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 #include "utility/FrequencyTimer2.h"
+
13 #include "utility/TimerOne.h"
+
14 
+
15 #if (F_CPU != 16000000)
+
16 #warning
+
17  "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino! Results may vary with other speeds."
+
18 #endif
+
19 
+
20 ////// BEGIN analog input code ////////
+
21 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
22 extern uint8_t analog_reference;
+
23 
+
24 ISR(ADC_vect, ISR_BLOCK)
+
25 {
+
26  MozziPrivate::advanceADCStep();
+
27 }
+
28 
+
29 namespace MozziPrivate {
+
30 #define getADCReading() ADC /* officially (ADCL | (ADCH << 8)) but the compiler works it out */
+
31 #define channelNumToIndex(channel) channel
+
32 uint8_t adcPinToChannelNum(uint8_t pin) {
+
33 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
+
34  if (pin >= 54) pin -= 54; // allow for channel or pin numbers
+
35 #elif defined(__AVR_ATmega32U4__)
+
36  if (pin >= 18) pin -= 18; // allow for channel or pin numbers
+
37 # if defined(CORE_TEENSY) // special handling for Teensy2, which does not (did not?) have an analogPinToChannel() define (see https://github.com/sensorium/Mozzi/issues/10)
+
38  static const uint8_t PROGMEM adc_mapping[] = {
+
39  // 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8
+
40  0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8, 10, 11, 12, 13, 7, 6, 5, 4, 1, 0, 8
+
41  };
+
42  pin = pgm_read_byte(adc_mapping + (P));
+
43 # else
+
44  pin = analogPinToChannel(pin);
+
45 # endif
+
46 #elif defined(__AVR_ATmega1284__)
+
47  if (pin >= 24) pin -= 24; // allow for channel or pin numbers
+
48 #else
+
49  if (pin >= 14) pin -= 14; // allow for channel or pin numbers
+
50 #endif
+
51  return pin;
+
52 }
+
53 
+
54 void adcStartConversion(uint8_t channel) {
+
55 #if defined(__AVR_ATmega32U4__)
+
56  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((channel >> 3) & 0x01) << MUX5);
+
57 #elif defined(ADCSRB) && defined(MUX5)
+
58  // the MUX5 bit of ADCSRB selects whether we're reading from channels
+
59  // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
+
60  ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((channel >> 3) & 0x01) << MUX5);
+
61 #endif
+
62 
+
63 // from wiring_analog.c:
+
64 // set the analog reference (high two bits of ADMUX) and select the
+
65 // channel (low 4 bits). this also sets ADLAR (left-adjust result)
+
66 // to 0 (the default).
+
67 #if defined(ADMUX)
+
68 # if defined(TEENSYDUINO) // analog_reference is not part TEENSY 2.0 codebase
+
69  ADMUX = (1 << REFS0) | (channel & 0x07); // TB2017 this overwrote analog_reference
+
70 # else
+
71  ADMUX = (analog_reference << 6) | (channel & 0x07);
+
72 # endif
+
73 #endif
+
74 #if defined(ADCSRA) && defined(ADCL)
+
75  // start the conversion
+
76  ADCSRA |= (1 << ADSC);
+
77 #endif
+
78 }
+
79 
+
80 static void startSecondADCReadOnCurrentChannel() {
+
81  ADCSRA |= (1 << ADSC); // start a second conversion on the current channel
+
82 }
+
83 
+
84 /*
+
85 void adcEnableInterrupt(){
+
86  ADCSRA |= (1 << ADIE);
+
87 }
+
88 */
+
89 
+
90 void setupMozziADC(int8_t speed) {
+
91  ADCSRA |= (1 << ADIE); // adc Enable Interrupt
+
92  adcDisconnectAllDigitalIns();
+
93  setupFastAnalogRead(speed);
+
94 }
+
95 
+
96 void setupFastAnalogRead(int8_t speed) {
+
97  if (speed == FAST_ADC){ // divide by 16
+
98  ADCSRA |= (1 << ADPS2);
+
99  ADCSRA &= ~(1 << ADPS1);
+
100  ADCSRA &= ~(1 << ADPS0);
+
101  } else if(speed == FASTER_ADC){ // divide by 8
+
102  ADCSRA &= ~(1 << ADPS2);
+
103  ADCSRA |= (1 << ADPS1);
+
104  ADCSRA |= (1 << ADPS0);
+
105  } else if(speed == FASTEST_ADC){ // divide by 4
+
106  ADCSRA &= ~(1 << ADPS2);
+
107  ADCSRA |= (1 << ADPS1);
+
108  ADCSRA &= ~(1 << ADPS0);
+
109  }
+
110 }
+
111 }
+
112 
+
113 #endif
+
114 
+
115 ////// END analog input code ////////
+
116 
+
117 
+
118 namespace MozziPrivate {
+
119 //// BEGIN AUDIO OUTPUT code ///////
+
120 /*
+
121 ATmega328 technical manual, Section 12.7.4:
+
122 The dual-slope operation [of phase correct pwm] has lower maximum operation
+
123 frequency than single slope operation. However, due to the symmetric feature
+
124 of the dual-slope PWM modes, these modes are preferred for motor control
+
125 applications.
+
126 Due to the single-slope operation, the operating frequency of the
+
127 fast PWM mode can be twice as high as the phase correct PWM mode that use
+
128 dual-slope operation. This high frequency makes the fast PWM mode well suited
+
129 for power regulation, rectification, and DAC applications. High frequency allows
+
130 physically small sized external components (coils, capacitors)..
+
131 
+
132 DAC, that's us! Fast PWM.
+
133 
+
134 PWM frequency tests
+
135 62500Hz, single 8 or dual 16 bits, bad aliasing
+
136 125000Hz dual 14 bits, sweet
+
137 250000Hz dual 12 bits, gritty, if you're gonna have 2 pins, have 14 bits
+
138 500000Hz dual 10 bits, grittier
+
139 16384Hz single nearly 9 bits (original mode) not bad for a single pin, but
+
140 carrier freq noise can be an issue
+
141 */
+
142 
+
143 // to store backups of timer registers so Mozzi can be stopped and pre_mozzi
+
144 // timer values can be restored
+
145 static uint8_t pre_mozzi_TCCR1A, pre_mozzi_TCCR1B, pre_mozzi_OCR1A,
+ +
147 
+
148 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
149 #if defined(TCCR2A)
+ + +
152 #elif defined(TCCR2)
+ +
154 #elif defined(TCCR4A)
+ + +
157 #endif
+
158 #endif
+
159 
+
160 static void backupPreMozziTimer1() {
+
161  // backup pre-mozzi register values for pausing later
+
162  pre_mozzi_TCCR1A = TCCR1A;
+
163  pre_mozzi_TCCR1B = TCCR1B;
+
164  pre_mozzi_OCR1A = OCR1A;
+
165  pre_mozzi_TIMSK1 = TIMSK1;
+
166 }
+
167 
+
168 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
169 #if defined(TCCR2A)
+ +
171 #elif defined(TCCR2)
+ +
173 #elif defined(TCCR4A)
+ + +
176 #endif
+
177 #endif
+
178 
+
179 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
180 static void startAudio() {
+ + +
183  (F_CPU/MOZZI_AUDIO_RATE)-1, // the -1 here is a result of empirical tests
+
184  // that showed that it brings the resulting frequency
+
185  // closer to what is expected.
+
186  // see: https://github.com/sensorium/Mozzi/pull/202
+
187 
+
188  PHASE_FREQ_CORRECT); // set period, phase and frequency correct
+
189  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using
+
190  // Timer1.attachInterrupt())
+
191 }
+
192 
+
193 } // namespace MozziPrivate
+
194 
+ + +
197 }
+
198 
+
199 namespace MozziPrivate {
+
200 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
201 static void startAudio() {}
+
202 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
203 inline void audioOutput(const AudioOutput f)
+
204 {
+ +
206 # if (MOZZI_AUDIO_CHANNELS > 1)
+ +
208 # endif
+
209 }
+
210 
+
211 static void startAudio() {
+ +
213 
+
214  pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); // set pin to output for audio
+
215 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) && (MOZZI_PWM_RATE < 32768) // Formerly known as the - long since deprecated - "STANDARD" mode
+ +
217  (F_CPU/MOZZI_AUDIO_RATE)-1,// the -1 here is a result of empirical tests
+
218  // that showed that it brings the resulting frequency
+
219  // closer to what is expected.
+
220  // see: https://github.com/sensorium/Mozzi/pull/202
+
221  PHASE_FREQ_CORRECT); // set period, phase and frequency correct
+
222 # else // Formerly known as "STANDARD_PLUS" mode
+
223  Timer1.initializeCPUCycles((F_CPU/MOZZI_PWM_RATE)-1, // the -1 here is a result of empirical tests
+
224  // that showed that it brings the resulting frequency
+
225  // closer to what is expected.
+
226  // see: https://github.com/sensorium/Mozzi/pull/202
+
227  FAST); // fast mode enables higher PWM rate
+
228 # endif
+ +
230  MOZZI_AUDIO_BIAS); // pwm pin, 50% of Mozzi's duty cycle, ie. 0 signal
+
231 # if (MOZZI_AUDIO_CHANNELS > 1)
+
232  pinMode(MOZZI_AUDIO_PIN_2, OUTPUT); // set pin to output for audio
+ +
234 # endif
+
235  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using
+
236  // Timer1.attachInterrupt())
+
237 }
+
238 
+
239 } // namespace MozziPrivate
+
240 
+
241 /* Interrupt service routine moves sound data from the output buffer to the
+
242 Arduino output register, running at MOZZI_AUDIO_RATE. */
+ +
244 # if (MOZZI_AUDIO_RATE < MOZZI_PWM_RATE) // only update every second ISR, if lower audio rate
+
245  static_assert(2l*MOZZI_AUDIO_RATE == MOZZI_PWM_RATE, "audio rate must the same, or exactly half of the pwm rate!");
+
246  static boolean alternate;
+
247  alternate = !alternate;
+
248  if (alternate) return;
+
249 # endif
+
250 
+ +
252 }
+
253 
+
254 namespace MozziPrivate {
+
255 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
256 inline void audioOutput(const AudioOutput f) {
+
257  // read about dual pwm at
+
258  // http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/
+
259  // sketches at http://wiki.openmusiclabs.com/wiki/PWMDAC,
+
260  // http://wiki.openmusiclabs.com/wiki/MiniArDSP
+
261  // if (!output_buffer.isEmpty()){
+
262  //unsigned int out = output_buffer.read();
+
263  // 14 bit, 7 bits on each pin
+
264  // MOZZI_AUDIO_PIN_1_REGISTER = out >> 7; // B00111111 10000000 becomes
+
265  // B1111111
+
266  // try to avoid looping over 7 shifts - need to check timing or disassemble to
+
267  // see what really happens unsigned int out_high = out<<1; // B00111111
+
268  // 10000000 becomes B01111111 00000000
+
269  // MOZZI_AUDIO_PIN_1_REGISTER = out_high >> 8; // B01111111 00000000
+
270  // produces B01111111 MOZZI_AUDIO_PIN_1_LOW_REGISTER = out & 127;
+
271  /* Atmega manual, p123
+
272  The high byte (OCR1xH) has to be written first.
+
273  When the high byte I/O location is written by the CPU,
+
274  the TEMP Register will be updated by the value written.
+
275  Then when the low byte (OCR1xL) is written to the lower eight bits,
+
276  the high byte will be copied into the upper 8-bits of
+
277  either the OCR1x buffer or OCR1x Compare Register in
+
278  the same system clock cycle.
+
279  */
+ + +
282 }
+
283 
+
284 static void setupTimer2();
+
285 static void startAudio() {
+ +
287  // pwm on timer 1
+
288  pinMode(MOZZI_AUDIO_PIN_1, OUTPUT); // set pin to output for audio, use 3.9k resistor
+
289  pinMode(MOZZI_AUDIO_PIN_1_LOW, OUTPUT); // set pin to output for audio, use 499k resistor
+ +
291  F_CPU/125000,
+
292  FAST); // set period for 125000 Hz fast pwm carrier frequency = 14 bits
+
293  Timer1.pwm(MOZZI_AUDIO_PIN_1, 0); // pwm pin, 0% duty cycle, ie. 0 signal
+ +
295  // audio output interrupt on timer 2, sets the pwm levels of timer 1
+
296  setupTimer2();
+
297 }
+
298 
+
299 /* set up Timer 2 using modified FrequencyTimer2 library */
+
300 void dummy() {}
+
301 
+
302 static void backupPreMozziTimer2() {
+
303  // backup Timer2 register values
+
304 #if defined(TCCR2A)
+ + + + +
309 #elif defined(TCCR2)
+ + + +
313 #elif defined(TCCR4A)
+ + + + + + + +
321 #endif
+
322 }
+
323 
+
324 // audio output interrupt on timer 2 (or 4 on ATMEGA32U4 cpu), sets the pwm
+
325 // levels of timer 2
+
326 static void setupTimer2() {
+
327  backupPreMozziTimer2(); // to reset while pausing
+
328  unsigned long period = F_CPU / MOZZI_AUDIO_RATE;
+ + + +
332 }
+
333 
+
334 } // namespace MozziPrivate
+
335 
+
336 #if defined(TIMER2_COMPA_vect)
+ +
338 #elif defined(TIMER2_COMP_vect)
+ +
340 #elif defined(TIMER4_COMPA_vect)
+ +
342 #else
+
343 #error
+
344  "This board does not have a hardware timer which is compatible with FrequencyTimer2"
+
345 void dummy_function(void)
+
346 #endif
+
347 {
+ +
349 }
+
350 
+
351 // end of HIFI
+
352 
+
353 namespace MozziPrivate {
+
354 
+
355 #endif
+
356 
+
357 //-----------------------------------------------------------------------------------------------------------------
+
358 
+
359 
+
360 void stopMozzi() {
+
361  noInterrupts();
+
362 
+
363  // restore backed up register values
+
364  TCCR1A = pre_mozzi_TCCR1A;
+
365  TCCR1B = pre_mozzi_TCCR1B;
+
366  OCR1A = pre_mozzi_OCR1A;
+
367 
+
368  TIMSK1 = pre_mozzi_TIMSK1;
+
369 
+
370 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
371 #if defined(TCCR2A)
+
372  TCCR2A = pre_mozzi_TCCR2A;
+
373  TCCR2B = pre_mozzi_TCCR2B;
+
374  OCR2A = pre_mozzi_OCR2A;
+
375  TIMSK2 = pre_mozzi_TIMSK2;
+
376 #elif defined(TCCR2)
+
377  TCCR2 = pre_mozzi_TCCR2;
+
378  OCR2 = pre_mozzi_OCR2;
+
379  TIMSK = pre_mozzi_TIMSK;
+
380 #elif defined(TCCR4A)
+
381  TCCR4B = pre_mozzi_TCCR4A;
+
382  TCCR4B = pre_mozzi_TCCR4B;
+
383  TCCR4B = pre_mozzi_TCCR4C;
+
384  TCCR4B = pre_mozzi_TCCR4D;
+
385  TCCR4B = pre_mozzi_TCCR4E;
+
386  OCR4C = pre_mozzi_OCR4C;
+
387  TIMSK4 = pre_mozzi_TIMSK4;
+
388 #endif
+
389 #endif
+
390  interrupts();
+
391 }
+
392 
+
393 // Unmodified TimerOne.cpp has TIMER3_OVF_vect.
+
394 // Watch out if you update the library file.
+
395 // The symptom will be no sound.
+
396 // ISR(TIMER1_OVF_vect)
+
397 // {
+
398 // Timer1.isrCallback();
+
399 // }
+
400 //// END AUDIO OUTPUT code ///////
+
401 
+
402 //// BEGIN Random seeding ////////
+
403 #if defined (__AVR_ATmega644P__)
+
404 
+
405 // a less fancy version for gizduino (__AVR_ATmega644P__) which doesn't know INTERNAL
+
406 static long longRandom()
+
407 {
+
408  return ((long)analogRead(0)+63)*(analogRead(1)+97); // added offsets in case analogRead is 0
+
409 }
+
410 
+
411 #else
+
412 
+
413 /*
+
414 longRandom(), used as a seed generator, comes from:
+
415 http://arduino.cc/forum/index.php/topic,38091.0.html
+
416 // AUTHOR: Rob Tillaart
+
417 // PURPOSE: Simple Random functions based upon unreliable internal temp sensor
+
418 // VERSION: 0.1
+
419 // DATE: 2011-05-01
+
420 //
+
421 // Released to the public domain, use at own risk
+
422 //
+
423 */
+
424 static long longRandom()
+
425 {
+
426  //analogReference(INTERNAL);
+
427  unsigned long rv = 0;
+
428  for (uint8_t i=0; i< 32; i++) rv |= ((analogRead(8)+1171) & 1L) << i; // added 1171 in case analogRead is 0
+
429  return rv;
+
430 }
+
431 #endif
+
432 
+
433 void MozziRandPrivate::autoSeed() {
+
434  ADCSRA &= ~ (1 << ADIE); // adc Disable Interrupt, re-enable at end
+
435  // this attempt at remembering analog_reference stops it working
+
436  // maybe needs a delay after changing analog reference in longRandom (Arduino reference suggests this)
+
437  // because the analog reads return 0
+
438  //uint8_t analog_reference_orig = ADMUX&192; // analog_reference is high 2 bits of ADMUX, store this because longRandom sets it to internal
+
439  x = longRandom();
+
440  y = longRandom();
+
441  z = longRandom();
+
442  //analogReference(analog_reference_orig); // change back to original
+
443  ADCSRA |= (1 << ADIE); // adc re-Enable Interrupt
+
444 }
+
445 
+
446 //// END Random seeding ////////
+
447 }
diff --git a/extras/doc/html/_mozzi_guts__impl___e_s_p32_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___e_s_p32_8hpp_source.html index 7b108d852..d28d24c00 100644 --- a/extras/doc/html/_mozzi_guts__impl___e_s_p32_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___e_s_p32_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_ESP32.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,191 @@
MozziGuts_impl_ESP32.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_ESP32())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 namespace MozziPrivate {
18 ////// BEGIN analog input code ////////
19 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
20 #error not yet implemented
21 
22 #define getADCReading() 0
23 #define channelNumToIndex(channel) channel
24 uint8_t adcPinToChannelNum(uint8_t pin) {
25  return pin;
26 }
27 void adcStartConversion(uint8_t channel) {
28 }
29 void startSecondADCReadOnCurrentChannel() {
30 }
31 void setupMozziADC(int8_t speed) {
32 }
33 void setupFastAnalogRead(int8_t speed) {
34 }
35 
36 #endif
37 ////// END analog input code ////////
38 
39 
40 //// BEGIN AUDIO OUTPUT code ///////
41 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
42 } // namespace MozziPrivate
43 # include <driver/i2s.h> // for I2S-based output modes, including - technically - internal DAC
44 namespace MozziPrivate {
45 const i2s_port_t i2s_num = MOZZI_I2S_PORT;
46 
47 // On ESP32 we cannot test wether the DMA buffer has room. Instead, we have to use a one-sample mini buffer. In each iteration we
48 // _try_ to write that sample to the DMA buffer, and if successful, we can buffer the next sample. Somewhat cumbersome, but works.
49 // TODO: Should ESP32 gain an implemenation of i2s_available(), we should switch to using that, instead.
50 static bool _esp32_can_buffer_next = true;
51 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
52 static uint16_t _esp32_prev_sample[2];
53 # define ESP_SAMPLE_SIZE (2*sizeof(uint16_t))
54 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
55 static int16_t _esp32_prev_sample[2];
56 # define ESP_SAMPLE_SIZE (2*sizeof(int16_t))
57 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
58 static uint32_t _esp32_prev_sample[PDM_RESOLUTION];
59 # define ESP_SAMPLE_SIZE (PDM_RESOLUTION*sizeof(uint32_t))
60 # endif
61 
62 inline bool esp32_tryWriteSample() {
63  size_t bytes_written;
64  i2s_write(i2s_num, &_esp32_prev_sample, ESP_SAMPLE_SIZE, &bytes_written, 0);
65  return (bytes_written != 0);
66 }
67 
68 inline bool canBufferAudioOutput() {
69  if (_esp32_can_buffer_next) return true;
70  _esp32_can_buffer_next = esp32_tryWriteSample();
71  return _esp32_can_buffer_next;
72 }
73 
74 inline void audioOutput(const AudioOutput f) {
75 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
76  _esp32_prev_sample[0] = (f.l() + MOZZI_AUDIO_BIAS) << 8;
77 # if (MOZZI_AUDIO_CHANNELS > 1)
78  _esp32_prev_sample[1] = (f.r() + MOZZI_AUDIO_BIAS) << 8;
79 # else
80  // For simplicity of code, even in mono, we're writing stereo samples
81  _esp32_prev_sample[1] = _esp32_prev_sample[0];
82 # endif
83 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
84  for (uint8_t i=0; i<MOZZI_PDM_RESOLUTION; ++i) {
85  _esp32_prev_sample[i] = pdmCode32(f.l() + MOZZI_AUDIO_BIAS);
86  }
87 # else
88  // PT8211 takes signed samples
89  _esp32_prev_sample[0] = f.l();
90  _esp32_prev_sample[1] = f.r();
91 # endif
92  _esp32_can_buffer_next = esp32_tryWriteSample();
93 }
94 #endif
95 
96 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
97 
98 } // namespace MozziPrivate
99 # include <driver/timer.h>
100 namespace MozziPrivate {
101 
102 void CACHED_FUNCTION_ATTR timer0_audio_output_isr(void *) {
103  TIMERG0.int_clr_timers.t0 = 1;
104  TIMERG0.hw_timer[0].config.alarm_en = 1;
105  defaultAudioOutput();
106 }
107 #endif
108 
109 static void startAudio() {
110 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // for external audio output, set up a timer running a audio rate
111  static intr_handle_t s_timer_handle;
112  const int div = 2;
113  timer_config_t config = {
114  .alarm_en = (timer_alarm_t)true,
115  .counter_en = (timer_start_t)false,
116  .intr_type = (timer_intr_mode_t) TIMER_INTR_LEVEL,
117  .counter_dir = TIMER_COUNT_UP,
118  .auto_reload = (timer_autoreload_t) true,
119  .divider = div // For max available precision: The APB_CLK clock signal is running at 80 MHz, i.e. 2/80 uS per tick
120  // Min acceptable value is 2
121  };
122  timer_init(TIMER_GROUP_0, TIMER_0, &config);
123  timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0);
124  timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 80000000UL / MOZZI_AUDIO_RATE / div);
125  timer_enable_intr(TIMER_GROUP_0, TIMER_0);
126  timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer0_audio_output_isr, nullptr, 0, &s_timer_handle);
127  timer_start(TIMER_GROUP_0, TIMER_0);
128 
129 #elif !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
130  static const i2s_config_t i2s_config = {
131 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
132  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
133 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
134  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
135 # endif
136  .sample_rate = MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION,
137  .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // only the top 8 bits will actually be used by the internal DAC, but using 8 bits straight away seems buggy
138  .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // always use stereo output. mono seems to be buggy, and the overhead is insignifcant on the ESP32
139  .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB), // this appears to be the correct setting for internal DAC and PT8211, but not for other dacs
140  .intr_alloc_flags = 0, // default interrupt priority
141  .dma_buf_count = 8, // 8*128 bytes of buffer corresponds to 256 samples (2 channels, see above, 2 bytes per sample per channel)
142  .dma_buf_len = 128,
143  .use_apll = false
144  };
145 
146  i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
147 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
148  static const i2s_pin_config_t pin_config = {
149  .bck_io_num = MOZZI_I2S_PIN_BCK,
150  .ws_io_num = MOZZI_I2S_PIN_WS,
151  .data_out_num = MOZZI_I2S_PIN_DATA,
152  .data_in_num = -1
153  };
154  i2s_set_pin((i2s_port_t)i2s_num, &pin_config);
155 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
156  i2s_set_pin((i2s_port_t)i2s_num, NULL);
157  i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
158 # endif
159  i2s_zero_dma_buffer((i2s_port_t)i2s_num);
160 
161 #endif
162 }
163 
164 void stopMozzi() {
165  // TODO: implement me
166 }
167 //// END AUDIO OUTPUT code ///////
168 
169 //// BEGIN Random seeding ////////
170 void MozziRandPrivate::autoSeed() {
171  x = esp_random();
172  y = esp_random();
173  z = esp_random();
174 }
175 //// END Random seeding ////////
176 
177 #undef ESP_SAMPLE_SIZE // only used inside this file
178 
179 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_ESP32.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2020-2024 Dieter Vandoren, Thomas Friedrichsmeier 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 #if !(IS_ESP32())
+
13 # error "Wrong implementation included for this platform"
+
14 #endif
+
15 
+
16 namespace MozziPrivate {
+
17 ////// BEGIN analog input code ////////
+
18 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
19 #error not yet implemented
+
20 
+
21 #define getADCReading() 0
+
22 #define channelNumToIndex(channel) channel
+ +
24  return pin;
+
25 }
+ +
27 }
+ +
29 }
+ +
31 }
+ +
33 }
+
34 
+
35 #endif
+
36 ////// END analog input code ////////
+
37 
+
38 
+
39 //// BEGIN AUDIO OUTPUT code ///////
+
40 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
+
41 } // namespace MozziPrivate
+
42 # include <driver/i2s.h> // for I2S-based output modes, including - technically - internal DAC
+
43 namespace MozziPrivate {
+ +
45 
+
46 // On ESP32 we cannot test wether the DMA buffer has room. Instead, we have to use a one-sample mini buffer. In each iteration we
+
47 // _try_ to write that sample to the DMA buffer, and if successful, we can buffer the next sample. Somewhat cumbersome, but works.
+
48 // TODO: Should ESP32 gain an implemenation of i2s_available(), we should switch to using that, instead.
+
49 static bool _esp32_can_buffer_next = true;
+
50 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+ +
52 # define ESP_SAMPLE_SIZE (2*sizeof(uint16_t))
+
53 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
+
54 static int16_t _esp32_prev_sample[2];
+
55 # define ESP_SAMPLE_SIZE (2*sizeof(int16_t))
+
56 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
+ +
58 # define ESP_SAMPLE_SIZE (PDM_RESOLUTION*sizeof(uint32_t))
+
59 # endif
+
60 
+
61 inline bool esp32_tryWriteSample() {
+ + +
64  return (bytes_written != 0);
+
65 }
+
66 
+
67 inline bool canBufferAudioOutput() {
+
68  if (_esp32_can_buffer_next) return true;
+ + +
71 }
+
72 
+
73 inline void audioOutput(const AudioOutput f) {
+
74 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
75  _esp32_prev_sample[0] = (f.l() + MOZZI_AUDIO_BIAS) << 8;
+
76 # if (MOZZI_AUDIO_CHANNELS > 1)
+
77  _esp32_prev_sample[1] = (f.r() + MOZZI_AUDIO_BIAS) << 8;
+
78 # else
+
79  // For simplicity of code, even in mono, we're writing stereo samples
+ +
81 # endif
+
82 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
+
83  for (uint8_t i=0; i<MOZZI_PDM_RESOLUTION; ++i) {
+ +
85  }
+
86 # else
+
87  // PT8211 takes signed samples
+
88  _esp32_prev_sample[0] = f.l();
+
89  _esp32_prev_sample[1] = f.r();
+
90 # endif
+ +
92 }
+
93 #endif
+
94 
+
95 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
96 
+
97 } // namespace MozziPrivate
+
98 # include <driver/timer.h>
+
99 namespace MozziPrivate {
+
100 
+ + + + +
105 }
+
106 #endif
+
107 
+
108 static void startAudio() {
+
109 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // for external audio output, set up a timer running a audio rate
+
110  static intr_handle_t s_timer_handle;
+
111  const int div = 2;
+
112  timer_config_t config = {
+
113  .alarm_en = (timer_alarm_t)true,
+
114  .counter_en = (timer_start_t)false,
+
115  .intr_type = (timer_intr_mode_t) TIMER_INTR_LEVEL,
+
116  .counter_dir = TIMER_COUNT_UP,
+
117  .auto_reload = (timer_autoreload_t) true,
+
118  .divider = div // For max available precision: The APB_CLK clock signal is running at 80 MHz, i.e. 2/80 uS per tick
+
119  // Min acceptable value is 2
+
120  };
+
121  timer_init(TIMER_GROUP_0, TIMER_0, &config);
+
122  timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0);
+
123  timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 80000000UL / MOZZI_AUDIO_RATE / div);
+
124  timer_enable_intr(TIMER_GROUP_0, TIMER_0);
+
125  timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer0_audio_output_isr, nullptr, 0, &s_timer_handle);
+
126  timer_start(TIMER_GROUP_0, TIMER_0);
+
127 
+
128 #elif !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
129  static const i2s_config_t i2s_config = {
+
130 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
+
131  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
+
132 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
133  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
+
134 # endif
+
135  .sample_rate = MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION,
+
136  .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // only the top 8 bits will actually be used by the internal DAC, but using 8 bits straight away seems buggy
+
137  .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // always use stereo output. mono seems to be buggy, and the overhead is insignifcant on the ESP32
+
138  .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB), // this appears to be the correct setting for internal DAC and PT8211, but not for other dacs
+
139  .intr_alloc_flags = 0, // default interrupt priority
+
140  .dma_buf_count = 8, // 8*128 bytes of buffer corresponds to 256 samples (2 channels, see above, 2 bytes per sample per channel)
+
141  .dma_buf_len = 128,
+
142  .use_apll = false
+
143  };
+
144 
+
145  i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
+
146 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
+
147  static const i2s_pin_config_t pin_config = {
+
148  .bck_io_num = MOZZI_I2S_PIN_BCK,
+
149  .ws_io_num = MOZZI_I2S_PIN_WS,
+
150  .data_out_num = MOZZI_I2S_PIN_DATA,
+
151  .data_in_num = -1
+
152  };
+
153  i2s_set_pin((i2s_port_t)i2s_num, &pin_config);
+
154 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
155  i2s_set_pin((i2s_port_t)i2s_num, NULL);
+
156  i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
+
157 # endif
+
158  i2s_zero_dma_buffer((i2s_port_t)i2s_num);
+
159 
+
160 #endif
+
161 }
+
162 
+
163 void stopMozzi() {
+
164  // TODO: implement me
+
165 }
+
166 //// END AUDIO OUTPUT code ///////
+
167 
+
168 //// BEGIN Random seeding ////////
+
169 void MozziRandPrivate::autoSeed() {
+
170  x = esp_random();
+
171  y = esp_random();
+
172  z = esp_random();
+
173 }
+
174 //// END Random seeding ////////
+
175 
+
176 #undef ESP_SAMPLE_SIZE // only used inside this file
+
177 
+
178 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl___e_s_p8266_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___e_s_p8266_8hpp_source.html index db3b8e9b7..c97367de7 100644 --- a/extras/doc/html/_mozzi_guts__impl___e_s_p8266_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___e_s_p8266_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_ESP8266.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,170 @@
MozziGuts_impl_ESP8266.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_ESP8266())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 namespace MozziPrivate {
18 
19 ////// BEGIN analog input code ////////
20 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
21 #error not yet implemented
22 
23 #define getADCReading() 0
24 #define channelNumToIndex(channel) channel
25 uint8_t adcPinToChannelNum(uint8_t pin) {
26  return pin;
27 }
28 void adcStartConversion(uint8_t channel) {
29 }
30 void startSecondADCReadOnCurrentChannel() {
31 }
32 void setupMozziADC(int8_t speed) {
33 }
34 void setupFastAnalogRead(int8_t speed) {
35 }
36 #endif
37 ////// END analog input code ////////
38 
39 //// BEGIN AUDIO OUTPUT code ///////
40 #define LOOP_YIELD yield();
41 
42 } // namespace MozziPrivate
43 #include <uart.h>
44 #include <I2S.h>
45 namespace MozziPrivate {
46 uint16_t output_buffer_size = 0;
47 
48 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC) // i.e. not external
49 
50 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
51 } // namespace MozziPrivate
52 # include <i2s.h>
53 namespace MozziPrivate {
54 inline bool canBufferAudioOutput() {
55  return (i2s_available() >= MOZZI_PDM_RESOLUTION);
56 }
57 inline void audioOutput(const AudioOutput f) {
58  for (uint8_t words = 0; words < MOZZI_PDM_RESOLUTION; ++words) {
59  i2s_write_sample(pdmCode32(f.l()+MOZZI_AUDIO_BIAS));
60  }
61 }
62 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
63 } // namespace MozziPrivate
64 # include <i2s.h>
65 namespace MozziPrivate {
66 inline bool canBufferAudioOutput() {
67  return (i2s_available() >= MOZZI_PDM_RESOLUTION);
68 }
69 inline void audioOutput(const AudioOutput f) {
70  i2s_write_lr(f.l(), f.r()); // Note: i2s_write expects zero-centered output
71 }
72 # else
73 MOZZI_ASSERT_EQUAL(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
74 // NOTE: This intermediate step is needed because the output timer is running at a rate higher than MOZZI_AUDIO_RATE, and we need to rely on the (tiny)
75 // serial buffer itself to achieve appropriate rate control
76 void CACHED_FUNCTION_ATTR esp8266_serial_audio_output() {
77  // Note: That unreadble mess is an optimized version of Serial1.availableForWrite()
78  while ((UART_TX_FIFO_SIZE - ((U1S >> USTXC) & 0xff)) > (MOZZI_PDM_RESOLUTION * 4)) {
79  defaultAudioOutput();
80  }
81 }
82 
83 inline void audioOutput(const AudioOutput f) {
84  // optimized version of: Serial1.write(...);
85  for (uint8_t i = 0; i < MOZZI_PDM_RESOLUTION*4; ++i) {
86  U1F = pdmCode8(f.l()+MOZZI_AUDIO_BIAS);
87  }
88 }
89 # endif
90 #endif
91 
92 static void startAudio() {
93 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // for external audio output, set up a timer running a audio rate
94  timer1_isr_init();
95  timer1_attachInterrupt(defaultAudioOutput);
96  timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP);
97  timer1_write(F_CPU / MOZZI_AUDIO_RATE);
98 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
99  Serial1.begin(
100  MOZZI_AUDIO_RATE * (MOZZI_PDM_RESOLUTION * 40), SERIAL_8N1,
101  SERIAL_TX_ONLY); // Note: PDM_RESOLUTION corresponds to packets of 32
102  // encoded bits However, the UART (unfortunately) adds a
103  // start and stop bit each around each byte, thus sending
104  // a total to 40 bits per audio sample per
105  // PDM_RESOLUTION.
106  // set up a timer to copy from Mozzi output_buffer into Serial TX buffer
107  timer1_isr_init();
108  timer1_attachInterrupt(esp8266_serial_audio_output);
109  // UART FIFO buffer size is 128 bytes. To be on the safe side, we keep the
110  // interval to the time needed to write half of that. PDM_RESOLUTION * 4 bytes
111  // per sample written.
112  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
113  timer1_write(F_CPU / (MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION));
114 #else
115  i2s_begin();
116 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
117  pinMode(2, INPUT); // Set the two unneeded I2S pins to input mode, to reduce
118  // side effects
119  pinMode(15, INPUT);
120 # endif
121  i2s_set_rate(MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION);
122  if (output_buffer_size == 0)
123  output_buffer_size =
124  i2s_available(); // Do not reset count when stopping / restarting
125 #endif
126 }
127 
128 
129 void stopMozzi() {
130 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC)
131  i2s_end();
132 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_EXTERNAL_TIMED)
133  timer1_disable();
134 #endif
135  interrupts();
136 }
137 
138 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) && (MOZZI_PDM_RESOLUTION != 1)
139 # define AUDIOTICK_ADJUSTMENT ((output_buffer_size - i2s_available()) / MOZZI_PDM_RESOLUTION)
140 #else
141 # define AUDIOTICK_ADJUSTMENT (output_buffer_size - i2s_available())
142 #endif
143 
144 //// END AUDIO OUTPUT code ///////
145 
146 //// BEGIN Random seeding ////////
147 } //namespace MozziPrivate
148 #include <esp8266_peri.h>
149 namespace MozziPrivate {
150 void MozziRandPrivate::autoSeed() {
151  x = RANDOM_REG32;
152  // TODO: The XORs may not be needed, but for lack of documentation (that I could find), let's assume RANDOM_REG32
153  // itself might not get updated on every read. NOTE: x, y, and z are initialized to non-zero, before this.
154  y = y ^ RANDOM_REG32;
155  z = z ^ RANDOM_REG32;
156 }
157 //// END Random seeding ////////
158 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_ESP8266.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2020-2024 Thomas Friedrichsmeier 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 #if !(IS_ESP8266())
+
13 # error "Wrong implementation included for this platform"
+
14 #endif
+
15 
+
16 namespace MozziPrivate {
+
17 
+
18 ////// BEGIN analog input code ////////
+
19 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
20 #error not yet implemented
+
21 
+
22 #define getADCReading() 0
+
23 #define channelNumToIndex(channel) channel
+ +
25  return pin;
+
26 }
+ +
28 }
+ +
30 }
+ +
32 }
+ +
34 }
+
35 #endif
+
36 ////// END analog input code ////////
+
37 
+
38 //// BEGIN AUDIO OUTPUT code ///////
+
39 #define LOOP_YIELD yield();
+
40 
+
41 } // namespace MozziPrivate
+
42 #include <uart.h>
+
43 #include <I2S.h>
+
44 namespace MozziPrivate {
+
45 uint16_t output_buffer_size = 0;
+
46 
+
47 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC) // i.e. not external
+
48 
+
49 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
+
50 } // namespace MozziPrivate
+
51 # include <i2s.h>
+
52 namespace MozziPrivate {
+
53 inline bool canBufferAudioOutput() {
+
54  return (i2s_available() >= MOZZI_PDM_RESOLUTION);
+
55 }
+
56 inline void audioOutput(const AudioOutput f) {
+
57  for (uint8_t words = 0; words < MOZZI_PDM_RESOLUTION; ++words) {
+ +
59  }
+
60 }
+
61 # elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
+
62 } // namespace MozziPrivate
+
63 # include <i2s.h>
+
64 namespace MozziPrivate {
+
65 inline bool canBufferAudioOutput() {
+
66  return (i2s_available() >= MOZZI_PDM_RESOLUTION);
+
67 }
+
68 inline void audioOutput(const AudioOutput f) {
+
69  i2s_write_lr(f.l(), f.r()); // Note: i2s_write expects zero-centered output
+
70 }
+
71 # else
+ +
73 // NOTE: This intermediate step is needed because the output timer is running at a rate higher than MOZZI_AUDIO_RATE, and we need to rely on the (tiny)
+
74 // serial buffer itself to achieve appropriate rate control
+ +
76  // Note: That unreadble mess is an optimized version of Serial1.availableForWrite()
+
77  while ((UART_TX_FIFO_SIZE - ((U1S >> USTXC) & 0xff)) > (MOZZI_PDM_RESOLUTION * 4)) {
+ +
79  }
+
80 }
+
81 
+
82 inline void audioOutput(const AudioOutput f) {
+
83  // optimized version of: Serial1.write(...);
+
84  for (uint8_t i = 0; i < MOZZI_PDM_RESOLUTION*4; ++i) {
+ +
86  }
+
87 }
+
88 # endif
+
89 #endif
+
90 
+
91 static void startAudio() {
+
92 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) // for external audio output, set up a timer running a audio rate
+
93  timer1_isr_init();
+
94  timer1_attachInterrupt(defaultAudioOutput);
+
95  timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP);
+
96  timer1_write(F_CPU / MOZZI_AUDIO_RATE);
+
97 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
+
98  Serial1.begin(
+
99  MOZZI_AUDIO_RATE * (MOZZI_PDM_RESOLUTION * 40), SERIAL_8N1,
+
100  SERIAL_TX_ONLY); // Note: PDM_RESOLUTION corresponds to packets of 32
+
101  // encoded bits However, the UART (unfortunately) adds a
+
102  // start and stop bit each around each byte, thus sending
+
103  // a total to 40 bits per audio sample per
+
104  // PDM_RESOLUTION.
+
105  // set up a timer to copy from Mozzi output_buffer into Serial TX buffer
+
106  timer1_isr_init();
+
107  timer1_attachInterrupt(esp8266_serial_audio_output);
+
108  // UART FIFO buffer size is 128 bytes. To be on the safe side, we keep the
+
109  // interval to the time needed to write half of that. PDM_RESOLUTION * 4 bytes
+
110  // per sample written.
+
111  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
+
112  timer1_write(F_CPU / (MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION));
+
113 #else
+
114  i2s_begin();
+
115 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
+
116  pinMode(2, INPUT); // Set the two unneeded I2S pins to input mode, to reduce
+
117  // side effects
+
118  pinMode(15, INPUT);
+
119 # endif
+
120  i2s_set_rate(MOZZI_AUDIO_RATE * MOZZI_PDM_RESOLUTION);
+
121  if (output_buffer_size == 0)
+
122  output_buffer_size =
+
123  i2s_available(); // Do not reset count when stopping / restarting
+
124 #endif
+
125 }
+
126 
+
127 
+
128 void stopMozzi() {
+
129 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC)
+
130  i2s_end();
+
131 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
132  timer1_disable();
+
133 #endif
+
134  interrupts();
+
135 }
+
136 
+
137 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S) && (MOZZI_PDM_RESOLUTION != 1)
+
138 # define AUDIOTICK_ADJUSTMENT ((output_buffer_size - i2s_available()) / MOZZI_PDM_RESOLUTION)
+
139 #else
+
140 # define AUDIOTICK_ADJUSTMENT (output_buffer_size - i2s_available())
+
141 #endif
+
142 
+
143 //// END AUDIO OUTPUT code ///////
+
144 
+
145 //// BEGIN Random seeding ////////
+
146 } //namespace MozziPrivate
+
147 #include <esp8266_peri.h>
+
148 namespace MozziPrivate {
+
149 void MozziRandPrivate::autoSeed() {
+
150  x = RANDOM_REG32;
+
151  // TODO: The XORs may not be needed, but for lack of documentation (that I could find), let's assume RANDOM_REG32
+
152  // itself might not get updated on every read. NOTE: x, y, and z are initialized to non-zero, before this.
+
153  y = y ^ RANDOM_REG32;
+
154  z = z ^ RANDOM_REG32;
+
155 }
+
156 //// END Random seeding ////////
+
157 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl___m_b_e_d_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___m_b_e_d_8hpp_source.html index afc32e0f0..4727aca14 100644 --- a/extras/doc/html/_mozzi_guts__impl___m_b_e_d_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___m_b_e_d_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_MBED.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,255 @@
MozziGuts_impl_MBED.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_MBED())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 #define CHUNKSIZE 64
18 
19 namespace MozziPrivate {
20 
21 ////// BEGIN analog input code ////////
22 
23 #if MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_STANDARD)
24 #define MOZZI__LEGACY_AUDIO_INPUT_IMPL 0
25 
26 } // namespace MozziPrivate
27 #include <Arduino_AdvancedAnalog.h>
28 namespace MozziPrivate {
29 
30 AdvancedADC adc(MOZZI_AUDIO_INPUT_PIN);
31 Sample inbuf[CHUNKSIZE];
32 int inbufpos=0;
33 
34 bool audioInputAvailable() {
35  if (inbufpos >= CHUNKSIZE) {
36  if (!adc.available()) return false;
37  SampleBuffer buf = adc.read();
38  memcpy(inbuf,buf.data(), CHUNKSIZE*sizeof(Sample));
39  inbufpos = 0;
40  buf.release();
41  return true;
42  }
43  else return true;
44 }
45 AudioOutputStorage_t readAudioInput(){
46  return inbuf[inbufpos++];
47 }
48 
49 
50 static void startAudioInput() {
51  if (!adc.begin(AN_RESOLUTION_12, MOZZI_AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) {
52  Serial.println("Failed to start analog acquisition!");
53  while (1);
54  }
55 }
56 #else
57 static void startAudioInput() {}; // dummy to ease coding
58 #endif
59 
60 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
61 #error not yet implemented
62 /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of USE_AUDIO_INPUT (if enabled).
63  * This template provides empty/dummy implementations to allow you to skip over this section, initially. Once you have an implementation, be sure to enable the
64  * #define, above */
65 
66 // Insert here code to read the result of the latest asynchronous conversion, when it is finished.
67 // You can also provide this as a function returning unsigned int, should it be more complex on your platform
68 #define getADCReading() 0
69 
70 /** NOTE: On "pins" vs. "channels" vs. "indices"
71  * "Pin" is the pin number as would usually be specified by the user in mozziAnalogRead().
72  * "Channel" is an internal ADC channel number corresponding to that pin. On many platforms this is simply the same as the pin number, on others it differs.
73  * In other words, this is an internal representation of "pin".
74  * "Index" is the index of the reading for a certain pin/channel in the array of analog_readings, ranging from 0 to NUM_ANALOG_PINS. This, again may be the
75  * same as "channel" (e.g. on AVR), however, on platforms where ADC-capable "channels" are not numbered sequentially starting from 0, the channel needs
76  * to be converted to a suitable index.
77  *
78  * In summary, the semantics are roughly
79  * mozziAnalogRead(pin) -> _ADCimplementation_(channel) -> analog_readings[index]
80  * Implement adcPinToChannelNum() and channelNumToIndex() to perform the appropriate mapping.
81  */
82 // NOTE: Theoretically, adcPinToChannelNum is public API for historical reasons, thus cannot be replaced by a define
83 uint8_t adcPinToChannelNum(uint8_t pin) {
84  return pin;
85 }
86 
87 /** NOTE: Code needed to trigger a conversion on a new channel */
88 void adcStartConversion(uint8_t channel) {
89 }
90 
91 /** NOTE: Code needed to trigger a subsequent conversion on the latest channel. If your platform has no special code for it, you should store the channel from
92  * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */
93 void startSecondADCReadOnCurrentChannel() {
94 }
95 
96 /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize.
97  * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */
98 void setupFastAnalogRead(int8_t speed) {
99 }
100 
101 /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and
102  * possibly calibration. */
103 void setupMozziADC(int8_t speed) {
104 }
105 
106 #endif
107 
108 ////// END analog input code ////////
109 
110 ////// BEGIN audio output code //////
111 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
112 
113 #define US_PER_AUDIO_TICK (1000000L / MOZZI_AUDIO_RATE)
114 } // namespace MozziPrivate
115 #include <mbed.h>
116 namespace MozziPrivate {
117 mbed::Ticker audio_output_timer;
118 
119 volatile bool audio_output_requested = false;
120 inline void defaultAudioOutputCallback() {
121  audio_output_requested = true;
122 }
123 
124 #define AUDIO_HOOK_HOOK { if (audio_output_requested) { audio_output_requested = false; defaultAudioOutput(); } }
125 
126 static void startAudio() {
127  audio_output_timer.attach_us(&defaultAudioOutputCallback, US_PER_AUDIO_TICK);
128  startAudioInput();
129 }
130 
131 void stopMozzi() {
132  audio_output_timer.detach();
133 }
134 
135 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
136 
137 } // namespace MozziPrivate
138 #include <Arduino_AdvancedAnalog.h>
139 namespace MozziPrivate {
140 
141 AdvancedDAC dac1(MOZZI_AUDIO_PIN_1);
142 Sample buf1[CHUNKSIZE];
143 #if (MOZZI_AUDIO_CHANNELS > 1)
144 AdvancedDAC dac2(MOZZI_AUDIO_PIN_2);
145 Sample buf2[CHUNKSIZE];
146 #endif
147 int bufpos = 0;
148 
149 inline void commitBuffer(Sample buffer[], AdvancedDAC &dac) {
150  SampleBuffer dmabuf = dac.dequeue();
151  // NOTE: Yes, this is silly code, and originated as an accident. Somehow it appears to help _a little_ against current problem wrt DAC stability
152  for (unsigned int i=0;i<CHUNKSIZE;i++) memcpy(dmabuf.data(), buffer, CHUNKSIZE*sizeof(Sample));
153  dac.write(dmabuf);
154 }
155 
156 inline void audioOutput(const AudioOutput f) {
157  if (bufpos >= CHUNKSIZE) {
158  commitBuffer(buf1, dac1);
159 #if (MOZZI_AUDIO_CHANNELS > 1)
160  commitBuffer(buf2, dac2);
161 #endif
162  bufpos = 0;
163  }
164  buf1[bufpos] = f.l()+MOZZI_AUDIO_BIAS;
165 #if (MOZZI_AUDIO_CHANNELS > 1)
166  buf2[bufpos] = f.r()+MOZZI_AUDIO_BIAS;
167 #endif
168  ++bufpos;
169 }
170 
171 bool canBufferAudioOutput() {
172  return (bufpos < CHUNKSIZE || (dac1.available()
173 #if (MOZZI_AUDIO_CHANNELS > 1)
174  && dac2.available()
175 #endif
176  ));
177 }
178 
179 static void startAudio() {
180  //NOTE: DAC setup currently affected by https://github.com/arduino-libraries/Arduino_AdvancedAnalog/issues/35 . Don't expect this to work, until using a fixed version fo Arduino_AdvancedAnalog!
181  if (!dac1.begin(AN_RESOLUTION_12, MOZZI_AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) {
182  Serial.println("Failed to start DAC1 !");
183  while (1);
184  }
185 #if (MOZZI_AUDIO_CHANNELS > 1)
186  if (!dac2.begin(AN_RESOLUTION_12, MOZZI_AUDIO_RATE, CHUNKSIZE, 256/CHUNKSIZE)) {
187  Serial.println("Failed to start DAC2 !");
188  while (1);
189  }
190 #endif
191  startAudioInput();
192 }
193 
194 void stopMozzi() {
195  dac1.stop();
196 #if (MOZZI_AUDIO_CHANNELS > 1)
197  dac2.stop();
198 #endif
199 }
200 
201 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
202 
203 } // namespace MozziPrivate
204 #include <mbed.h>
205 namespace MozziPrivate {
206 
207 mbed::BufferedSerial serial_out1(digitalPinToPinName(MOZZI_SERIAL_PIN_TX), digitalPinToPinName(MOZZI_SERIAL_PIN_RX));
208 uint8_t buf[MOZZI_PDM_RESOLUTION*4];
209 
210 bool canBufferAudioOutput() {
211  return serial_out1.writable();
212 }
213 
214 inline void audioOutput(const AudioOutput f) {
215  for (uint8_t i = 0; i < MOZZI_PDM_RESOLUTION*4; ++i) {
216  buf[i] = pdmCode8(f.l()+MOZZI_AUDIO_BIAS);
217  }
218  serial_out1.write(&buf, MOZZI_PDM_RESOLUTION*4);
219 }
220 
221 static void startAudio() {
222  serial_out1.set_baud(MOZZI_AUDIO_RATE*MOZZI_PDM_RESOLUTION*40); // NOTE: 40 == 4 * (8 bits + stop-bits)
223  serial_out1.set_format(8, mbed::BufferedSerial::None, 1);
224 }
225 
226 void stopMozzi() {
227 #warning implement me
228 }
229 
230 
231 #endif
232 ////// END audio output code //////
233 
234 //// BEGIN Random seeding ////////
235 void MozziRandPrivate::autoSeed() {
236 #warning Automatic random seeding is not implemented on this platform
237 }
238 //// END Random seeding ////////
239 
240 } // namespace MozziPrivate
241 
242 #undef CHUNKSIZE
243 #undef US_PER_AUDIO_TICK
+
1 /*
+
2  * MozziGuts_impl_MBED.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 T. Combriat 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 #if !(IS_MBED())
+
13 # error "Wrong implementation included for this platform"
+
14 #endif
+
15 
+
16 #define CHUNKSIZE 64
+
17 
+
18 namespace MozziPrivate {
+
19 
+
20 ////// BEGIN analog input code ////////
+
21 
+
22 #if MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_STANDARD)
+
23 #define MOZZI__LEGACY_AUDIO_INPUT_IMPL 0
+
24 
+
25 } // namespace MozziPrivate
+
26 #include <Arduino_AdvancedAnalog.h>
+
27 namespace MozziPrivate {
+
28 
+ + +
31 int inbufpos=0;
+
32 
+
33 bool audioInputAvailable() {
+
34  if (inbufpos >= CHUNKSIZE) {
+
35  if (!adc.available()) return false;
+ +
37  memcpy(inbuf,buf.data(), CHUNKSIZE*sizeof(Sample));
+
38  inbufpos = 0;
+
39  buf.release();
+
40  return true;
+
41  }
+
42  else return true;
+
43 }
+ +
45  return inbuf[inbufpos++];
+
46 }
+
47 
+
48 
+
49 static void startAudioInput() {
+ +
51  Serial.println("Failed to start analog acquisition!");
+
52  while (1);
+
53  }
+
54 }
+
55 #else
+
56 static void startAudioInput() {}; // dummy to ease coding
+
57 #endif
+
58 
+
59 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
60 #error not yet implemented
+
61 /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of USE_AUDIO_INPUT (if enabled).
+
62  * This template provides empty/dummy implementations to allow you to skip over this section, initially. Once you have an implementation, be sure to enable the
+
63  * #define, above */
+
64 
+
65 // Insert here code to read the result of the latest asynchronous conversion, when it is finished.
+
66 // You can also provide this as a function returning unsigned int, should it be more complex on your platform
+
67 #define getADCReading() 0
+
68 
+
69 /** NOTE: On "pins" vs. "channels" vs. "indices"
+
70  * "Pin" is the pin number as would usually be specified by the user in mozziAnalogRead().
+
71  * "Channel" is an internal ADC channel number corresponding to that pin. On many platforms this is simply the same as the pin number, on others it differs.
+
72  * In other words, this is an internal representation of "pin".
+
73  * "Index" is the index of the reading for a certain pin/channel in the array of analog_readings, ranging from 0 to NUM_ANALOG_PINS. This, again may be the
+
74  * same as "channel" (e.g. on AVR), however, on platforms where ADC-capable "channels" are not numbered sequentially starting from 0, the channel needs
+
75  * to be converted to a suitable index.
+
76  *
+
77  * In summary, the semantics are roughly
+
78  * mozziAnalogRead(pin) -> _ADCimplementation_(channel) -> analog_readings[index]
+
79  * Implement adcPinToChannelNum() and channelNumToIndex() to perform the appropriate mapping.
+
80  */
+
81 // NOTE: Theoretically, adcPinToChannelNum is public API for historical reasons, thus cannot be replaced by a define
+ +
83  return pin;
+
84 }
+
85 
+
86 /** NOTE: Code needed to trigger a conversion on a new channel */
+ +
88 }
+
89 
+
90 /** NOTE: Code needed to trigger a subsequent conversion on the latest channel. If your platform has no special code for it, you should store the channel from
+
91  * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */
+ +
93 }
+
94 
+
95 /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize.
+
96  * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */
+ +
98 }
+
99 
+
100 /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and
+
101  * possibly calibration. */
+
102 void setupMozziADC(int8_t speed) {
+
103 }
+
104 
+
105 #endif
+
106 
+
107 ////// END analog input code ////////
+
108 
+
109 ////// BEGIN audio output code //////
+
110 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
111 
+
112 #define US_PER_AUDIO_TICK (1000000L / MOZZI_AUDIO_RATE)
+
113 } // namespace MozziPrivate
+
114 #include <mbed.h>
+
115 namespace MozziPrivate {
+ +
117 
+
118 volatile bool audio_output_requested = false;
+
119 inline void defaultAudioOutputCallback() {
+
120  audio_output_requested = true;
+
121 }
+
122 
+
123 #define AUDIO_HOOK_HOOK { if (audio_output_requested) { audio_output_requested = false; defaultAudioOutput(); } }
+
124 
+
125 static void startAudio() {
+ +
127  startAudioInput();
+
128 }
+
129 
+
130 void stopMozzi() {
+ +
132 }
+
133 
+
134 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
135 
+
136 } // namespace MozziPrivate
+
137 #include <Arduino_AdvancedAnalog.h>
+
138 namespace MozziPrivate {
+
139 
+ + +
142 #if (MOZZI_AUDIO_CHANNELS > 1)
+ + +
145 #endif
+
146 int bufpos = 0;
+
147 
+
148 inline void commitBuffer(Sample buffer[], AdvancedDAC &dac) {
+ +
150  // NOTE: Yes, this is silly code, and originated as an accident. Somehow it appears to help _a little_ against current problem wrt DAC stability
+
151  for (unsigned int i=0;i<CHUNKSIZE;i++) memcpy(dmabuf.data(), buffer, CHUNKSIZE*sizeof(Sample));
+
152  dac.write(dmabuf);
+
153 }
+
154 
+
155 inline void audioOutput(const AudioOutput f) {
+
156  if (bufpos >= CHUNKSIZE) {
+ +
158 #if (MOZZI_AUDIO_CHANNELS > 1)
+ +
160 #endif
+
161  bufpos = 0;
+
162  }
+ +
164 #if (MOZZI_AUDIO_CHANNELS > 1)
+ +
166 #endif
+
167  ++bufpos;
+
168 }
+
169 
+
170 bool canBufferAudioOutput() {
+
171  return (bufpos < CHUNKSIZE || (dac1.available()
+
172 #if (MOZZI_AUDIO_CHANNELS > 1)
+
173  && dac2.available()
+
174 #endif
+
175  ));
+
176 }
+
177 
+
178 static void startAudio() {
+
179  //NOTE: DAC setup currently affected by https://github.com/arduino-libraries/Arduino_AdvancedAnalog/issues/35 . Don't expect this to work, until using a fixed version fo Arduino_AdvancedAnalog!
+ +
181  Serial.println("Failed to start DAC1 !");
+
182  while (1);
+
183  }
+
184 #if (MOZZI_AUDIO_CHANNELS > 1)
+ +
186  Serial.println("Failed to start DAC2 !");
+
187  while (1);
+
188  }
+
189 #endif
+
190  startAudioInput();
+
191 }
+
192 
+
193 void stopMozzi() {
+
194  dac1.stop();
+
195 #if (MOZZI_AUDIO_CHANNELS > 1)
+
196  dac2.stop();
+
197 #endif
+
198 }
+
199 
+
200 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
+
201 
+
202 } // namespace MozziPrivate
+
203 #include <mbed.h>
+
204 namespace MozziPrivate {
+
205 
+ + +
208 
+
209 bool canBufferAudioOutput() {
+
210  return serial_out1.writable();
+
211 }
+
212 
+
213 inline void audioOutput(const AudioOutput f) {
+
214  for (uint8_t i = 0; i < MOZZI_PDM_RESOLUTION*4; ++i) {
+ +
216  }
+ +
218 }
+
219 
+
220 static void startAudio() {
+
221  serial_out1.set_baud(MOZZI_AUDIO_RATE*MOZZI_PDM_RESOLUTION*40); // NOTE: 40 == 4 * (8 bits + stop-bits)
+ +
223 }
+
224 
+
225 void stopMozzi() {
+
226 #warning implement me
+
227 }
+
228 
+
229 
+
230 #endif
+
231 ////// END audio output code //////
+
232 
+
233 //// BEGIN Random seeding ////////
+
234 void MozziRandPrivate::autoSeed() {
+
235 #warning Automatic random seeding is not implemented on this platform
+
236 }
+
237 //// END Random seeding ////////
+
238 
+
239 } // namespace MozziPrivate
+
240 
+
241 #undef CHUNKSIZE
+
242 #undef US_PER_AUDIO_TICK
+
diff --git a/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s_8hpp_source.html index 14c2d0c51..7ae178558 100644 --- a/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_RENESAS.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,197 @@
MozziGuts_impl_RENESAS.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_RENESAS())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 #include <FspTimer.h>
18 
19 namespace MozziPrivate {
20 
21 ////// BEGIN analog input code ////////
22 
23 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
24 
25 #define channelNumToIndex(channel) channel-14 // A0=14
26 void const *const p_context = 0; // unused but needed for the ADC call
27 adc_callback_args_t *const p_callback_memory = NULL; // idem
28 uint16_t cfg_adc = 0; // put at 0 for starters but modified by the ADC_container
29 uint8_t r4_pin; // to store it between calls
30 
31 void adc_callback(adc_callback_args_t *p_args) {
32  advanceADCStep();
33 }
34 
35 } // namespace MozziPrivate
36 
37 #include "MozziGuts_impl_RENESAS_ADC.hpp"
38 
39 namespace MozziPrivate {
40 
41 #define getADCReading() readADC(r4_pin)
42 
43 uint8_t adcPinToChannelNum(uint8_t pin) {
44  return pin;
45 }
46 
47 void adcStartConversion(uint8_t channel) {
48  r4_pin = channel; // remember for startSecondADCReadOnCurrentChannel()
49  startScan(r4_pin);
50 }
51 
52 void startSecondADCReadOnCurrentChannel() {
53  startScan(r4_pin);
54 }
55 
56 void setupFastAnalogRead(int8_t speed) {
57  //#warning Fast analog read not implemented on this platform
58 }
59 
60 void setupMozziADC(int8_t speed) {
61  IRQManager::getInstance().addADCScanEnd(&adc, NULL); // this is needed to change some config inside the ADC, even though we do not give the callback here (doing so crashes the board). The callback is declared to the ADC by: R_ADC_CallbackSet(&(_adc->ctrl), adc_callback, p_context, p_callback_memory); in MozziGuts_impl_RENESAS_ADC.hpp.
62 }
63 #endif
64 
65 ////// END analog input code ////////
66 
67 
68 
69 //// BEGIN AUDIO OUTPUT code ///////
70 
71 /*
72 The strategy to output sound on this platform differs somehow from what is usually done in Mozzi.
73 Usually, Mozzi's circular buffer are read from the outputting device (PWM, DAC...) or committed as
74 a whole (for the MBED platform) and thus emptied. Once a free spot is present, Mozzi fills it with updateAudio().
75 Here, the DAC works straight from a buffer, outputting samples from it at a fixed rate.
76 This is sweet as we can branch it straight to Mozzi's buffer and it will read from it without
77 further action from us.
78 The big difference is that it *does not* empty the buffer, nor notify that something has been
79 read, which is okay for outputting a periodic signal where just a full period is present
80 in the buffer.
81 As a consequence we need to artificially empty the buffer at the same rate that the DAC is reading
82 it.
83 */
84 
85 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
86 FspTimer timer;
87 #endif
88 
89 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
90 CircularBuffer<uint16_t> output_buffer;
91 } // namespace MozziPrivate
92 #include "MozziGuts_impl_RENESAS_analog.hpp"
93 namespace MozziPrivate {
94 #endif
95 
96 
97 //////////////// TIMER ////////////////
98 
99 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
100 void timer_callback_dummy(timer_callback_args_t __attribute__((unused)) *args){defaultAudioOutput();};
101 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
102 //void timer_callback_dummy(timer_callback_args_t __attribute__((unused)) *args){
103 void timer_callback_dummy(timer_callback_args_t __attribute__((unused)) *args){output_buffer.read();}; // to empty the buffer (the dac does not take care of it), a bit a waste of timer...
104 #endif
105 
106 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
107 void timer_init() {
108  uint8_t type;
109  int8_t tindex = FspTimer::get_available_timer(type);
110 
111  if (tindex < 0) {
112  tindex = FspTimer::get_available_timer(type, true);
113  }
114 
115  if (tindex >= 0) {
116  timer.begin(TIMER_MODE_PERIODIC, type, tindex, MOZZI_AUDIO_RATE, 50.0,timer_callback_dummy);
117  timer.setup_overflow_irq();
118  }
119 
120 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
121  // we need to set up another timer for dac caring
122  // note: it is running at the same speed than the other one, but could not manage
123  // to get the other one updating the dac and removing the samples from the buffer…
124  tindex = FspTimer::get_available_timer(type);
125 
126  if (tindex < 0) {
127  tindex = FspTimer::get_available_timer(type, true);
128  }
129 
130  if (tindex >= 0) {
131  FspTimer::force_use_of_pwm_reserved_timer();
132  timer_dac.begin(TIMER_MODE_PERIODIC, type, tindex, MOZZI_AUDIO_RATE, 50.0);
133  timer_dac.setup_overflow_irq();
134  dtc_cfg_extend.activation_source = timer_dac.get_cfg()->cycle_end_irq;
135  timer_dac.open();
136  }
137 # endif // TODO: This endif used to be two lines up from here (above timer.open), which does not make sense syntactically, for external output
138  timer.open();
139 }
140 #endif
141 
142 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
143 inline void audioOutput(const AudioOutput f) {
144  output_buffer.write(f+MOZZI_AUDIO_BIAS);
145 }
146 # define canBufferAudioOutput() (!output_buffer.isFull())
147 #endif
148 
149 static void startAudio() {
150 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
151  dac_creation(MOZZI_AUDIO_PIN_1);
152 #endif
153 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
154  timer_init(); // this need to be done between the DAC creation and initialization in the case where the on-board DAC is used, hence the ugly repetition here.
155 #endif
156 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
157  dac_init();
158  R_DTC_Open(&dtc_ctrl, &dtc_cfg);
159  R_DTC_Enable(&dtc_ctrl);
160 
161  // The following branches the DAC straight on Mozzi's circular buffer.
162  dtc_cfg.p_info->p_src = output_buffer.address();
163  dtc_cfg.p_info->length = MOZZI_BUFFER_SIZE;
164  R_DTC_Reconfigure(&dtc_ctrl, dtc_cfg.p_info);
165  timer_dac.start();
166 #endif
167 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
168  timer.start();
169 #endif
170 }
171 
172 void stopMozzi() {
173 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
174  timer.stop();
175 #endif
176 }
177 //// END AUDIO OUTPUT code ///////
178 
179 //// BEGIN Random seeding ////////
180 void MozziRandPrivate::autoSeed() {
181 #warning Automatic random seeding is not implemented on this platform
182 }
183 //// END Random seeding ////////
184 
185 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_RENESAS.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 T. Combriat 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 #if !(IS_RENESAS())
+
13 # error "Wrong implementation included for this platform"
+
14 #endif
+
15 
+
16 #include <FspTimer.h>
+
17 
+
18 namespace MozziPrivate {
+
19 
+
20 ////// BEGIN analog input code ////////
+
21 
+
22 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
23 
+
24 #define channelNumToIndex(channel) channel-14 // A0=14
+
25 void const *const p_context = 0; // unused but needed for the ADC call
+ +
27 uint16_t cfg_adc = 0; // put at 0 for starters but modified by the ADC_container
+
28 uint8_t r4_pin; // to store it between calls
+
29 
+ + +
32 }
+
33 
+
34 } // namespace MozziPrivate
+
35 
+
36 #include "MozziGuts_impl_RENESAS_ADC.hpp"
+
37 
+
38 namespace MozziPrivate {
+
39 
+
40 #define getADCReading() readADC(r4_pin)
+
41 
+ +
43  return pin;
+
44 }
+
45 
+ +
47  r4_pin = channel; // remember for startSecondADCReadOnCurrentChannel()
+ +
49 }
+
50 
+ + +
53 }
+
54 
+ +
56  //#warning Fast analog read not implemented on this platform
+
57 }
+
58 
+ +
60  IRQManager::getInstance().addADCScanEnd(&adc, NULL); // this is needed to change some config inside the ADC, even though we do not give the callback here (doing so crashes the board). The callback is declared to the ADC by: R_ADC_CallbackSet(&(_adc->ctrl), adc_callback, p_context, p_callback_memory); in MozziGuts_impl_RENESAS_ADC.hpp.
+
61 }
+
62 #endif
+
63 
+
64 ////// END analog input code ////////
+
65 
+
66 
+
67 
+
68 //// BEGIN AUDIO OUTPUT code ///////
+
69 
+
70 /*
+
71 The strategy to output sound on this platform differs somehow from what is usually done in Mozzi.
+
72 Usually, Mozzi's circular buffer are read from the outputting device (PWM, DAC...) or committed as
+
73 a whole (for the MBED platform) and thus emptied. Once a free spot is present, Mozzi fills it with updateAudio().
+
74 Here, the DAC works straight from a buffer, outputting samples from it at a fixed rate.
+
75 This is sweet as we can branch it straight to Mozzi's buffer and it will read from it without
+
76 further action from us.
+
77 The big difference is that it *does not* empty the buffer, nor notify that something has been
+
78 read, which is okay for outputting a periodic signal where just a full period is present
+
79 in the buffer.
+
80 As a consequence we need to artificially empty the buffer at the same rate that the DAC is reading
+
81 it.
+
82 */
+
83 
+
84 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+ +
86 #endif
+
87 
+
88 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+ +
90 } // namespace MozziPrivate
+
91 #include "MozziGuts_impl_RENESAS_analog.hpp"
+
92 namespace MozziPrivate {
+
93 #endif
+
94 
+
95 
+
96 //////////////// TIMER ////////////////
+
97 
+
98 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+ +
100 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
101 //void timer_callback_dummy(timer_callback_args_t __attribute__((unused)) *args){
+
102 void timer_callback_dummy(timer_callback_args_t __attribute__((unused)) *args){output_buffer.read();}; // to empty the buffer (the dac does not take care of it), a bit a waste of timer...
+
103 #endif
+
104 
+
105 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
106 void timer_init() {
+
107  uint8_t type;
+ +
109 
+
110  if (tindex < 0) {
+ +
112  }
+
113 
+
114  if (tindex >= 0) {
+ + +
117  }
+
118 
+
119 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
120  // we need to set up another timer for dac caring
+
121  // note: it is running at the same speed than the other one, but could not manage
+
122  // to get the other one updating the dac and removing the samples from the buffer…
+ +
124 
+
125  if (tindex < 0) {
+ +
127  }
+
128 
+
129  if (tindex >= 0) {
+ + + + +
134  timer_dac.open();
+
135  }
+
136 # endif // TODO: This endif used to be two lines up from here (above timer.open), which does not make sense syntactically, for external output
+
137  timer.open();
+
138 }
+
139 #endif
+
140 
+
141 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
142 inline void audioOutput(const AudioOutput f) {
+ +
144 }
+
145 # define canBufferAudioOutput() (!output_buffer.isFull())
+
146 #endif
+
147 
+
148 static void startAudio() {
+
149 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
150  dac_creation(MOZZI_AUDIO_PIN_1);
+
151 #endif
+
152 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
153  timer_init(); // this need to be done between the DAC creation and initialization in the case where the on-board DAC is used, hence the ugly repetition here.
+
154 #endif
+
155 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
156  dac_init();
+
157  R_DTC_Open(&dtc_ctrl, &dtc_cfg);
+
158  R_DTC_Enable(&dtc_ctrl);
+
159 
+
160  // The following branches the DAC straight on Mozzi's circular buffer.
+
161  dtc_cfg.p_info->p_src = output_buffer.address();
+
162  dtc_cfg.p_info->length = MOZZI_BUFFER_SIZE;
+
163  R_DTC_Reconfigure(&dtc_ctrl, dtc_cfg.p_info);
+
164  timer_dac.start();
+
165 #endif
+
166 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
167  timer.start();
+
168 #endif
+
169 }
+
170 
+
171 void stopMozzi() {
+
172 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
173  timer.stop();
+
174 #endif
+
175 }
+
176 //// END AUDIO OUTPUT code ///////
+
177 
+
178 //// BEGIN Random seeding ////////
+
179 void MozziRandPrivate::autoSeed() {
+
180 #warning Automatic random seeding is not implemented on this platform
+
181 }
+
182 //// END Random seeding ////////
+
183 
+
184 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s___a_d_c_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s___a_d_c_8hpp_source.html index c258265ae..2e43d7bca 100644 --- a/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s___a_d_c_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s___a_d_c_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_RENESAS_ADC.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,144 @@
MozziGuts_impl_RENESAS_ADC.hpp
-
1 /*
2 
3 Parts of this file are drawn from Arduino's source code for analogRead() (https://github.com/arduino/ArduinoCore-renesas/blob/main/cores/arduino/analog.cpp) and part from Renesas' documentation (https://renesas.github.io/fsp/group___a_d_c.html), among other things.
4 It contains functions to interact with the ADC in order to implement async ADC reads, aka mozziAnalogRead().
5 */
6 
7 #include <analog.h>
8 //#include <analog.cpp>
9 #include <IRQManager.h>
10 
11 namespace MozziPrivate {
12 
13 /** VERBATIM from Arduino's analog.cpp
14  */
15 #define MAX_ADC_CHANNELS 29
16 static uint16_t analog_values_by_channels[MAX_ADC_CHANNELS] = {0};
17 static void ADC_irq_cbk(adc_callback_args_t * cb_data);
18 static ADC_Container adc(0,ADC_irq_cbk);
19 static ADC_Container adc1(1,ADC_irq_cbk);
20 
21 static ADCIrqCbk_f scan_complete_cbk = nullptr;
22 static ADCIrqCbk_f scan_complete_b_cbk = nullptr;
23 static ADCIrqCbk_f window_compare_a_cbk = nullptr;
24 static ADCIrqCbk_f window_compare_b_cbk = nullptr;
25 
26 static void readAllGroupA(ADC_Container *_adc) {
27  for(int i = 0; i < MAX_ADC_CHANNELS; i++) {
28  if(_adc->channel_cfg.scan_mask & (1 << i)) {
29  //is the channel active -> yes, read it
30  R_ADC_Read(&(_adc->ctrl), (adc_channel_t)i, analog_values_by_channels + i);
31  }
32  }
33 }
34 
35 static void readAllGroupB(ADC_Container *_adc) {
36  for(int i = 0; i < MAX_ADC_CHANNELS; i++) {
37  if(_adc->channel_cfg.scan_mask_group_b & (1 << i)) {
38  //is the channel active -> yes, read it
39  R_ADC_Read(&(_adc->ctrl), (adc_channel_t)i, analog_values_by_channels + i);
40  }
41  }
42 }
43 
44 
45 static void ADC_irq_cbk(adc_callback_args_t * cb_data) {
46  if(cb_data->event == ADC_EVENT_SCAN_COMPLETE) {
47  if(scan_complete_cbk != nullptr) {
48  if(cb_data->unit == 0) {
49  readAllGroupA(&adc);
50  }
51  else if(cb_data->unit == 1) {
52  readAllGroupA(&adc1);
53  }
54  scan_complete_cbk(cb_data->unit);
55  }
56  }
57  else if(cb_data->event == ADC_EVENT_SCAN_COMPLETE_GROUP_B) {
58  if(scan_complete_b_cbk != nullptr) {
59  if(cb_data->unit == 0) {
60  readAllGroupB(&adc);
61  }
62  else if(cb_data->unit == 1) {
63  readAllGroupB(&adc1);
64  }
65  scan_complete_b_cbk(cb_data->unit);
66  }
67  }
68  else if(cb_data->event == ADC_EVENT_WINDOW_COMPARE_A) {
69  if(window_compare_a_cbk != nullptr) {
70  window_compare_a_cbk(cb_data->unit);
71  }
72  }
73  else if(cb_data->event == ADC_EVENT_WINDOW_COMPARE_B) {
74  if(window_compare_b_cbk != nullptr) {
75  window_compare_b_cbk(cb_data->unit);
76  }
77  }
78 }
79 
80 /* -------------------------------------------------------------------------- */
81 static ADC_Container *get_ADC_container_ptr(int32_t pin, uint16_t &cfg) {
82 /* -------------------------------------------------------------------------- */
83  ADC_Container *rv = nullptr;
84  auto cfg_adc = getPinCfgs(pin, PIN_CFG_REQ_ADC);
85  if(cfg_adc[0] > 0 ) {
86  if(IS_ADC1(cfg_adc[0])) {
87  rv = &adc1;
88  }
89  else {
90  rv = &adc;
91  }
92  }
93  cfg = cfg_adc[0];
94  return rv;
95 
96 }
97 
98 /* END of verbatim
99  */
100 //////////////////// ADC //////////////
101 
102 void startScan(int pin)
103 {
104  int32_t adc_idx = digitalPinToAnalogPin(pin);
105  ADC_Container *_adc = get_ADC_container_ptr(adc_idx, cfg_adc);
106  _adc->cfg.mode = ADC_MODE_SINGLE_SCAN;
107  pinPeripheral(digitalPinToBspPin(adc_idx), (uint32_t)IOPORT_CFG_ANALOG_ENABLE);
108  _adc->channel_cfg.scan_mask |= (1 << GET_CHANNEL(cfg_adc));
109  R_ADC_Open(&(_adc->ctrl), &(_adc->cfg));
110  R_ADC_CallbackSet(&(_adc->ctrl), adc_callback, p_context, p_callback_memory);
111  R_ADC_ScanCfg(&(_adc->ctrl), &(_adc->channel_cfg));
112  R_ADC_ScanStart(&(_adc->ctrl));
113 }
114 
115 uint16_t readADC(int pin)
116 {
117  uint16_t result;
118  int32_t adc_idx = digitalPinToAnalogPin(pin);
119  ADC_Container *_adc = get_ADC_container_ptr(adc_idx, cfg_adc);
120  R_ADC_Read(&(_adc->ctrl), (adc_channel_t)GET_CHANNEL(cfg_adc), &result);
121  return result;
122 }
123 
124 } // namespace MozziPrivate
#define MAX_ADC_CHANNELS
VERBATIM from Arduino&#39;s analog.cpp.
+
1 /*
+
2  * MozziGuts_impl_ADC.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 T. Combriat and the Mozzi Team
+
7  *
+
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
9 
+
10 Parts of this file are drawn from Arduino's source code for analogRead() (https://github.com/arduino/ArduinoCore-renesas/blob/main/cores/arduino/analog.cpp) and part from Renesas' documentation (https://renesas.github.io/fsp/group___a_d_c.html), among other things.
+
11 It contains functions to interact with the ADC in order to implement async ADC reads, aka mozziAnalogRead().
+
12 */
+
13 
+
14 #include <analog.h>
+
15 //#include <analog.cpp>
+
16 #include <IRQManager.h>
+
17 
+
18 namespace MozziPrivate {
+
19 
+
20 /** VERBATIM from Arduino's analog.cpp
+
21  */
+
22 #define MAX_ADC_CHANNELS 29
+ +
24 static void ADC_irq_cbk(adc_callback_args_t * cb_data);
+
25 static ADC_Container adc(0,ADC_irq_cbk);
+
26 static ADC_Container adc1(1,ADC_irq_cbk);
+
27 
+
28 static ADCIrqCbk_f scan_complete_cbk = nullptr;
+
29 static ADCIrqCbk_f scan_complete_b_cbk = nullptr;
+
30 static ADCIrqCbk_f window_compare_a_cbk = nullptr;
+
31 static ADCIrqCbk_f window_compare_b_cbk = nullptr;
+
32 
+
33 static void readAllGroupA(ADC_Container *_adc) {
+
34  for(int i = 0; i < MAX_ADC_CHANNELS; i++) {
+
35  if(_adc->channel_cfg.scan_mask & (1 << i)) {
+
36  //is the channel active -> yes, read it
+
37  R_ADC_Read(&(_adc->ctrl), (adc_channel_t)i, analog_values_by_channels + i);
+
38  }
+
39  }
+
40 }
+
41 
+
42 static void readAllGroupB(ADC_Container *_adc) {
+
43  for(int i = 0; i < MAX_ADC_CHANNELS; i++) {
+
44  if(_adc->channel_cfg.scan_mask_group_b & (1 << i)) {
+
45  //is the channel active -> yes, read it
+
46  R_ADC_Read(&(_adc->ctrl), (adc_channel_t)i, analog_values_by_channels + i);
+
47  }
+
48  }
+
49 }
+
50 
+
51 
+
52 static void ADC_irq_cbk(adc_callback_args_t * cb_data) {
+
53  if(cb_data->event == ADC_EVENT_SCAN_COMPLETE) {
+
54  if(scan_complete_cbk != nullptr) {
+
55  if(cb_data->unit == 0) {
+
56  readAllGroupA(&adc);
+
57  }
+
58  else if(cb_data->unit == 1) {
+
59  readAllGroupA(&adc1);
+
60  }
+
61  scan_complete_cbk(cb_data->unit);
+
62  }
+
63  }
+
64  else if(cb_data->event == ADC_EVENT_SCAN_COMPLETE_GROUP_B) {
+
65  if(scan_complete_b_cbk != nullptr) {
+
66  if(cb_data->unit == 0) {
+
67  readAllGroupB(&adc);
+
68  }
+
69  else if(cb_data->unit == 1) {
+
70  readAllGroupB(&adc1);
+
71  }
+
72  scan_complete_b_cbk(cb_data->unit);
+
73  }
+
74  }
+
75  else if(cb_data->event == ADC_EVENT_WINDOW_COMPARE_A) {
+
76  if(window_compare_a_cbk != nullptr) {
+
77  window_compare_a_cbk(cb_data->unit);
+
78  }
+
79  }
+
80  else if(cb_data->event == ADC_EVENT_WINDOW_COMPARE_B) {
+
81  if(window_compare_b_cbk != nullptr) {
+
82  window_compare_b_cbk(cb_data->unit);
+
83  }
+
84  }
+
85 }
+
86 
+
87 /* -------------------------------------------------------------------------- */
+
88 static ADC_Container *get_ADC_container_ptr(int32_t pin, uint16_t &cfg) {
+
89 /* -------------------------------------------------------------------------- */
+
90  ADC_Container *rv = nullptr;
+
91  auto cfg_adc = getPinCfgs(pin, PIN_CFG_REQ_ADC);
+
92  if(cfg_adc[0] > 0 ) {
+
93  if(IS_ADC1(cfg_adc[0])) {
+
94  rv = &adc1;
+
95  }
+
96  else {
+
97  rv = &adc;
+
98  }
+
99  }
+
100  cfg = cfg_adc[0];
+
101  return rv;
+
102 
+
103 }
+
104 
+
105 /* END of verbatim
+
106  */
+
107 //////////////////// ADC //////////////
+
108 
+
109 void startScan(int pin)
+
110 {
+
111  int32_t adc_idx = digitalPinToAnalogPin(pin);
+
112  ADC_Container *_adc = get_ADC_container_ptr(adc_idx, cfg_adc);
+
113  _adc->cfg.mode = ADC_MODE_SINGLE_SCAN;
+
114  pinPeripheral(digitalPinToBspPin(adc_idx), (uint32_t)IOPORT_CFG_ANALOG_ENABLE);
+
115  _adc->channel_cfg.scan_mask |= (1 << GET_CHANNEL(cfg_adc));
+
116  R_ADC_Open(&(_adc->ctrl), &(_adc->cfg));
+
117  R_ADC_CallbackSet(&(_adc->ctrl), adc_callback, p_context, p_callback_memory);
+
118  R_ADC_ScanCfg(&(_adc->ctrl), &(_adc->channel_cfg));
+
119  R_ADC_ScanStart(&(_adc->ctrl));
+
120 }
+
121 
+
122 uint16_t readADC(int pin)
+
123 {
+
124  uint16_t result;
+
125  int32_t adc_idx = digitalPinToAnalogPin(pin);
+
126  ADC_Container *_adc = get_ADC_container_ptr(adc_idx, cfg_adc);
+
127  R_ADC_Read(&(_adc->ctrl), (adc_channel_t)GET_CHANNEL(cfg_adc), &result);
+
128  return result;
+
129 }
+
130 
+
131 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s__analog_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s__analog_8hpp_source.html index 400f92987..637ebfa49 100644 --- a/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s__analog_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___r_e_n_e_s_a_s__analog_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_RENESAS_analog.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,113 @@
MozziGuts_impl_RENESAS_analog.hpp
-
1 /*
2 Most of this file is drawn, more or less adapted from the AnalogWave example
3 for Renesas board from Arduino.
4 It contains functions to create and start the on-board DAC (and associate timer).
5 */
6 
7 #include <dac.h>
8 #include <FspTimer.h>
9 #include <r_dtc.h>
10 
11 namespace MozziPrivate {
12 
13 FspTimer timer_dac;
14 
15 volatile uint32_t pin;
16 uint8_t dac_bits;
17 dtc_instance_ctrl_t dtc_ctrl;
18 transfer_info_t dtc_info;
19 dtc_extended_cfg_t dtc_cfg_extend;
20 transfer_cfg_t dtc_cfg;
21 
22 ////////////// DAC CREATION AND FIRST INIT ///////////////////
23 // DAC creation, will take care of specifying the number of bits according to the
24 // capacity of the DAC (12 only for now) and set up the transfer mode straight from
25 // an external buffer.
26 void dac_creation(pin_size_t pinN) {
27  if (IS_DAC(pinN)) {
28  auto cfg_dac = getPinCfgs(pinN, PIN_CFG_REQ_DAC);
29  pin = cfg_dac[0];
30  if (IS_DAC_8BIT(pin)) {
31  dac_bits = 8;
32  dtc_info.transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE;
33  if (GET_CHANNEL(pin) == 0) {
34 #ifdef DAC_ADDRESS_8_CH0
35  dtc_info.p_dest = (void *)DAC_ADDRESS_8_CH0;
36 #endif
37  } else if (GET_CHANNEL(pin) == 1) {
38 #ifdef DAC_ADDRESS_8_CH1
39  dtc_info.p_dest = (void *)DAC_ADDRESS_8_CH1;
40 #endif
41  }
42  } else {
43  dac_bits = 12;
44  dtc_info.transfer_settings_word_b.size = TRANSFER_SIZE_2_BYTE;
45  if (GET_CHANNEL(pin) == 0) {
46 #ifdef DAC_ADDRESS_12_CH0
47  dtc_info.p_dest = (void *)DAC_ADDRESS_12_CH0;
48 #endif
49  } else if (GET_CHANNEL(pin) == 1) {
50 #ifdef DAC_ADDRESS_12_CH1
51  dtc_info.p_dest = (void *)DAC_ADDRESS_12_CH1;
52 #endif
53  }
54  }
55  }
56 
57  dtc_info.transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED;
58  dtc_info.transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE;
59  dtc_info.transfer_settings_word_b.irq = TRANSFER_IRQ_END;
60  dtc_info.transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED;
61  dtc_info.transfer_settings_word_b.src_addr_mode =
62  TRANSFER_ADDR_MODE_INCREMENTED;
63  dtc_info.transfer_settings_word_b.mode = TRANSFER_MODE_REPEAT;
64  dtc_info.p_src = (void const *)NULL;
65 
66  dtc_info.num_blocks = 0;
67  dtc_info.length = 0;
68 
69  dtc_cfg.p_info = &dtc_info;
70  dtc_cfg.p_extend = &dtc_cfg_extend;
71 
72  dtc_cfg_extend.activation_source = FSP_INVALID_VECTOR;
73 }
74 
75 
76 // DAC initialization
77 void dac_init() {
78  if (IS_DAC_8BIT(pin)) {
79 #if DAC8_HOWMANY > 0
80  if (GET_CHANNEL(pin) < DAC8_HOWMANY) {
81  _dac8[GET_CHANNEL(pin)].init();
82  }
83 #endif
84  } else {
85  if (GET_CHANNEL(pin) < DAC12_HOWMANY) {
86  _dac12[GET_CHANNEL(pin)].init();
87  }
88  }
89 }
90 
91 }
+
1 /*
+
2  * MozziGuts_impl_RENESAS_analog.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 T. Combriat 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 Most of this file is drawn, more or less adapted from the AnalogWave example
+
12 for Renesas board from Arduino.
+
13 It contains functions to create and start the on-board DAC (and associate timer).
+
14 */
+
15 
+
16 #include <dac.h>
+
17 #include <FspTimer.h>
+
18 #include <r_dtc.h>
+
19 
+
20 namespace MozziPrivate {
+
21 
+
22 FspTimer timer_dac;
+
23 
+
24 volatile uint32_t pin;
+
25 uint8_t dac_bits;
+
26 dtc_instance_ctrl_t dtc_ctrl;
+
27 transfer_info_t dtc_info;
+
28 dtc_extended_cfg_t dtc_cfg_extend;
+
29 transfer_cfg_t dtc_cfg;
+
30 
+
31 ////////////// DAC CREATION AND FIRST INIT ///////////////////
+
32 // DAC creation, will take care of specifying the number of bits according to the
+
33 // capacity of the DAC (12 only for now) and set up the transfer mode straight from
+
34 // an external buffer.
+
35 void dac_creation(pin_size_t pinN) {
+
36  if (IS_DAC(pinN)) {
+
37  auto cfg_dac = getPinCfgs(pinN, PIN_CFG_REQ_DAC);
+
38  pin = cfg_dac[0];
+
39  if (IS_DAC_8BIT(pin)) {
+
40  dac_bits = 8;
+
41  dtc_info.transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE;
+
42  if (GET_CHANNEL(pin) == 0) {
+
43 #ifdef DAC_ADDRESS_8_CH0
+
44  dtc_info.p_dest = (void *)DAC_ADDRESS_8_CH0;
+
45 #endif
+
46  } else if (GET_CHANNEL(pin) == 1) {
+
47 #ifdef DAC_ADDRESS_8_CH1
+
48  dtc_info.p_dest = (void *)DAC_ADDRESS_8_CH1;
+
49 #endif
+
50  }
+
51  } else {
+
52  dac_bits = 12;
+
53  dtc_info.transfer_settings_word_b.size = TRANSFER_SIZE_2_BYTE;
+
54  if (GET_CHANNEL(pin) == 0) {
+
55 #ifdef DAC_ADDRESS_12_CH0
+
56  dtc_info.p_dest = (void *)DAC_ADDRESS_12_CH0;
+
57 #endif
+
58  } else if (GET_CHANNEL(pin) == 1) {
+
59 #ifdef DAC_ADDRESS_12_CH1
+
60  dtc_info.p_dest = (void *)DAC_ADDRESS_12_CH1;
+
61 #endif
+
62  }
+
63  }
+
64  }
+
65 
+
66  dtc_info.transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED;
+
67  dtc_info.transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE;
+
68  dtc_info.transfer_settings_word_b.irq = TRANSFER_IRQ_END;
+
69  dtc_info.transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED;
+
70  dtc_info.transfer_settings_word_b.src_addr_mode =
+
71  TRANSFER_ADDR_MODE_INCREMENTED;
+
72  dtc_info.transfer_settings_word_b.mode = TRANSFER_MODE_REPEAT;
+
73  dtc_info.p_src = (void const *)NULL;
+
74 
+
75  dtc_info.num_blocks = 0;
+
76  dtc_info.length = 0;
+
77 
+
78  dtc_cfg.p_info = &dtc_info;
+
79  dtc_cfg.p_extend = &dtc_cfg_extend;
+
80 
+
81  dtc_cfg_extend.activation_source = FSP_INVALID_VECTOR;
+
82 }
+
83 
+
84 
+
85 // DAC initialization
+
86 void dac_init() {
+
87  if (IS_DAC_8BIT(pin)) {
+
88 #if DAC8_HOWMANY > 0
+
89  if (GET_CHANNEL(pin) < DAC8_HOWMANY) {
+
90  _dac8[GET_CHANNEL(pin)].init();
+
91  }
+
92 #endif
+
93  } else {
+
94  if (GET_CHANNEL(pin) < DAC12_HOWMANY) {
+
95  _dac12[GET_CHANNEL(pin)].init();
+
96  }
+
97  }
+
98 }
+
99 
+
100 }
+
diff --git a/extras/doc/html/_mozzi_guts__impl___r_p2040_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___r_p2040_8hpp_source.html index 3be3f9135..ccf9aecb0 100644 --- a/extras/doc/html/_mozzi_guts__impl___r_p2040_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___r_p2040_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_RP2040.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,301 @@
MozziGuts_impl_RP2040.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 // The main point of this check is to document, what platform & variants this implementation file is for.
14 #if !(IS_RP2040())
15 # error "Wrong implementation included for this platform"
16 #endif
17 
18 #include <hardware/dma.h>
19 
20 namespace MozziPrivate {
21 
22 ////// BEGIN analog input code ////////
23 
24 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
25 
26 /** Implementation notes:
27  * - So nobody on the nets seems to have quite figured out, how to run the RP2040 ADC in "regular" asynchronous mode.
28  * - The ADC sports an interrupt, presumably to be triggered when a conversion is done, but how to connect a callback to that?
29  * - There is, however, an official example on a free running ADC writing to DMA (https://github.com/raspberrypi/pico-examples/blob/master/adc/dma_capture/dma_capture.c ; BSD licensed)
30  * We'll abuse that to connect a callback to the DMA channel, instead.
31 */
32 
33 } // namespace MozziPrivate
34 
35 #include <hardware/adc.h>
36 
37 namespace MozziPrivate {
38 
39 #define getADCReading() rp2040_adc_result
40 #define channelNumToIndex(channel) channel
41 
42 inline void adc_run_once () { // see rp2040 sdk code for adc_read() vs adc_run()
43  hw_set_bits(&adc_hw->cs, ADC_CS_START_ONCE_BITS); // vs ADC_CS_START_MANY_BITS
44 }
45 
46 uint8_t adcPinToChannelNum(uint8_t pin) {
47  if (pin >= 26) pin -= 26; // allow analog to be called by GP or ADC numbering
48  return pin;
49 
50 }
51 
52 void adcStartConversion(uint8_t channel) {
53  adc_select_input(channel);
54  adc_run_once();
55  // adc_run(true);
56 }
57 
58 void startSecondADCReadOnCurrentChannel() {
59  adc_run_once();
60  // adc_run(true);
61 }
62 
63 void setupFastAnalogRead(int8_t speed) {
64  if (speed == FAST_ADC) {
65  adc_set_clkdiv(2048); // Note: arbritray pick
66  } else if (speed == FASTER_ADC) {
67  adc_set_clkdiv(256); // Note: arbritray pick
68  } else {
69  adc_set_clkdiv(0); // max speed
70  }
71 }
72 
73 void rp2040_adc_queue_handler();
74 
75 static uint16_t rp2040_adc_result = 0;
76 int rp2040_adc_dma_chan;
77 void setupMozziADC(int8_t speed) {
78  for (int i = 0; i < (int) NUM_ANALOG_INPUTS; ++i) {
79  adc_gpio_init(i);
80  }
81 
82  adc_init();
83  adc_fifo_setup(
84  true, // Write each completed conversion to the sample FIFO
85  true, // Enable DMA data request (DREQ)
86  1, // DREQ (and IRQ) asserted when at least 1 sample present
87  false, // Don't want ERR bit
88  false // Keep full sample range
89  );
90 
91  uint dma_chan = dma_claim_unused_channel(true);
92  rp2040_adc_dma_chan = dma_chan;
93  static dma_channel_config cfg = dma_channel_get_default_config(dma_chan);
94 
95  // Reading from constant address, writing to incrementing byte addresses
96  channel_config_set_transfer_data_size(&cfg, DMA_SIZE_16);
97  channel_config_set_read_increment(&cfg, false);
98  channel_config_set_write_increment(&cfg, false); // we don't really want a fifo, just keep reading to the same address
99 
100  // Pace transfers based on availability of ADC samples
101  channel_config_set_dreq(&cfg, DREQ_ADC);
102 
103  dma_channel_configure(dma_chan, &cfg,
104  &rp2040_adc_result, // dst
105  &adc_hw->fifo, // src
106  1, // transfer count
107  true // start immediately
108  );
109 
110  // we want notification, when a sample has arrived
111  dma_channel_set_irq0_enabled(dma_chan, true);
112  irq_add_shared_handler(DMA_IRQ_0, rp2040_adc_queue_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
113  irq_set_enabled(DMA_IRQ_0, true);
114  dma_channel_start(dma_chan);
115 }
116 
117 void rp2040_adc_queue_handler() {
118  if (!dma_channel_get_irq0_status(rp2040_adc_dma_chan)) return; // shared handler may get called on unrelated events
119  dma_channel_acknowledge_irq0(rp2040_adc_dma_chan); // clear interrupt flag
120  //adc_run(false); // adc not running continuous
121  //adc_fifo_drain(); // no need to drain fifo, the dma transfer did that
122  dma_channel_set_trans_count(rp2040_adc_dma_chan, 1, true); // set up for another read
123  advanceADCStep();
124 }
125 
126 #endif // MOZZI_ANALOG_READ
127 
128 ////// END analog input code ////////
129 
130 
131 ////// BEGIN audio output code //////
132 #define LOOP_YIELD tight_loop_contents(); // apparently needed, among other things, to service the alarm pool
133 
134 
135 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
136 #include <hardware/pwm.h>
137 
138 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
139 inline void audioOutput(const AudioOutput f) {
140  pwm_set_gpio_level(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
141 # if (MOZZI_AUDIO_CHANNELS > 1)
142  pwm_set_gpio_level(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS);
143 # endif
144 }
145 # endif // MOZZI_OUTPUT_PWM
146 
147 } // namespace MozziPrivate
148 #include <pico/time.h>
149 namespace MozziPrivate {
150 /** Implementation notes:
151  * - For the time being this port uses a very crude approach to audio output: PWM updated by a hardware timer running at MOZZI_AUDIO_RATE
152  * - Hardware timer isn't fixed, but rather we claim the first unclaimed one
153  * - Quite pleasently, the RP2040 latches PWM duty cycle, so we do not have to worry about updating whilst in the middle of the previous PWM cycle.
154  * - The more simple add_repeating_timer_us has appers to have far too much jitter
155  * - Using DMA transfers, instead of a manual timer, would be much more elegant, but I'll leave that as an exercise to the reader ;-)
156  * - Not to mention PWM output, etc.
157  */
158 absolute_time_t next_audio_update;
159 uint64_t micros_per_update;
160 uint audio_update_alarm_num;
161 
162 void audioOutputCallback(uint) {
163  do {
164  defaultAudioOutput();
165  next_audio_update = delayed_by_us(next_audio_update, micros_per_update);
166  // NOTE: hardware_alarm_set_target returns true, if the target was already missed. In that case, keep pushing samples, until we have caught up.
167  } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update));
168 }
169 
170 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
171 } // namespace MozziPrivate
172 #include <I2S.h>
173 namespace MozziPrivate {
174 I2S i2s(OUTPUT);
175 
176 inline bool canBufferAudioOutput() {
177  return (i2s.availableForWrite());
178 }
179 
180 inline void audioOutput(const AudioOutput f) {
181 
182 # if (MOZZI_AUDIO_BITS == 8)
183 # if (MOZZI_AUDIO_CHANNELS > 1)
184  i2s.write8(f.l(), f.r());
185 # else
186  i2s.write8(f.l(), 0);
187 # endif
188 
189 # elif (MOZZI_AUDIO_BITS == 16)
190 # if (MOZZI_AUDIO_CHANNELS > 1)
191  i2s.write16(f.l(), f.r());
192 # else
193  i2s.write16(f.l(), 0);
194 # endif
195 
196 # elif (MOZZI_AUDIO_BITS == 24)
197 # if (MOZZI_AUDIO_CHANNELS > 1)
198  i2s.write24(f.l(), f.r());
199 # else
200  i2s.write24(f.l(), 0);
201 # endif
202 
203 # elif (MOZZI_AUDIO_BITS == 32)
204 # if (MOZZI_AUDIO_CHANNELS > 1)
205  i2s.write32(f.l(), f.r());
206 # else
207  i2s.write32(f.l(), 0);
208 # endif
209 # else
210 # error Invalid number of MOZZI_AUDIO_BITS configured
211 # endif
212 
213 }
214 #endif
215 
216 
217 static void startAudio() {
218 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
219  // calling analogWrite for the first time will try to init the pwm frequency and range on all pins. We don't want that happening after we've set up our own,
220  // so we start off with a dummy call to analogWrite:
221  analogWrite(MOZZI_AUDIO_PIN_1, MOZZI_AUDIO_BIAS);
222  // Set up fast PWM on the output pins
223  // TODO: This is still very crude!
224  pwm_config c = pwm_get_default_config();
225  pwm_config_set_clkdiv(&c, 1); // Fastest we can get: PWM clock running at full CPU speed
226  pwm_config_set_wrap(&c, 1l << MOZZI_AUDIO_BITS); // 11 bits output resolution means FCPU / 2048 values per second, which is around 60kHz for 133Mhz clock speed.
227  pwm_init(pwm_gpio_to_slice_num(MOZZI_AUDIO_PIN_1), &c, true);
228  gpio_set_function(MOZZI_AUDIO_PIN_1, GPIO_FUNC_PWM);
229  gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get
230 # if (MOZZI_AUDIO_CHANNELS > 1)
231 # if ((MOZZI_AUDIO_PIN_1 / 2) != (MOZZI_AUDIO_PIN_1 / 2))
232 # error Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. Adjust MOZZI_AUDIO_PIN_1/2 .
233 # endif
234  gpio_set_function(MOZZI_AUDIO_PIN_2, GPIO_FUNC_PWM);
235  gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get
236 # endif
237 #endif
238 
239 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
240  for (audio_update_alarm_num = 0; audio_update_alarm_num < 4; ++audio_update_alarm_num) {
241  if (!hardware_alarm_is_claimed(audio_update_alarm_num)) {
242  hardware_alarm_claim(audio_update_alarm_num);
243  hardware_alarm_set_callback(audio_update_alarm_num, audioOutputCallback);
244  break;
245  }
246  }
247  micros_per_update = 1000000l / MOZZI_AUDIO_RATE;
248  do {
249  next_audio_update = make_timeout_time_us(micros_per_update);
250  // See audioOutputCallback(), above. In _theory_ some interrupt stuff might delay us, here, causing us to miss the first beat (and everything that follows)
251  } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update));
252 
253 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
254  i2s.setBCLK(MOZZI_I2S_PIN_BCK);
255  i2s.setDATA(MOZZI_I2S_PIN_DATA);
256  i2s.setBitsPerSample(MOZZI_AUDIO_BITS);
257 
258 # if (MOZZI_AUDIO_BITS > 16)
259  i2s.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS), 0);
260 # else
261  i2s.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS/2), 0);
262 # endif
263 # if MOZZI_IS(MOZZI_I2S_FORMAT, MOZZI_I2S_FORMAT_LSBJ)
264  i2s.setLSBJFormat();
265 # endif
266  i2s.begin(MOZZI_AUDIO_RATE);
267 #endif
268 }
269 
270 void stopMozzi() {
271 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
272  hardware_alarm_set_callback(audio_update_alarm_num, NULL);
273 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
274  i2s.end();
275 #endif
276 
277 }
278 ////// END audio output code //////
279 
280 //// BEGIN Random seeding ////////
281 void MozziRandPrivate::autoSeed() {
282 #warning Automatic random seeding is not implemented on this platform
283 }
284 //// END Random seeding ////////
285 
286 } // namespace MozziPrivate
287 
288 #undef MOZZI_RP2040_BUFFERS
289 #undef MOZZI_RP2040_BUFFER_SIZE
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_RP2040.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2022-2024 Thomas Friedrichsmeier 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 // The main point of this check is to document, what platform & variants this implementation file is for.
+
13 #if !(IS_RP2040())
+
14 # error "Wrong implementation included for this platform"
+
15 #endif
+
16 
+
17 #include <hardware/dma.h>
+
18 
+
19 namespace MozziPrivate {
+
20 
+
21 ////// BEGIN analog input code ////////
+
22 
+
23 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
24 
+
25 /** Implementation notes:
+
26  * - So nobody on the nets seems to have quite figured out, how to run the RP2040 ADC in "regular" asynchronous mode.
+
27  * - The ADC sports an interrupt, presumably to be triggered when a conversion is done, but how to connect a callback to that?
+
28  * - There is, however, an official example on a free running ADC writing to DMA (https://github.com/raspberrypi/pico-examples/blob/master/adc/dma_capture/dma_capture.c ; BSD licensed)
+
29  * We'll abuse that to connect a callback to the DMA channel, instead.
+
30 */
+
31 
+
32 } // namespace MozziPrivate
+
33 
+
34 #include <hardware/adc.h>
+
35 
+
36 namespace MozziPrivate {
+
37 
+
38 #define getADCReading() rp2040_adc_result
+
39 #define channelNumToIndex(channel) channel
+
40 
+
41 inline void adc_run_once () { // see rp2040 sdk code for adc_read() vs adc_run()
+
42  hw_set_bits(&adc_hw->cs, ADC_CS_START_ONCE_BITS); // vs ADC_CS_START_MANY_BITS
+
43 }
+
44 
+ +
46  if (pin >= 26) pin -= 26; // allow analog to be called by GP or ADC numbering
+
47  return pin;
+
48 
+
49 }
+
50 
+ + +
53  adc_run_once();
+
54  // adc_run(true);
+
55 }
+
56 
+ +
58  adc_run_once();
+
59  // adc_run(true);
+
60 }
+
61 
+ +
63  if (speed == FAST_ADC) {
+
64  adc_set_clkdiv(2048); // Note: arbritray pick
+
65  } else if (speed == FASTER_ADC) {
+
66  adc_set_clkdiv(256); // Note: arbritray pick
+
67  } else {
+
68  adc_set_clkdiv(0); // max speed
+
69  }
+
70 }
+
71 
+ +
73 
+
74 static uint16_t rp2040_adc_result = 0;
+ + +
77  for (int i = 0; i < (int) NUM_ANALOG_INPUTS; ++i) {
+ +
79  }
+
80 
+
81  adc_init();
+ +
83  true, // Write each completed conversion to the sample FIFO
+
84  true, // Enable DMA data request (DREQ)
+
85  1, // DREQ (and IRQ) asserted when at least 1 sample present
+
86  false, // Don't want ERR bit
+
87  false // Keep full sample range
+
88  );
+
89 
+ + + +
93 
+
94  // Reading from constant address, writing to incrementing byte addresses
+ + +
97  channel_config_set_write_increment(&cfg, false); // we don't really want a fifo, just keep reading to the same address
+
98 
+
99  // Pace transfers based on availability of ADC samples
+ +
101 
+ +
103  &rp2040_adc_result, // dst
+
104  &adc_hw->fifo, // src
+
105  1, // transfer count
+
106  true // start immediately
+
107  );
+
108 
+
109  // we want notification, when a sample has arrived
+ + +
112  irq_set_enabled(DMA_IRQ_0, true);
+ +
114 }
+
115 
+ +
117  if (!dma_channel_get_irq0_status(rp2040_adc_dma_chan)) return; // shared handler may get called on unrelated events
+
118  dma_channel_acknowledge_irq0(rp2040_adc_dma_chan); // clear interrupt flag
+
119  //adc_run(false); // adc not running continuous
+
120  //adc_fifo_drain(); // no need to drain fifo, the dma transfer did that
+
121  dma_channel_set_trans_count(rp2040_adc_dma_chan, 1, true); // set up for another read
+
122  advanceADCStep();
+
123 }
+
124 
+
125 #endif // MOZZI_ANALOG_READ
+
126 
+
127 ////// END analog input code ////////
+
128 
+
129 
+
130 ////// BEGIN audio output code //////
+
131 #define LOOP_YIELD tight_loop_contents(); // apparently needed, among other things, to service the alarm pool
+
132 
+
133 
+
134 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
135 #include <hardware/pwm.h>
+
136 
+
137 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
138 inline void audioOutput(const AudioOutput f) {
+ +
140 # if (MOZZI_AUDIO_CHANNELS > 1)
+ +
142 # endif
+
143 }
+
144 # endif // MOZZI_OUTPUT_PWM
+
145 
+
146 } // namespace MozziPrivate
+
147 #include <pico/time.h>
+
148 namespace MozziPrivate {
+
149 /** Implementation notes:
+
150  * - For the time being this port uses a very crude approach to audio output: PWM updated by a hardware timer running at MOZZI_AUDIO_RATE
+
151  * - Hardware timer isn't fixed, but rather we claim the first unclaimed one
+
152  * - Quite pleasently, the RP2040 latches PWM duty cycle, so we do not have to worry about updating whilst in the middle of the previous PWM cycle.
+
153  * - The more simple add_repeating_timer_us has appers to have far too much jitter
+
154  * - Using DMA transfers, instead of a manual timer, would be much more elegant, but I'll leave that as an exercise to the reader ;-)
+
155  * - Not to mention PWM output, etc.
+
156  */
+ + + +
160 
+ +
162  do {
+ + +
165  // NOTE: hardware_alarm_set_target returns true, if the target was already missed. In that case, keep pushing samples, until we have caught up.
+ +
167 }
+
168 
+
169 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
+
170 } // namespace MozziPrivate
+
171 #include <I2S.h>
+
172 namespace MozziPrivate {
+
173 I2S i2s(OUTPUT);
+
174 
+
175 inline bool canBufferAudioOutput() {
+
176  return (i2s.availableForWrite());
+
177 }
+
178 
+
179 inline void audioOutput(const AudioOutput f) {
+
180 
+
181 # if (MOZZI_AUDIO_BITS == 8)
+
182 # if (MOZZI_AUDIO_CHANNELS > 1)
+
183  i2s.write8(f.l(), f.r());
+
184 # else
+
185  i2s.write8(f.l(), 0);
+
186 # endif
+
187 
+
188 # elif (MOZZI_AUDIO_BITS == 16)
+
189 # if (MOZZI_AUDIO_CHANNELS > 1)
+
190  i2s.write16(f.l(), f.r());
+
191 # else
+
192  i2s.write16(f.l(), 0);
+
193 # endif
+
194 
+
195 # elif (MOZZI_AUDIO_BITS == 24)
+
196 # if (MOZZI_AUDIO_CHANNELS > 1)
+
197  i2s.write24(f.l(), f.r());
+
198 # else
+
199  i2s.write24(f.l(), 0);
+
200 # endif
+
201 
+
202 # elif (MOZZI_AUDIO_BITS == 32)
+
203 # if (MOZZI_AUDIO_CHANNELS > 1)
+
204  i2s.write32(f.l(), f.r());
+
205 # else
+
206  i2s.write32(f.l(), 0);
+
207 # endif
+
208 # else
+
209 # error Invalid number of MOZZI_AUDIO_BITS configured
+
210 # endif
+
211 
+
212 }
+
213 #endif
+
214 
+
215 
+
216 static void startAudio() {
+
217 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
218  // calling analogWrite for the first time will try to init the pwm frequency and range on all pins. We don't want that happening after we've set up our own,
+
219  // so we start off with a dummy call to analogWrite:
+
220  analogWrite(MOZZI_AUDIO_PIN_1, MOZZI_AUDIO_BIAS);
+
221  // Set up fast PWM on the output pins
+
222  // TODO: This is still very crude!
+
223  pwm_config c = pwm_get_default_config();
+
224  pwm_config_set_clkdiv(&c, 1); // Fastest we can get: PWM clock running at full CPU speed
+
225  pwm_config_set_wrap(&c, 1l << MOZZI_AUDIO_BITS); // 11 bits output resolution means FCPU / 2048 values per second, which is around 60kHz for 133Mhz clock speed.
+
226  pwm_init(pwm_gpio_to_slice_num(MOZZI_AUDIO_PIN_1), &c, true);
+
227  gpio_set_function(MOZZI_AUDIO_PIN_1, GPIO_FUNC_PWM);
+
228  gpio_set_drive_strength(MOZZI_AUDIO_PIN_1, GPIO_DRIVE_STRENGTH_12MA); // highest we can get
+
229 # if (MOZZI_AUDIO_CHANNELS > 1)
+
230 # if ((MOZZI_AUDIO_PIN_1 / 2) != (MOZZI_AUDIO_PIN_1 / 2))
+
231 # error Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. Adjust MOZZI_AUDIO_PIN_1/2 .
+
232 # endif
+
233  gpio_set_function(MOZZI_AUDIO_PIN_2, GPIO_FUNC_PWM);
+
234  gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get
+
235 # endif
+
236 #endif
+
237 
+
238 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
239  for (audio_update_alarm_num = 0; audio_update_alarm_num < 4; ++audio_update_alarm_num) {
+
240  if (!hardware_alarm_is_claimed(audio_update_alarm_num)) {
+
241  hardware_alarm_claim(audio_update_alarm_num);
+
242  hardware_alarm_set_callback(audio_update_alarm_num, audioOutputCallback);
+
243  break;
+
244  }
+
245  }
+
246  micros_per_update = 1000000l / MOZZI_AUDIO_RATE;
+
247  do {
+
248  next_audio_update = make_timeout_time_us(micros_per_update);
+
249  // See audioOutputCallback(), above. In _theory_ some interrupt stuff might delay us, here, causing us to miss the first beat (and everything that follows)
+
250  } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update));
+
251 
+
252 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
+
253  i2s.setBCLK(MOZZI_I2S_PIN_BCK);
+
254  i2s.setDATA(MOZZI_I2S_PIN_DATA);
+
255  i2s.setBitsPerSample(MOZZI_AUDIO_BITS);
+
256 
+
257 # if (MOZZI_AUDIO_BITS > 16)
+
258  i2s.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS), 0);
+
259 # else
+
260  i2s.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS/2), 0);
+
261 # endif
+
262 # if MOZZI_IS(MOZZI_I2S_FORMAT, MOZZI_I2S_FORMAT_LSBJ)
+
263  i2s.setLSBJFormat();
+
264 # endif
+
265  i2s.begin(MOZZI_AUDIO_RATE);
+
266 #endif
+
267 }
+
268 
+
269 void stopMozzi() {
+
270 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
271  hardware_alarm_set_callback(audio_update_alarm_num, NULL);
+
272 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
+
273  i2s.end();
+
274 #endif
+
275 
+
276 }
+
277 ////// END audio output code //////
+
278 
+
279 //// BEGIN Random seeding ////////
+
280 void MozziRandPrivate::autoSeed() {
+
281 #warning Automatic random seeding is not implemented on this platform
+
282 }
+
283 //// END Random seeding ////////
+
284 
+
285 } // namespace MozziPrivate
+
286 
+
287 #undef MOZZI_RP2040_BUFFERS
+
288 #undef MOZZI_RP2040_BUFFER_SIZE
diff --git a/extras/doc/html/_mozzi_guts__impl___s_a_m_d_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___s_a_m_d_8hpp_source.html index 48051425d..51434d292 100644 --- a/extras/doc/html/_mozzi_guts__impl___s_a_m_d_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___s_a_m_d_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_SAMD.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,167 @@
MozziGuts_impl_SAMD.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_SAMD21())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 namespace MozziPrivate {
18 
19 ////// BEGIN analog input code ////////
20 #if MOZZI_IS(MOZZI_ANALOG_READ, NOZZI_ANALOG_READ_STANDARD)
21 #error not yet implemented
22 #define getADCReading() 0
23 #define channelNumToIndex(channel) channel
24 uint8_t adcPinToChannelNum(uint8_t pin) {
25  return pin;
26 }
27 void adcStartConversion(uint8_t channel) {
28 }
29 void startSecondADCReadOnCurrentChannel() {
30 }
31 void setupFastAnalogRead(int8_t speed) {
32 }
33 void setupMozziADC(int8_t speed) {
34 }
35 #endif
36 ////// END analog input code ////////
37 
38 
39 
40 //// BEGIN AUDIO OUTPUT code ///////
41 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
42 // These are ARM SAMD21 Timer 5 routines to establish a sample rate interrupt
43 static bool tcIsSyncing() {
44  return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;
45 }
46 
47 static void tcReset() {
48  // Reset TCx
49  TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
50  while (tcIsSyncing())
51  ;
52  while (TC5->COUNT16.CTRLA.bit.SWRST)
53  ;
54 }
55 /* Not currently used, and does not compile with EXTERNAL_AUDIO_OUTPUT
56 static void tcEnd() {
57  // Disable TC5
58  TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
59  while (tcIsSyncing())
60  ;
61  tcReset();
62  analogWrite(AUDIO_CHANNEL_1_PIN, 0);
63 } */
64 
65 static void tcConfigure(uint32_t sampleRate) {
66  // Enable GCLK for TCC2 and TC5 (timer counter input clock)
67  GCLK->CLKCTRL.reg = (uint16_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 |
68  GCLK_CLKCTRL_ID(GCM_TC4_TC5));
69  while (GCLK->STATUS.bit.SYNCBUSY)
70  ;
71 
72  tcReset();
73 
74  // Set Timer counter Mode to 16 bits
75  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
76 
77  // Set TC5 mode as match frequency
78  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
79 
80  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
81 
82  TC5->COUNT16.CC[0].reg = (uint16_t)(SystemCoreClock / sampleRate - 1);
83  while (tcIsSyncing())
84  ;
85 
86  // Configure interrupt request
87  NVIC_DisableIRQ(TC5_IRQn);
88  NVIC_ClearPendingIRQ(TC5_IRQn);
89  NVIC_SetPriority(TC5_IRQn, 0);
90  NVIC_EnableIRQ(TC5_IRQn);
91 
92  // Enable the TC5 interrupt request
93  TC5->COUNT16.INTENSET.bit.MC0 = 1;
94  while (tcIsSyncing())
95  ;
96 }
97 
98 } // namespace MozziPrivate
99 
100 void TC5_Handler(void) __attribute__((weak, alias("samd21AudioOutput")));
101 
102 #ifdef __cplusplus
103 extern "C" {
104 #endif
105 void samd21AudioOutput() {
106  MozziPrivate::defaultAudioOutput();
107  TC5->COUNT16.INTFLAG.bit.MC0 = 1;
108 }
109 #ifdef __cplusplus
110 }
111 #endif
112 
113 namespace MozziPrivate {
114 
115 #endif // MOZZI_AUDIO_MODE
116 
117 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
118 inline void audioOutput(const AudioOutput f) {
119  analogWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
120 }
121 #endif
122 
123 static void startAudio() {
124 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
125 # ifdef ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS
126  {
127  static const int CPLAY_SPEAKER_SHUTDOWN = 11;
128  pinMode(CPLAY_SPEAKER_SHUTDOWN, OUTPUT);
129  digitalWrite(CPLAY_SPEAKER_SHUTDOWN, HIGH);
130  }
131 
132 # endif
133 
134  analogWriteResolution(MOZZI_AUDIO_BITS);
135  analogWrite(MOZZI_AUDIO_PIN_1, 0);
136 #endif
137 
138 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
139  tcConfigure(MOZZI_AUDIO_RATE);
140 #endif
141 }
142 
143 void stopMozzi() {
144  // TODO: implement me
145  interrupts();
146 }
147 //// END AUDIO OUTPUT code ///////
148 
149 //// BEGIN Random seeding ////////
150 void MozziRandPrivate::autoSeed() {
151 #warning Automatic random seeding is not implemented on this platform
152 }
153 //// END Random seeding ////////
154 
155 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_SAMD21.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2020-2024 Adrian Freed 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 #if !(IS_SAMD21())
+
13 # error "Wrong implementation included for this platform"
+
14 #endif
+
15 
+
16 namespace MozziPrivate {
+
17 
+
18 ////// BEGIN analog input code ////////
+
19 #if MOZZI_IS(MOZZI_ANALOG_READ, NOZZI_ANALOG_READ_STANDARD)
+
20 #error not yet implemented
+
21 #define getADCReading() 0
+
22 #define channelNumToIndex(channel) channel
+ +
24  return pin;
+
25 }
+ +
27 }
+ +
29 }
+ +
31 }
+ +
33 }
+
34 #endif
+
35 ////// END analog input code ////////
+
36 
+
37 
+
38 
+
39 //// BEGIN AUDIO OUTPUT code ///////
+
40 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
41 // These are ARM SAMD21 Timer 5 routines to establish a sample rate interrupt
+
42 static bool tcIsSyncing() {
+ +
44 }
+
45 
+
46 static void tcReset() {
+
47  // Reset TCx
+ +
49  while (tcIsSyncing())
+
50  ;
+
51  while (TC5->COUNT16.CTRLA.bit.SWRST)
+
52  ;
+
53 }
+
54 /* Not currently used, and does not compile with EXTERNAL_AUDIO_OUTPUT
+
55 static void tcEnd() {
+
56  // Disable TC5
+
57  TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
+
58  while (tcIsSyncing())
+
59  ;
+
60  tcReset();
+
61  analogWrite(AUDIO_CHANNEL_1_PIN, 0);
+
62 } */
+
63 
+
64 static void tcConfigure(uint32_t sampleRate) {
+
65  // Enable GCLK for TCC2 and TC5 (timer counter input clock)
+ + +
68  while (GCLK->STATUS.bit.SYNCBUSY)
+
69  ;
+
70 
+
71  tcReset();
+
72 
+
73  // Set Timer counter Mode to 16 bits
+ +
75 
+
76  // Set TC5 mode as match frequency
+ +
78 
+ +
80 
+ +
82  while (tcIsSyncing())
+
83  ;
+
84 
+
85  // Configure interrupt request
+ + + + +
90 
+
91  // Enable the TC5 interrupt request
+
92  TC5->COUNT16.INTENSET.bit.MC0 = 1;
+
93  while (tcIsSyncing())
+
94  ;
+
95 }
+
96 
+
97 } // namespace MozziPrivate
+
98 
+
99 void TC5_Handler(void) __attribute__((weak, alias("samd21AudioOutput")));
+
100 
+
101 #ifdef __cplusplus
+
102 extern "C" {
+
103 #endif
+
104 void samd21AudioOutput() {
+ +
106  TC5->COUNT16.INTFLAG.bit.MC0 = 1;
+
107 }
+
108 #ifdef __cplusplus
+
109 }
+
110 #endif
+
111 
+
112 namespace MozziPrivate {
+
113 
+
114 #endif // MOZZI_AUDIO_MODE
+
115 
+
116 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
117 inline void audioOutput(const AudioOutput f) {
+ +
119 }
+
120 #endif
+
121 
+
122 static void startAudio() {
+
123 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
124 # ifdef ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS
+
125  {
+
126  static const int CPLAY_SPEAKER_SHUTDOWN = 11;
+
127  pinMode(CPLAY_SPEAKER_SHUTDOWN, OUTPUT);
+
128  digitalWrite(CPLAY_SPEAKER_SHUTDOWN, HIGH);
+
129  }
+
130 
+
131 # endif
+
132 
+
133  analogWriteResolution(MOZZI_AUDIO_BITS);
+
134  analogWrite(MOZZI_AUDIO_PIN_1, 0);
+
135 #endif
+
136 
+
137 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
138  tcConfigure(MOZZI_AUDIO_RATE);
+
139 #endif
+
140 }
+
141 
+
142 void stopMozzi() {
+
143  // TODO: implement me
+
144  interrupts();
+
145 }
+
146 //// END AUDIO OUTPUT code ///////
+
147 
+
148 //// BEGIN Random seeding ////////
+
149 void MozziRandPrivate::autoSeed() {
+
150 #warning Automatic random seeding is not implemented on this platform
+
151 }
+
152 //// END Random seeding ////////
+
153 
+
154 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl___s_t_m32_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___s_t_m32_8hpp_source.html index ad099a50b..bfc11f278 100644 --- a/extras/doc/html/_mozzi_guts__impl___s_t_m32_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___s_t_m32_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_STM32.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,180 @@
MozziGuts_impl_STM32.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #include "HardwareTimer.h"
14 
15 namespace MozziPrivate {
16 
17 ////// BEGIN analog input code ////////
18 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
19 
20 } // namespace MozziPrivate
21 //#include <STM32ADC.h> // Disabled, here. See hardware_defines.h
22 namespace MozziPrivate {
23 
24 STM32ADC adc(ADC1);
25 uint8_t stm32_current_adc_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform
26 #define getADCReading() adc.getData()
27 #define channelNumToIndex(channel) STM32PinMap(channel)
28 uint8_t adcPinToChannelNum(uint8_t pin) {
29  return pin;
30 }
31 
32 void adcStartConversion(uint8_t channel) {
33  stm32_current_adc_pin = channel;
34  adc.setPins(&stm32_current_adc_pin, 1);
35  adc.startConversion();
36 }
37 
38 static void startSecondADCReadOnCurrentChannel() {
39  adc.setPins(&stm32_current_adc_pin, 1);
40  adc.startConversion();
41 }
42 
43 void stm32_adc_eoc_handler() {
44  advanceADCStep();
45 }
46 
47 void setupMozziADC(int8_t speed) {
48  adc.attachInterrupt(stm32_adc_eoc_handler);
49 }
50 
51 
52 inline uint8_t STM32PinMap(uint8_t pin)
53 {
54  if (pin > 15) return pin-8;
55  else return pin;
56 }
57 
58 void setupFastAnalogRead(int8_t speed) {
59  // NOTE: These picks are pretty arbitrary. Further available options are 7_5, 28_5, 55_5, 71_5 and 239_5 (i.e. 7.5 ADC cylces, etc.)
60  if (speed == FASTEST_ADC) adc.setSampleRate(ADC_SMPR_1_5);
61  else if (speed == FASTER_ADC) adc.setSampleRate(ADC_SMPR_13_5);
62  else (adc.setSampleRate(ADC_SMPR_41_5));
63 }
64 #endif
65 
66 ////// END analog input code ////////
67 
68 
69 
70 //// BEGIN AUDIO OUTPUT code ///////
71 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
72 HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER);
73 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
74 HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER);
75 HardwareTimer audio_pwm_timer(MOZZI_AUDIO_PWM_TIMER);
76 
77 inline void audioOutput(const AudioOutput f) {
78 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
79  pwmWrite(MOZZI_AUDIO_PIN_1, (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_CHANNEL);
80  pwmWrite(MOZZI_AUDIO_PIN_1_LOW, (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1));
81 # else
82  pwmWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
83 # if (MOZZI_AUDIO_CHANNELS > 1)
84  pwmWrite(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS);
85 # endif
86 #endif
87 }
88 #endif
89 
90 static void startAudio() {
91 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
92  audio_update_timer.pause();
93  //audio_update_timer.setPeriod(1000000UL / MOZZI_AUDIO_RATE);
94  // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors
95  uint32_t period_cyc = F_CPU / MOZZI_AUDIO_RATE;
96  uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1);
97  uint16_t overflow = (uint16_t)((period_cyc + (prescaler / 2)) / prescaler);
98  audio_update_timer.setPrescaleFactor(prescaler);
99  audio_update_timer.setOverflow(overflow);
100  audio_update_timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
101  audio_update_timer.setCompare(TIMER_CH1,
102  1); // Interrupt 1 count after each update
103  audio_update_timer.attachInterrupt(TIMER_CH1, defaultAudioOutput);
104  audio_update_timer.refresh();
105  audio_update_timer.resume();
106 #endif
107 
108 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
109  pinMode(MOZZI_AUDIO_PIN_1, PWM);
110 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
111  pinMode(MOZZI_AUDIO_PIN_1_LOW, PWM);
112 # elif (MOZZI_AUDIO_CHANNELS > 1)
113  pinMode(MOZZI_AUDIO_PIN_2, PWM);
114 # endif
115 
116 # define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL))
117 # if MAX_CARRIER_FREQ < MOZZI_AUDIO_RATE
118 # error Configured audio resolution is definitely too high at the configured audio rate (and the given CPU speed)
119 # elif MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 3)
120 # warning Configured audio resolution may be higher than optimal at the configured audio rate (and the given CPU speed)
121 # endif
122 
123 # if MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 5)
124  // Generate as fast a carrier as possible
125  audio_pwm_timer.setPrescaleFactor(1);
126 # else
127  // No point in generating arbitrarily high carrier frequencies. In fact, if
128  // there _is_ any headroom, give the PWM pin more time to swing from HIGH to
129  // LOW and BACK, cleanly
130  audio_pwm_timer.setPrescaleFactor((int)MAX_CARRIER_FREQ / (MOZZI_AUDIO_RATE * 5));
131 # endif
132  audio_pwm_timer.setOverflow(
133  1 << MOZZI_AUDIO_BITS_PER_CHANNEL); // Allocate enough room to write all
134  // intended bits
135 # undef MAX_CARRIER_FREQ // no longer needed
136 #endif
137 }
138 
139 void stopMozzi() {
140 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
141  audio_update_timer.pause();
142 #endif
143 }
144 
145 //// END AUDIO OUTPUT code ///////
146 
147 //// BEGIN Random seeding ////////
148 void MozziRandPrivate::autoSeed() {
149  // Unfortunately the internal temp sensor on STM32s does _not_ appear to create a lot of noise.
150  // Ironically, the calls to calibrate help induce some random noise. You're still fairly likely to produce two equal
151  // random seeds in two subsequent runs, however.
152  adc.enableInternalReading();
153  union {
154  float cf;
155  uint32_t ci;
156  } conv;
157  conv.cf = adc.readTemp();
158  x=x^conv.ci;
159  adc.calibrate();
160  conv.cf = adc.readTemp();
161  y=y^conv.ci;
162  adc.calibrate();
163  conv.cf = adc.readTemp();
164  z=z^conv.ci;
165 }
166 //// END Random seeding ////////
167 
168 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_STM32.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2020-2024 Thomas Friedrichsmeier 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 #include "HardwareTimer.h"
+
13 
+
14 namespace MozziPrivate {
+
15 
+
16 ////// BEGIN analog input code ////////
+
17 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
18 
+
19 } // namespace MozziPrivate
+
20 //#include <STM32ADC.h> // Disabled, here. See hardware_defines.h
+
21 namespace MozziPrivate {
+
22 
+ +
24 uint8_t stm32_current_adc_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform
+
25 #define getADCReading() adc.getData()
+
26 #define channelNumToIndex(channel) STM32PinMap(channel)
+ +
28  return pin;
+
29 }
+
30 
+ + + + +
35 }
+
36 
+ + + +
40 }
+
41 
+
42 void stm32_adc_eoc_handler() {
+ +
44 }
+
45 
+ + +
48 }
+
49 
+
50 
+ +
52 {
+
53  if (pin > 15) return pin-8;
+
54  else return pin;
+
55 }
+
56 
+ +
58  // NOTE: These picks are pretty arbitrary. Further available options are 7_5, 28_5, 55_5, 71_5 and 239_5 (i.e. 7.5 ADC cylces, etc.)
+ + + +
62 }
+
63 #endif
+
64 
+
65 ////// END analog input code ////////
+
66 
+
67 
+
68 
+
69 //// BEGIN AUDIO OUTPUT code ///////
+
70 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+ +
72 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
+ + +
75 
+
76 inline void audioOutput(const AudioOutput f) {
+
77 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+ + +
80 # else
+ +
82 # if (MOZZI_AUDIO_CHANNELS > 1)
+ +
84 # endif
+
85 #endif
+
86 }
+
87 #endif
+
88 
+
89 static void startAudio() {
+
90 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
91  audio_update_timer.pause();
+
92  //audio_update_timer.setPeriod(1000000UL / MOZZI_AUDIO_RATE);
+
93  // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors
+
94  uint32_t period_cyc = F_CPU / MOZZI_AUDIO_RATE;
+
95  uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1);
+
96  uint16_t overflow = (uint16_t)((period_cyc + (prescaler / 2)) / prescaler);
+
97  audio_update_timer.setPrescaleFactor(prescaler);
+
98  audio_update_timer.setOverflow(overflow);
+
99  audio_update_timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
+
100  audio_update_timer.setCompare(TIMER_CH1,
+
101  1); // Interrupt 1 count after each update
+
102  audio_update_timer.attachInterrupt(TIMER_CH1, defaultAudioOutput);
+
103  audio_update_timer.refresh();
+
104  audio_update_timer.resume();
+
105 #endif
+
106 
+
107 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
+
108  pinMode(MOZZI_AUDIO_PIN_1, PWM);
+
109 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
110  pinMode(MOZZI_AUDIO_PIN_1_LOW, PWM);
+
111 # elif (MOZZI_AUDIO_CHANNELS > 1)
+
112  pinMode(MOZZI_AUDIO_PIN_2, PWM);
+
113 # endif
+
114 
+
115 # define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL))
+
116 # if MAX_CARRIER_FREQ < MOZZI_AUDIO_RATE
+
117 # error Configured audio resolution is definitely too high at the configured audio rate (and the given CPU speed)
+
118 # elif MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 3)
+
119 # warning Configured audio resolution may be higher than optimal at the configured audio rate (and the given CPU speed)
+
120 # endif
+
121 
+
122 # if MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 5)
+
123  // Generate as fast a carrier as possible
+
124  audio_pwm_timer.setPrescaleFactor(1);
+
125 # else
+
126  // No point in generating arbitrarily high carrier frequencies. In fact, if
+
127  // there _is_ any headroom, give the PWM pin more time to swing from HIGH to
+
128  // LOW and BACK, cleanly
+
129  audio_pwm_timer.setPrescaleFactor((int)MAX_CARRIER_FREQ / (MOZZI_AUDIO_RATE * 5));
+
130 # endif
+
131  audio_pwm_timer.setOverflow(
+
132  1 << MOZZI_AUDIO_BITS_PER_CHANNEL); // Allocate enough room to write all
+
133  // intended bits
+
134 # undef MAX_CARRIER_FREQ // no longer needed
+
135 #endif
+
136 }
+
137 
+
138 void stopMozzi() {
+
139 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
140  audio_update_timer.pause();
+
141 #endif
+
142 }
+
143 
+
144 //// END AUDIO OUTPUT code ///////
+
145 
+
146 //// BEGIN Random seeding ////////
+
147 void MozziRandPrivate::autoSeed() {
+
148  // Unfortunately the internal temp sensor on STM32s does _not_ appear to create a lot of noise.
+
149  // Ironically, the calls to calibrate help induce some random noise. You're still fairly likely to produce two equal
+
150  // random seeds in two subsequent runs, however.
+ +
152  union {
+
153  float cf;
+
154  uint32_t ci;
+
155  } conv;
+
156  conv.cf = adc.readTemp();
+
157  x=x^conv.ci;
+
158  adc.calibrate();
+
159  conv.cf = adc.readTemp();
+
160  y=y^conv.ci;
+
161  adc.calibrate();
+
162  conv.cf = adc.readTemp();
+
163  z=z^conv.ci;
+
164 }
+
165 //// END Random seeding ////////
+
166 
+
167 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl___s_t_m32duino_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___s_t_m32duino_8hpp_source.html index 88d0f66a3..d82fe388f 100644 --- a/extras/doc/html/_mozzi_guts__impl___s_t_m32duino_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___s_t_m32duino_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_STM32duino.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,196 @@
MozziGuts_impl_STM32duino.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #include "HardwareTimer.h"
14 
15 namespace MozziPrivate {
16 ////// BEGIN analog input code ////////
17 
18 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
19 // Notes on ADC implementation: So in hours I could not get IRQ-driven ADC to work, much less in a way that should work across the whole STM32 family.
20 // Instead, this code resorts to polling, but contrary to the regular implementation, it sets does so non-blocking. Polling is done from inside audioHook().
21 // Not terribly efficient, but seems to work ok.
22 //
23 // All this still involves coping much, much more low level detail, than I would like. Most of that is moved to MozziGuts_impl_STM32duino_analog.hpp .
24 // If this core ever gets a more advanced ADC API, we should definitely switch to using that.
25 
26 #define getADCReading() HAL_ADC_GetValue(&AdcHandle)
27 
28 // NOTE: a single uint8_t for ADC channel is no good, here, as we may be dealing with serval distinct ADCs servicing the pins.
29 // However, there is a real danger of overflowing an int8_t storage (as is used as an intermediate), so subtract min pin number.
30 #define channelNumToIndex(channel) channel
31 uint8_t adcPinToChannelNum(uint8_t pin) {
32  return pin - PNUM_ANALOG_BASE;
33 }
34 
35 uint32_t adc_pins_initialized = 0;
36 int16_t previously_sampled_pin = -1;
37 bool conversion_running = false;
38 ADC_HandleTypeDef AdcHandle = {};
39 
40 } // namespace MozziPrivate
41 #include "MozziGuts_impl_STM32duino_analog.hpp"
42 namespace MozziPrivate {
43 
44 void adcStartConversion(int8_t pin) {
45  if (pin != previously_sampled_pin) {
46  if (conversion_running) {
47  HAL_ADC_Stop(&AdcHandle);
48  HAL_ADC_DeInit(&AdcHandle);
49  }
50  previously_sampled_pin = pin;
51  uint32_t mask = 1 << pin;
52  if (!(adc_pins_initialized & mask)) {
53  analogRead(pin+PNUM_ANALOG_BASE); // I have no idea, what black magic analogRead() performs, but it seems to be needed - once - on STM32F411
54  adc_pins_initialized += mask;
55  }
56  }
57  adc_setup_read(analogInputToPinName(pin+PNUM_ANALOG_BASE), 16); // resolution will be limited to max available, anyway, so let's request 16 bits
58  conversion_running = true;
59 }
60 
61 void startSecondADCReadOnCurrentChannel() {
62  HAL_ADC_Start(&AdcHandle);
63  conversion_running = true;
64 }
65 
66 void setupMozziADC(int8_t /*speed*/) {
67 }
68 
69 #define AUDIO_HOOK_HOOK checkADCConversionComplete();
70 
71 void checkADCConversionComplete() {
72  if (!conversion_running) return;
73  if(HAL_ADC_PollForConversion(&AdcHandle, 0) == HAL_OK) {
74  conversion_running = false;
75  advanceADCStep();
76  }
77 }
78 
79 #endif
80 
81 void setupFastAnalogRead(int8_t /*speed*/) {
82 }
83 
84 ////// END analog input code ////////
85 ////// END analog input code ////////
86 
87 
88 
89 //// BEGIN AUDIO OUTPUT code ///////
90 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
91 HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER);
92 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
93 HardwareTimer audio_update_timer(MOZZI_AUDIO_UPDATE_TIMER);
94 HardwareTimer *pwm_timer_ht;
95 PinName output_pin_1 = digitalPinToPinName(MOZZI_AUDIO_PIN_1);
96 uint32_t pwm_timer_channel_1 = STM_PIN_CHANNEL(pinmap_function(output_pin_1, PinMap_TIM));
97 
98 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
99 PinName output_pin_1_low = digitalPinToPinName(MOZZI_AUDIO_PIN_1_LOW);
100 uint32_t pwm_timer_channel_1_low = STM_PIN_CHANNEL(pinmap_function(output_pin_1_low, PinMap_TIM));
101 # elif (MOZZI_AUDIO_CHANNELS > 1)
102 PinName output_pin_2 = digitalPinToPinName(MOZZI_AUDIO_PIN_2);
103 uint32_t pwm_timer_channel_2 = STM_PIN_CHANNEL(pinmap_function(output_pin_2, PinMap_TIM));
104 # endif
105 
106 inline void audioOutput(const AudioOutput f) {
107 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
108  pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, (f.l()+MOZZI_AUDIO_BIAS) >> MOZZI_AUDIO_BITS_PER_CHANNEL);
109  pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1_low, (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1));
110 # else
111  pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, f.l()+MOZZI_AUDIO_BIAS);
112 # if (MOZZI_AUDIO_CHANNELS > 1)
113  pwm_timer_ht->setCaptureCompare(pwm_timer_channel_2, f.r()+MOZZI_AUDIO_BIAS);
114 # endif
115 #endif
116 }
117 #endif
118 
119 static void startAudio() {
120 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
121  audio_update_timer.pause();
122  //audio_update_timer.setPeriod(1000000UL / MOZZI_AUDIO_RATE);
123  // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors
124  uint32_t period_cyc = F_CPU / MOZZI_AUDIO_RATE;
125  uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1);
126  uint16_t overflow = (uint16_t)((period_cyc + (prescaler / 2)) / prescaler);
127  audio_update_timer.setPrescaleFactor(prescaler);
128  audio_update_timer.setOverflow(overflow);
129  audio_update_timer.setMode(/* channel */ 1, TIMER_OUTPUT_COMPARE);
130  audio_update_timer.setCaptureCompare(/* channel */ 1, 1); // Interrupt 1 count after each update
131  audio_update_timer.attachInterrupt(/* channel */ 1, defaultAudioOutput);
132  audio_update_timer.refresh();
133 #endif
134 
135 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
136  // Configure PWM output
137  pinMode(MOZZI_AUDIO_PIN_1, OUTPUT);
138 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
139  pinMode(MOZZI_AUDIO_PIN_1_LOW, OUTPUT);
140 # elif (MOZZI_AUDIO_CHANNELS > 1)
141  pinMode(MOZZI_AUDIO_PIN_2, OUTPUT);
142 # endif
143 
144 # define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL))
145  // static_assert(MAX_CARRIER_FREQ >= MOZZI_AUDIO_RATE); // Unfortunately, we cannot test this at compile time. F_CPU expands to a runtime variable
146  TIM_TypeDef *pwm_timer_tim = (TIM_TypeDef *) pinmap_peripheral(output_pin_1, PinMap_TIM);
147  pwm_timer_ht = new HardwareTimer(pwm_timer_tim);
148  pwm_timer_ht->setMode(pwm_timer_channel_1, TIMER_OUTPUT_COMPARE_PWM1, output_pin_1);
149 # if MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 5)
150  // Generate as fast a carrier as possible
151  pwm_timer_ht->setPrescaleFactor(1);
152 # else
153  // No point in generating arbitrarily high carrier frequencies. In fact, if
154  // there _is_ any headroom, give the PWM pin more time to swing from HIGH to
155  // LOW and BACK, cleanly
156  pwm_timer_ht->setPrescaleFactor((int)MAX_CARRIER_FREQ / (MOZZI_AUDIO_RATE * 5)); // as fast as possible
157 # endif
158 // Allocate enough room to write all intended bits
159  pwm_timer_ht->setOverflow(1 << MOZZI_AUDIO_BITS_PER_CHANNEL);
160  pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, MOZZI_AUDIO_BIAS /*, resolution */);
161 
162  pwm_timer_ht->resume();
163 #endif
164 
165 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
166  audio_update_timer.resume();
167 #endif
168 }
169 
170 void stopMozzi() {
171 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
172  audio_update_timer.pause();
173 #endif
174 }
175 
176 //// END AUDIO OUTPUT code ///////
177 
178 //// BEGIN Random seeding ////////
179 void MozziRandPrivate::autoSeed() {
180 #warning Automatic random seeding is not implemented on this platform
181 }
182 //// END Random seeding ////////
183 
184 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
-
void setupFastAnalogRead(int8_t)
This is automatically called in startMozzi.
+
1 /*
+
2  * MozziGuts_impl_STM32duino.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 #include "HardwareTimer.h"
+
13 
+
14 namespace MozziPrivate {
+
15 ////// BEGIN analog input code ////////
+
16 
+
17 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
18 // Notes on ADC implementation: So in hours I could not get IRQ-driven ADC to work, much less in a way that should work across the whole STM32 family.
+
19 // Instead, this code resorts to polling, but contrary to the regular implementation, it sets does so non-blocking. Polling is done from inside audioHook().
+
20 // Not terribly efficient, but seems to work ok.
+
21 //
+
22 // All this still involves coping much, much more low level detail, than I would like. Most of that is moved to MozziGuts_impl_STM32duino_analog.hpp .
+
23 // If this core ever gets a more advanced ADC API, we should definitely switch to using that.
+
24 
+
25 #define getADCReading() HAL_ADC_GetValue(&AdcHandle)
+
26 
+
27 // NOTE: a single uint8_t for ADC channel is no good, here, as we may be dealing with serval distinct ADCs servicing the pins.
+
28 // However, there is a real danger of overflowing an int8_t storage (as is used as an intermediate), so subtract min pin number.
+
29 #define channelNumToIndex(channel) channel
+ +
31  return pin - PNUM_ANALOG_BASE;
+
32 }
+
33 
+ + +
36 bool conversion_running = false;
+ +
38 
+
39 } // namespace MozziPrivate
+
40 #include "MozziGuts_impl_STM32duino_analog.hpp"
+
41 namespace MozziPrivate {
+
42 
+ +
44  if (pin != previously_sampled_pin) {
+
45  if (conversion_running) {
+ + +
48  }
+ +
50  uint32_t mask = 1 << pin;
+
51  if (!(adc_pins_initialized & mask)) {
+
52  analogRead(pin+PNUM_ANALOG_BASE); // I have no idea, what black magic analogRead() performs, but it seems to be needed - once - on STM32F411
+ +
54  }
+
55  }
+
56  adc_setup_read(analogInputToPinName(pin+PNUM_ANALOG_BASE), 16); // resolution will be limited to max available, anyway, so let's request 16 bits
+
57  conversion_running = true;
+
58 }
+
59 
+ + +
62  conversion_running = true;
+
63 }
+
64 
+
65 void setupMozziADC(int8_t /*speed*/) {
+
66 }
+
67 
+
68 #define AUDIO_HOOK_HOOK checkADCConversionComplete();
+
69 
+ +
71  if (!conversion_running) return;
+ +
73  conversion_running = false;
+ +
75  }
+
76 }
+
77 
+
78 #endif
+
79 
+
80 void setupFastAnalogRead(int8_t /*speed*/) {
+
81 }
+
82 
+
83 ////// END analog input code ////////
+
84 ////// END analog input code ////////
+
85 
+
86 
+
87 
+
88 //// BEGIN AUDIO OUTPUT code ///////
+
89 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+ +
91 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
+ + + + +
96 
+
97 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+ + +
100 # elif (MOZZI_AUDIO_CHANNELS > 1)
+ + +
103 # endif
+
104 
+
105 inline void audioOutput(const AudioOutput f) {
+
106 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+ + +
109 # else
+ +
111 # if (MOZZI_AUDIO_CHANNELS > 1)
+ +
113 # endif
+
114 #endif
+
115 }
+
116 #endif
+
117 
+
118 static void startAudio() {
+
119 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
120  audio_update_timer.pause();
+
121  //audio_update_timer.setPeriod(1000000UL / MOZZI_AUDIO_RATE);
+
122  // Manually calculate prescaler and overflow instead of using setPeriod, to avoid rounding errors
+
123  uint32_t period_cyc = F_CPU / MOZZI_AUDIO_RATE;
+
124  uint16_t prescaler = (uint16_t)(period_cyc / 65535 + 1);
+
125  uint16_t overflow = (uint16_t)((period_cyc + (prescaler / 2)) / prescaler);
+
126  audio_update_timer.setPrescaleFactor(prescaler);
+
127  audio_update_timer.setOverflow(overflow);
+
128  audio_update_timer.setMode(/* channel */ 1, TIMER_OUTPUT_COMPARE);
+
129  audio_update_timer.setCaptureCompare(/* channel */ 1, 1); // Interrupt 1 count after each update
+
130  audio_update_timer.attachInterrupt(/* channel */ 1, defaultAudioOutput);
+
131  audio_update_timer.refresh();
+
132 #endif
+
133 
+
134 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
+
135  // Configure PWM output
+
136  pinMode(MOZZI_AUDIO_PIN_1, OUTPUT);
+
137 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
138  pinMode(MOZZI_AUDIO_PIN_1_LOW, OUTPUT);
+
139 # elif (MOZZI_AUDIO_CHANNELS > 1)
+
140  pinMode(MOZZI_AUDIO_PIN_2, OUTPUT);
+
141 # endif
+
142 
+
143 # define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL))
+
144  // static_assert(MAX_CARRIER_FREQ >= MOZZI_AUDIO_RATE); // Unfortunately, we cannot test this at compile time. F_CPU expands to a runtime variable
+
145  TIM_TypeDef *pwm_timer_tim = (TIM_TypeDef *) pinmap_peripheral(output_pin_1, PinMap_TIM);
+
146  pwm_timer_ht = new HardwareTimer(pwm_timer_tim);
+
147  pwm_timer_ht->setMode(pwm_timer_channel_1, TIMER_OUTPUT_COMPARE_PWM1, output_pin_1);
+
148 # if MAX_CARRIER_FREQ < (MOZZI_AUDIO_RATE * 5)
+
149  // Generate as fast a carrier as possible
+
150  pwm_timer_ht->setPrescaleFactor(1);
+
151 # else
+
152  // No point in generating arbitrarily high carrier frequencies. In fact, if
+
153  // there _is_ any headroom, give the PWM pin more time to swing from HIGH to
+
154  // LOW and BACK, cleanly
+
155  pwm_timer_ht->setPrescaleFactor((int)MAX_CARRIER_FREQ / (MOZZI_AUDIO_RATE * 5)); // as fast as possible
+
156 # endif
+
157 // Allocate enough room to write all intended bits
+
158  pwm_timer_ht->setOverflow(1 << MOZZI_AUDIO_BITS_PER_CHANNEL);
+
159  pwm_timer_ht->setCaptureCompare(pwm_timer_channel_1, MOZZI_AUDIO_BIAS /*, resolution */);
+
160 
+
161  pwm_timer_ht->resume();
+
162 #endif
+
163 
+
164 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
165  audio_update_timer.resume();
+
166 #endif
+
167 }
+
168 
+
169 void stopMozzi() {
+
170 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
171  audio_update_timer.pause();
+
172 #endif
+
173 }
+
174 
+
175 //// END AUDIO OUTPUT code ///////
+
176 
+
177 //// BEGIN Random seeding ////////
+
178 void MozziRandPrivate::autoSeed() {
+
179 #warning Automatic random seeding is not implemented on this platform
+
180 }
+
181 //// END Random seeding ////////
+
182 
+
183 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl___s_t_m32duino__analog_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___s_t_m32duino__analog_8hpp_source.html index 0e6903497..835cf958f 100644 --- a/extras/doc/html/_mozzi_guts__impl___s_t_m32duino__analog_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___s_t_m32duino__analog_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_STM32duino_analog.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,339 @@
MozziGuts_impl_STM32duino_analog.hpp
-
1 namespace MozziPrivate {
2 // NOTE: The contents of this file are copied mostly verbatim from Arduino_Core_STM32, (c) STMicroelectronics, BSD 3-clause license.
3 static PinName g_current_pin = NC;
4 
5 #ifndef ADC_SAMPLINGTIME
6 #if defined(ADC_SAMPLETIME_8CYCLES_5)
7 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_8CYCLES_5;
8 #elif defined(ADC_SAMPLETIME_12CYCLES)
9 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_12CYCLES;
10 #elif defined(ADC_SAMPLETIME_12CYCLES_5)
11 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_12CYCLES_5;
12 #elif defined(ADC_SAMPLETIME_13CYCLES_5)
13 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_13CYCLES_5;
14 #elif defined(ADC_SAMPLETIME_15CYCLES)
15 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_15CYCLES;
16 #elif defined(ADC_SAMPLETIME_16CYCLES)
17 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_16CYCLES;
18 #elif defined(ADC_SAMPLETIME_19CYCLES_5)
19 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_19CYCLES_5;
20 #endif
21 #endif /* !ADC_SAMPLINGTIME */
22 
23 #if defined(ADC_VER_V5_V90) && !defined(ADC3_SAMPLINGTIME)
24 #define ADC3_SAMPLINGTIME ADC3_SAMPLETIME_24CYCLES_5;
25 #endif
26 
27 #if defined(ADC4_SAMPLETIME_19CYCLES_5) && !defined(ADC4_SAMPLINGTIME)
28 #define ADC4_SAMPLINGTIME ADC4_SAMPLETIME_19CYCLES_5;
29 #endif
30 
31 /*
32  * Minimum ADC sampling time is required when reading
33  * internal channels so set it to max possible value.
34  * It can be defined more precisely by defining:
35  * ADC_SAMPLINGTIME_INTERNAL
36  * to the desired ADC sample time.
37  */
38 #ifndef ADC_SAMPLINGTIME_INTERNAL
39 #if defined(ADC_SAMPLETIME_480CYCLES)
40 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_480CYCLES
41 #elif defined(ADC_SAMPLETIME_384CYCLES)
42 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_384CYCLES
43 #elif defined(ADC_SAMPLETIME_810CYCLES_5)
44 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_810CYCLES_5
45 #elif defined(ADC_SAMPLETIME_814CYCLES)
46 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_814CYCLES
47 #elif defined(ADC_SAMPLETIME_640CYCLES_5)
48 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_640CYCLES_5
49 #elif defined(ADC_SAMPLETIME_601CYCLES_5)
50 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_601CYCLES_5
51 #elif defined(ADC_SAMPLETIME_247CYCLES_5)
52 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_247CYCLES_5
53 #elif defined(ADC_SAMPLETIME_239CYCLES_5)
54 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_239CYCLES_5
55 #elif defined(ADC_SAMPLETIME_160CYCLES_5)
56 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_160CYCLES_5
57 #else
58 #error "ADC sampling time could not be defined for internal channels!"
59 #endif
60 #endif /* !ADC_SAMPLINGTIME_INTERNAL */
61 
62 
63 #ifndef ADC_CLOCK_DIV
64 #ifdef ADC_CLOCK_SYNC_PCLK_DIV4
65 #define ADC_CLOCK_DIV ADC_CLOCK_SYNC_PCLK_DIV4
66 #elif ADC_CLOCK_SYNC_PCLK_DIV2
67 #define ADC_CLOCK_DIV ADC_CLOCK_SYNC_PCLK_DIV2
68 #elif defined(ADC_CLOCK_ASYNC_DIV4)
69 #define ADC_CLOCK_DIV ADC_CLOCK_ASYNC_DIV4
70 #endif
71 #endif /* !ADC_CLOCK_DIV */
72 
73 #ifndef ADC_REGULAR_RANK_1
74 #define ADC_REGULAR_RANK_1 1
75 #endif
76 
77 // adc_read_value() modified to keep only the ADC setup, but not the (blocking) ADC read
78 bool adc_setup_read(PinName pin, uint32_t resolution) {
79  AdcHandle = {};
80  ADC_ChannelConfTypeDef AdcChannelConf = {};
81  uint32_t samplingTime = ADC_SAMPLINGTIME;
82  uint32_t channel = 0;
83  uint32_t bank = 0;
84 
85  if ((pin & PADC_BASE) && (pin < ANA_START)) {
86 #if defined(STM32H7xx) || defined(STM32MP1xx)
87 #ifdef ADC3
88  AdcHandle.Instance = ADC3;
89 #else
90  AdcHandle.Instance = ADC2;
91 #endif
92 #else
93  AdcHandle.Instance = ADC1;
94 #if defined(ADC5) && defined(ADC_CHANNEL_TEMPSENSOR_ADC5)
95  if (pin == PADC_TEMP_ADC5) {
96  AdcHandle.Instance = ADC5;
97  }
98 #endif
99 #endif
100  channel = get_adc_internal_channel(pin);
101  samplingTime = ADC_SAMPLINGTIME_INTERNAL;
102  } else {
103  AdcHandle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC);
104  channel = get_adc_channel(pin, &bank);
105 #if defined(ADC_VER_V5_V90)
106  if (AdcHandle.Instance == ADC3) {
107  samplingTime = ADC3_SAMPLINGTIME;
108  }
109 #endif
110 #if defined(ADC4_SAMPLINGTIME)
111  if (AdcHandle.Instance == ADC4) {
112  samplingTime = ADC4_SAMPLINGTIME;
113  }
114 #endif
115  }
116 
117  if (AdcHandle.Instance == NP) {
118  return 0;
119  }
120 
121 #ifdef ADC_CLOCK_DIV
122  AdcHandle.Init.ClockPrescaler = ADC_CLOCK_DIV; /* (A)synchronous clock mode, input ADC clock divided */
123 #endif
124 #ifdef ADC_RESOLUTION_12B
125  switch (resolution) {
126 #ifdef ADC_RESOLUTION_6B
127  case 6:
128  AdcHandle.Init.Resolution = ADC_RESOLUTION_6B; /* resolution for converted data */
129  break;
130 #endif
131  case 8:
132  AdcHandle.Init.Resolution = ADC_RESOLUTION_8B; /* resolution for converted data */
133  break;
134  case 10:
135  AdcHandle.Init.Resolution = ADC_RESOLUTION_10B; /* resolution for converted data */
136  break;
137  case 12:
138  default:
139  AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* resolution for converted data */
140  break;
141 #ifdef ADC_RESOLUTION_14B
142  case 14:
143  AdcHandle.Init.Resolution = ADC_RESOLUTION_14B; /* resolution for converted data */
144  break;
145 #endif
146 #ifdef ADC_RESOLUTION_16B
147  case 16:
148  AdcHandle.Init.Resolution = ADC_RESOLUTION_16B; /* resolution for converted data */
149  break;
150 #endif
151  }
152 #else
153  UNUSED(resolution);
154 #endif
155 #ifdef ADC_DATAALIGN_RIGHT
156  AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */
157 #endif
158 #ifdef ADC_SCAN_SEQ_FIXED
159  AdcHandle.Init.ScanConvMode = ADC_SCAN_SEQ_FIXED; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
160 #else
161  AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
162 #endif
163 #ifdef ADC_EOC_SINGLE_CONV
164  AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */
165 #endif
166 #if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32F4xx) &&
167  !defined(STM32F7xx) && !defined(ADC1_V2_5)
168  AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
169 #endif
170 #if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32F3xx) &&
171  !defined(STM32F4xx) && !defined(STM32F7xx) && !defined(STM32G4xx) &&
172  !defined(STM32H7xx) && !defined(STM32L4xx) && !defined(STM32L5xx) &&
173  !defined(STM32MP1xx) && !defined(STM32WBxx) || defined(ADC_SUPPORT_2_5_MSPS)
174  AdcHandle.Init.LowPowerAutoPowerOff = DISABLE; /* ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered */
175 #endif
176 #ifdef ADC_CHANNELS_BANK_B
177  AdcHandle.Init.ChannelsBank = bank;
178 #elif defined(ADC_CHANNELS_BANK_A)
179  AdcHandle.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
180 #endif
181  AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */
182 #if !defined(STM32F0xx) && !defined(STM32L0xx)
183  AdcHandle.Init.NbrOfConversion = 1; /* Specifies the number of ranks that will be converted within the regular group sequencer. */
184 #endif
185  AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
186 #if !defined(STM32C0xx) && !defined(STM32F0xx) && !defined(STM32G0xx) &&
187  !defined(STM32L0xx) && !defined(STM32WLxx) && !defined(ADC_SUPPORT_2_5_MSPS)
188  AdcHandle.Init.NbrOfDiscConversion = 0; /* Parameter discarded because sequencer is disabled */
189 #endif
190  AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */
191 #if !defined(STM32F1xx) && !defined(ADC1_V2_5)
192  AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
193 #endif
194 #if !defined(STM32F1xx) && !defined(STM32H7xx) && !defined(STM32MP1xx) &&
195  !defined(ADC1_V2_5)
196  AdcHandle.Init.DMAContinuousRequests = DISABLE; /* DMA one-shot mode selected (not applied to this example) */
197 #endif
198 #ifdef ADC_CONVERSIONDATA_DR
199  AdcHandle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; /* Regular Conversion data stored in DR register only */
200 #endif
201 #ifdef ADC_OVR_DATA_OVERWRITTEN
202  AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */
203 #endif
204 #ifdef ADC_LEFTBITSHIFT_NONE
205  AdcHandle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; /* No bit shift left applied on the final ADC conversion data */
206 #endif
207 
208 #if defined(STM32F0xx)
209  AdcHandle.Init.SamplingTimeCommon = samplingTime;
210 #endif
211 #if defined(STM32C0xx) || defined(STM32G0xx) || defined(STM32U5xx) ||
212  defined(STM32WLxx) || defined(ADC_SUPPORT_2_5_MSPS)
213  AdcHandle.Init.SamplingTimeCommon1 = samplingTime; /* Set sampling time common to a group of channels. */
214  AdcHandle.Init.SamplingTimeCommon2 = samplingTime; /* Set sampling time common to a group of channels, second common setting possible.*/
215 #endif
216 #if defined(STM32L0xx)
217  AdcHandle.Init.LowPowerFrequencyMode = DISABLE; /* To be enabled only if ADC clock < 2.8 MHz */
218  AdcHandle.Init.SamplingTime = samplingTime;
219 #endif
220 #if !defined(STM32F0xx) && !defined(STM32F1xx) && !defined(STM32F2xx) &&
221  !defined(STM32F3xx) && !defined(STM32F4xx) && !defined(STM32F7xx) &&
222  !defined(STM32L1xx) && !defined(ADC_SUPPORT_2_5_MSPS)
223  AdcHandle.Init.OversamplingMode = DISABLE;
224  /* AdcHandle.Init.Oversample ignore for STM32L0xx as oversampling disabled */
225  /* AdcHandle.Init.Oversampling ignored for other as oversampling disabled */
226 #endif
227 #if defined(ADC_CFGR_DFSDMCFG) && defined(DFSDM1_Channel0)
228  AdcHandle.Init.DFSDMConfig = ADC_DFSDM_MODE_DISABLE; /* ADC conversions are not transferred by DFSDM. */
229 #endif
230 #ifdef ADC_TRIGGER_FREQ_HIGH
231  AdcHandle.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
232 #endif
233 #ifdef ADC_VREF_PPROT_NONE
234  AdcHandle.Init.VrefProtection = ADC_VREF_PPROT_NONE;
235 #endif
236 
237  AdcHandle.State = HAL_ADC_STATE_RESET;
238  AdcHandle.DMA_Handle = NULL;
239  AdcHandle.Lock = HAL_UNLOCKED;
240  /* Some other ADC_HandleTypeDef fields exists but not required */
241 
242  g_current_pin = pin; /* Needed for HAL_ADC_MspInit*/
243 
244  if (HAL_ADC_Init(&AdcHandle) != HAL_OK) {
245  return 0;
246  }
247 
248  AdcChannelConf.Channel = channel; /* Specifies the channel to configure into ADC */
249 
250 #if defined(STM32G4xx) || defined(STM32L4xx) || defined(STM32L5xx) ||
251  defined(STM32WBxx)
252  if (!IS_ADC_CHANNEL(&AdcHandle, AdcChannelConf.Channel)) {
253 #else
254  if (!IS_ADC_CHANNEL(AdcChannelConf.Channel)) {
255 #endif
256  return 0;
257  }
258 #if defined(ADC_SCAN_SEQ_FIXED) && defined(ADC_RANK_CHANNEL_NUMBER)
259  AdcChannelConf.Rank = ADC_RANK_CHANNEL_NUMBER; /* Enable the rank of the selected channels when not fully configurable */
260 #else
261  AdcChannelConf.Rank = ADC_REGULAR_RANK_1; /* Specifies the rank in the regular group sequencer */
262 #endif
263 #if !defined(STM32L0xx)
264 #if !defined(STM32G0xx)
265  AdcChannelConf.SamplingTime = samplingTime; /* Sampling time value to be set for the selected channel */
266 #else
267  AdcChannelConf.SamplingTime = ADC_SAMPLINGTIME_COMMON_1; /* Sampling time value to be set for the selected channel */
268 #endif
269 #endif
270 #if defined(ADC_DIFFERENTIAL_ENDED) && !defined(ADC1_V2_5)
271  AdcChannelConf.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */
272  AdcChannelConf.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */
273 #endif
274 #if !defined(STM32C0xx) && !defined(STM32F0xx) && !defined(STM32F1xx) &&
275  !defined(STM32F2xx) && !defined(STM32G0xx) && !defined(STM32L0xx) &&
276  !defined(STM32L1xx) && !defined(STM32WBxx) && !defined(STM32WLxx) &&
277  !defined(ADC1_V2_5)
278  AdcChannelConf.Offset = 0; /* Parameter discarded because offset correction is disabled */
279 #endif
280 #if defined (STM32H7xx) || defined(STM32MP1xx)
281  AdcChannelConf.OffsetRightShift = DISABLE; /* No Right Offset Shift */
282  AdcChannelConf.OffsetSignedSaturation = DISABLE; /* Signed saturation feature is not used */
283 #endif
284 
285  /*##-2- Configure ADC regular channel ######################################*/
286  if (HAL_ADC_ConfigChannel(&AdcHandle, &AdcChannelConf) != HAL_OK) {
287  /* Channel Configuration Error */
288  return 0;
289  }
290 
291 #if defined(ADC_CR_ADCAL) || defined(ADC_CR2_RSTCAL)
292  /*##-2.1- Calibrate ADC then Start the conversion process ####################*/
293 #if defined(ADC_CALIB_OFFSET)
294  if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
295 #elif defined(ADC_SINGLE_ENDED) && !defined(ADC1_V2_5)
296  if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK)
297 #else
298  if (HAL_ADCEx_Calibration_Start(&AdcHandle) != HAL_OK)
299 #endif
300  {
301  /* ADC Calibration Error */
302  return 0;
303  }
304 #endif
305 
306  /*##-3- Start the conversion process ####################*/
307  if (HAL_ADC_Start(&AdcHandle) != HAL_OK) {
308  /* Start Conversion Error */
309  return 0;
310  }
311 
312  return HAL_OK;
313 }
314 
315 } // namespace MozziPrivate
#define ADC_REGULAR_RANK_1
+
1 /*
+
2  * MozziGuts_impl_STM32duino_analog.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team
+
7  *
+
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
9  *
+
10 // NOTE: The contents of this file are copied mostly verbatim from Arduino_Core_STM32, (c) STMicroelectronics, BSD 3-clause license.
+
11 */
+
12 
+
13 namespace MozziPrivate {
+
14 static PinName g_current_pin = NC;
+
15 
+
16 #ifndef ADC_SAMPLINGTIME
+
17 #if defined(ADC_SAMPLETIME_8CYCLES_5)
+
18 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_8CYCLES_5;
+
19 #elif defined(ADC_SAMPLETIME_12CYCLES)
+
20 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_12CYCLES;
+
21 #elif defined(ADC_SAMPLETIME_12CYCLES_5)
+
22 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_12CYCLES_5;
+
23 #elif defined(ADC_SAMPLETIME_13CYCLES_5)
+
24 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_13CYCLES_5;
+
25 #elif defined(ADC_SAMPLETIME_15CYCLES)
+
26 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_15CYCLES;
+
27 #elif defined(ADC_SAMPLETIME_16CYCLES)
+
28 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_16CYCLES;
+
29 #elif defined(ADC_SAMPLETIME_19CYCLES_5)
+
30 #define ADC_SAMPLINGTIME ADC_SAMPLETIME_19CYCLES_5;
+
31 #endif
+
32 #endif /* !ADC_SAMPLINGTIME */
+
33 
+
34 #if defined(ADC_VER_V5_V90) && !defined(ADC3_SAMPLINGTIME)
+
35 #define ADC3_SAMPLINGTIME ADC3_SAMPLETIME_24CYCLES_5;
+
36 #endif
+
37 
+
38 #if defined(ADC4_SAMPLETIME_19CYCLES_5) && !defined(ADC4_SAMPLINGTIME)
+
39 #define ADC4_SAMPLINGTIME ADC4_SAMPLETIME_19CYCLES_5;
+
40 #endif
+
41 
+
42 /*
+
43  * Minimum ADC sampling time is required when reading
+
44  * internal channels so set it to max possible value.
+
45  * It can be defined more precisely by defining:
+
46  * ADC_SAMPLINGTIME_INTERNAL
+
47  * to the desired ADC sample time.
+
48  */
+
49 #ifndef ADC_SAMPLINGTIME_INTERNAL
+
50 #if defined(ADC_SAMPLETIME_480CYCLES)
+
51 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_480CYCLES
+
52 #elif defined(ADC_SAMPLETIME_384CYCLES)
+
53 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_384CYCLES
+
54 #elif defined(ADC_SAMPLETIME_810CYCLES_5)
+
55 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_810CYCLES_5
+
56 #elif defined(ADC_SAMPLETIME_814CYCLES)
+
57 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_814CYCLES
+
58 #elif defined(ADC_SAMPLETIME_640CYCLES_5)
+
59 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_640CYCLES_5
+
60 #elif defined(ADC_SAMPLETIME_601CYCLES_5)
+
61 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_601CYCLES_5
+
62 #elif defined(ADC_SAMPLETIME_247CYCLES_5)
+
63 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_247CYCLES_5
+
64 #elif defined(ADC_SAMPLETIME_239CYCLES_5)
+
65 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_239CYCLES_5
+
66 #elif defined(ADC_SAMPLETIME_160CYCLES_5)
+
67 #define ADC_SAMPLINGTIME_INTERNAL ADC_SAMPLETIME_160CYCLES_5
+
68 #else
+
69 #error "ADC sampling time could not be defined for internal channels!"
+
70 #endif
+
71 #endif /* !ADC_SAMPLINGTIME_INTERNAL */
+
72 
+
73 
+
74 #ifndef ADC_CLOCK_DIV
+
75 #ifdef ADC_CLOCK_SYNC_PCLK_DIV4
+
76 #define ADC_CLOCK_DIV ADC_CLOCK_SYNC_PCLK_DIV4
+
77 #elif ADC_CLOCK_SYNC_PCLK_DIV2
+
78 #define ADC_CLOCK_DIV ADC_CLOCK_SYNC_PCLK_DIV2
+
79 #elif defined(ADC_CLOCK_ASYNC_DIV4)
+
80 #define ADC_CLOCK_DIV ADC_CLOCK_ASYNC_DIV4
+
81 #endif
+
82 #endif /* !ADC_CLOCK_DIV */
+
83 
+
84 #ifndef ADC_REGULAR_RANK_1
+
85 #define ADC_REGULAR_RANK_1 1
+
86 #endif
+
87 
+
88 // adc_read_value() modified to keep only the ADC setup, but not the (blocking) ADC read
+
89 bool adc_setup_read(PinName pin, uint32_t resolution) {
+
90  AdcHandle = {};
+
91  ADC_ChannelConfTypeDef AdcChannelConf = {};
+
92  uint32_t samplingTime = ADC_SAMPLINGTIME;
+
93  uint32_t channel = 0;
+
94  uint32_t bank = 0;
+
95 
+
96  if ((pin & PADC_BASE) && (pin < ANA_START)) {
+
97 #if defined(STM32H7xx) || defined(STM32MP1xx)
+
98 #ifdef ADC3
+
99  AdcHandle.Instance = ADC3;
+
100 #else
+
101  AdcHandle.Instance = ADC2;
+
102 #endif
+
103 #else
+
104  AdcHandle.Instance = ADC1;
+
105 #if defined(ADC5) && defined(ADC_CHANNEL_TEMPSENSOR_ADC5)
+
106  if (pin == PADC_TEMP_ADC5) {
+
107  AdcHandle.Instance = ADC5;
+
108  }
+
109 #endif
+
110 #endif
+
111  channel = get_adc_internal_channel(pin);
+
112  samplingTime = ADC_SAMPLINGTIME_INTERNAL;
+
113  } else {
+
114  AdcHandle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC);
+
115  channel = get_adc_channel(pin, &bank);
+
116 #if defined(ADC_VER_V5_V90)
+
117  if (AdcHandle.Instance == ADC3) {
+
118  samplingTime = ADC3_SAMPLINGTIME;
+
119  }
+
120 #endif
+
121 #if defined(ADC4_SAMPLINGTIME)
+
122  if (AdcHandle.Instance == ADC4) {
+
123  samplingTime = ADC4_SAMPLINGTIME;
+
124  }
+
125 #endif
+
126  }
+
127 
+
128  if (AdcHandle.Instance == NP) {
+
129  return 0;
+
130  }
+
131 
+
132 #ifdef ADC_CLOCK_DIV
+
133  AdcHandle.Init.ClockPrescaler = ADC_CLOCK_DIV; /* (A)synchronous clock mode, input ADC clock divided */
+
134 #endif
+
135 #ifdef ADC_RESOLUTION_12B
+
136  switch (resolution) {
+
137 #ifdef ADC_RESOLUTION_6B
+
138  case 6:
+
139  AdcHandle.Init.Resolution = ADC_RESOLUTION_6B; /* resolution for converted data */
+
140  break;
+
141 #endif
+
142  case 8:
+
143  AdcHandle.Init.Resolution = ADC_RESOLUTION_8B; /* resolution for converted data */
+
144  break;
+
145  case 10:
+
146  AdcHandle.Init.Resolution = ADC_RESOLUTION_10B; /* resolution for converted data */
+
147  break;
+
148  case 12:
+
149  default:
+
150  AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* resolution for converted data */
+
151  break;
+
152 #ifdef ADC_RESOLUTION_14B
+
153  case 14:
+
154  AdcHandle.Init.Resolution = ADC_RESOLUTION_14B; /* resolution for converted data */
+
155  break;
+
156 #endif
+
157 #ifdef ADC_RESOLUTION_16B
+
158  case 16:
+
159  AdcHandle.Init.Resolution = ADC_RESOLUTION_16B; /* resolution for converted data */
+
160  break;
+
161 #endif
+
162  }
+
163 #else
+
164  UNUSED(resolution);
+
165 #endif
+
166 #ifdef ADC_DATAALIGN_RIGHT
+
167  AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */
+
168 #endif
+
169 #ifdef ADC_SCAN_SEQ_FIXED
+
170  AdcHandle.Init.ScanConvMode = ADC_SCAN_SEQ_FIXED; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
+
171 #else
+
172  AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
+
173 #endif
+
174 #ifdef ADC_EOC_SINGLE_CONV
+
175  AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */
+
176 #endif
+
177 #if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32F4xx) &&
+
178  !defined(STM32F7xx) && !defined(ADC1_V2_5)
+
179  AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
+
180 #endif
+
181 #if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32F3xx) &&
+
182  !defined(STM32F4xx) && !defined(STM32F7xx) && !defined(STM32G4xx) &&
+
183  !defined(STM32H7xx) && !defined(STM32L4xx) && !defined(STM32L5xx) &&
+
184  !defined(STM32MP1xx) && !defined(STM32WBxx) || defined(ADC_SUPPORT_2_5_MSPS)
+
185  AdcHandle.Init.LowPowerAutoPowerOff = DISABLE; /* ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered */
+
186 #endif
+
187 #ifdef ADC_CHANNELS_BANK_B
+
188  AdcHandle.Init.ChannelsBank = bank;
+
189 #elif defined(ADC_CHANNELS_BANK_A)
+
190  AdcHandle.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
+
191 #endif
+
192  AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */
+
193 #if !defined(STM32F0xx) && !defined(STM32L0xx)
+
194  AdcHandle.Init.NbrOfConversion = 1; /* Specifies the number of ranks that will be converted within the regular group sequencer. */
+
195 #endif
+
196  AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
+
197 #if !defined(STM32C0xx) && !defined(STM32F0xx) && !defined(STM32G0xx) &&
+
198  !defined(STM32L0xx) && !defined(STM32WLxx) && !defined(ADC_SUPPORT_2_5_MSPS)
+
199  AdcHandle.Init.NbrOfDiscConversion = 0; /* Parameter discarded because sequencer is disabled */
+
200 #endif
+
201  AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */
+
202 #if !defined(STM32F1xx) && !defined(ADC1_V2_5)
+
203  AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
+
204 #endif
+
205 #if !defined(STM32F1xx) && !defined(STM32H7xx) && !defined(STM32MP1xx) &&
+
206  !defined(ADC1_V2_5)
+
207  AdcHandle.Init.DMAContinuousRequests = DISABLE; /* DMA one-shot mode selected (not applied to this example) */
+
208 #endif
+
209 #ifdef ADC_CONVERSIONDATA_DR
+
210  AdcHandle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; /* Regular Conversion data stored in DR register only */
+
211 #endif
+
212 #ifdef ADC_OVR_DATA_OVERWRITTEN
+
213  AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */
+
214 #endif
+
215 #ifdef ADC_LEFTBITSHIFT_NONE
+
216  AdcHandle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; /* No bit shift left applied on the final ADC conversion data */
+
217 #endif
+
218 
+
219 #if defined(STM32F0xx)
+
220  AdcHandle.Init.SamplingTimeCommon = samplingTime;
+
221 #endif
+
222 #if defined(STM32C0xx) || defined(STM32G0xx) || defined(STM32U5xx) ||
+
223  defined(STM32WLxx) || defined(ADC_SUPPORT_2_5_MSPS)
+
224  AdcHandle.Init.SamplingTimeCommon1 = samplingTime; /* Set sampling time common to a group of channels. */
+
225  AdcHandle.Init.SamplingTimeCommon2 = samplingTime; /* Set sampling time common to a group of channels, second common setting possible.*/
+
226 #endif
+
227 #if defined(STM32L0xx)
+
228  AdcHandle.Init.LowPowerFrequencyMode = DISABLE; /* To be enabled only if ADC clock < 2.8 MHz */
+
229  AdcHandle.Init.SamplingTime = samplingTime;
+
230 #endif
+
231 #if !defined(STM32F0xx) && !defined(STM32F1xx) && !defined(STM32F2xx) &&
+
232  !defined(STM32F3xx) && !defined(STM32F4xx) && !defined(STM32F7xx) &&
+
233  !defined(STM32L1xx) && !defined(ADC_SUPPORT_2_5_MSPS)
+
234  AdcHandle.Init.OversamplingMode = DISABLE;
+
235  /* AdcHandle.Init.Oversample ignore for STM32L0xx as oversampling disabled */
+
236  /* AdcHandle.Init.Oversampling ignored for other as oversampling disabled */
+
237 #endif
+
238 #if defined(ADC_CFGR_DFSDMCFG) && defined(DFSDM1_Channel0)
+
239  AdcHandle.Init.DFSDMConfig = ADC_DFSDM_MODE_DISABLE; /* ADC conversions are not transferred by DFSDM. */
+
240 #endif
+
241 #ifdef ADC_TRIGGER_FREQ_HIGH
+
242  AdcHandle.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
+
243 #endif
+
244 #ifdef ADC_VREF_PPROT_NONE
+
245  AdcHandle.Init.VrefProtection = ADC_VREF_PPROT_NONE;
+
246 #endif
+
247 
+
248  AdcHandle.State = HAL_ADC_STATE_RESET;
+
249  AdcHandle.DMA_Handle = NULL;
+
250  AdcHandle.Lock = HAL_UNLOCKED;
+
251  /* Some other ADC_HandleTypeDef fields exists but not required */
+
252 
+
253  g_current_pin = pin; /* Needed for HAL_ADC_MspInit*/
+
254 
+
255  if (HAL_ADC_Init(&AdcHandle) != HAL_OK) {
+
256  return 0;
+
257  }
+
258 
+
259  AdcChannelConf.Channel = channel; /* Specifies the channel to configure into ADC */
+
260 
+
261 #if defined(STM32G4xx) || defined(STM32L4xx) || defined(STM32L5xx) ||
+
262  defined(STM32WBxx)
+
263  if (!IS_ADC_CHANNEL(&AdcHandle, AdcChannelConf.Channel)) {
+
264 #else
+
265  if (!IS_ADC_CHANNEL(AdcChannelConf.Channel)) {
+
266 #endif
+
267  return 0;
+
268  }
+
269 #if defined(ADC_SCAN_SEQ_FIXED) && defined(ADC_RANK_CHANNEL_NUMBER)
+
270  AdcChannelConf.Rank = ADC_RANK_CHANNEL_NUMBER; /* Enable the rank of the selected channels when not fully configurable */
+
271 #else
+
272  AdcChannelConf.Rank = ADC_REGULAR_RANK_1; /* Specifies the rank in the regular group sequencer */
+
273 #endif
+
274 #if !defined(STM32L0xx)
+
275 #if !defined(STM32G0xx)
+
276  AdcChannelConf.SamplingTime = samplingTime; /* Sampling time value to be set for the selected channel */
+
277 #else
+
278  AdcChannelConf.SamplingTime = ADC_SAMPLINGTIME_COMMON_1; /* Sampling time value to be set for the selected channel */
+
279 #endif
+
280 #endif
+
281 #if defined(ADC_DIFFERENTIAL_ENDED) && !defined(ADC1_V2_5)
+
282  AdcChannelConf.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */
+
283  AdcChannelConf.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */
+
284 #endif
+
285 #if !defined(STM32C0xx) && !defined(STM32F0xx) && !defined(STM32F1xx) &&
+
286  !defined(STM32F2xx) && !defined(STM32G0xx) && !defined(STM32L0xx) &&
+
287  !defined(STM32L1xx) && !defined(STM32WBxx) && !defined(STM32WLxx) &&
+
288  !defined(ADC1_V2_5)
+
289  AdcChannelConf.Offset = 0; /* Parameter discarded because offset correction is disabled */
+
290 #endif
+
291 #if defined (STM32H7xx) || defined(STM32MP1xx)
+
292  AdcChannelConf.OffsetRightShift = DISABLE; /* No Right Offset Shift */
+
293  AdcChannelConf.OffsetSignedSaturation = DISABLE; /* Signed saturation feature is not used */
+
294 #endif
+
295 
+
296  /*##-2- Configure ADC regular channel ######################################*/
+
297  if (HAL_ADC_ConfigChannel(&AdcHandle, &AdcChannelConf) != HAL_OK) {
+
298  /* Channel Configuration Error */
+
299  return 0;
+
300  }
+
301 
+
302 #if defined(ADC_CR_ADCAL) || defined(ADC_CR2_RSTCAL)
+
303  /*##-2.1- Calibrate ADC then Start the conversion process ####################*/
+
304 #if defined(ADC_CALIB_OFFSET)
+
305  if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
+
306 #elif defined(ADC_SINGLE_ENDED) && !defined(ADC1_V2_5)
+
307  if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK)
+
308 #else
+
309  if (HAL_ADCEx_Calibration_Start(&AdcHandle) != HAL_OK)
+
310 #endif
+
311  {
+
312  /* ADC Calibration Error */
+
313  return 0;
+
314  }
+
315 #endif
+
316 
+
317  /*##-3- Start the conversion process ####################*/
+
318  if (HAL_ADC_Start(&AdcHandle) != HAL_OK) {
+
319  /* Start Conversion Error */
+
320  return 0;
+
321  }
+
322 
+
323  return HAL_OK;
+
324 }
+
325 
+
326 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl___t_e_e_n_s_y_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl___t_e_e_n_s_y_8hpp_source.html index d7c28863b..22790eb3c 100644 --- a/extras/doc/html/_mozzi_guts__impl___t_e_e_n_s_y_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl___t_e_e_n_s_y_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_TEENSY.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,141 @@
MozziGuts_impl_TEENSY.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #if !(IS_TEENSY3() || IS_TEENSY4())
14 # error "Wrong implementation included for this platform"
15 #endif
16 
17 #if (IS_TEENSY3() && F_CPU != 48000000)
18 #warning
19  "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino and 48MHz on Teensy 3! Results may vary with other speeds."
20 #endif
21 
22 namespace MozziPrivate {
23 ////// BEGIN analog input code ////////
24 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
25 // required from http://github.com/pedvide/ADC for Teensy 3.*
26 } //namespace MozziPrivate
27 #include <ADC.h>
28 namespace MozziPrivate {
29 
30 ADC *adc; // adc object
31 uint8_t teensy_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform
32 int8_t teensy_adc=0;
33 #define getADCReading() adc->readSingle(teensy_adc)
34 #define channelNumToIndex(channel) teensyPinMap(channel)
35 uint8_t adcPinToChannelNum(uint8_t pin) {
36  return pin;
37 }
38 
39 void setupFastAnalogRead(int8_t speed) {
40  adc->adc0->setAveraging(0);
41  adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED); // could be HIGH_SPEED, noisier
42 #ifdef ADC_DUAL_ADCS
43  adc->adc1->setAveraging(0);
44  adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED);
45 #endif
46 }
47 
48 } // namespace MozziPrivate
49 void adc0_isr(void)
50 {
51  MozziPrivate::advanceADCStep();
52 }
53 namespace MozziPrivate {
54 
55 void setupMozziADC(int8_t speed) {
56  adc = new ADC();
57  adc->adc0->enableInterrupts(adc0_isr); // TODO: is this even correct? Does the function take a parameter? And is adc0_isr a predefined name, or are we free to move this to MozziPrivate?
58 #ifdef ADC_DUAL_ADCS
59  adc->adc1->enableInterrupts(adc0_isr);
60 #endif
61 }
62 
63 void adcStartConversion(uint8_t channel) {
64  teensy_pin = channel; // remember for startSecondADCReadOnCurrentChannel()
65 #ifdef ADC_DUAL_ADCS
66  if (adc->adc0->checkPin(teensy_pin)) teensy_adc = 0;
67  else teensy_adc=1;
68 #endif
69  adc->startSingleRead(teensy_pin,teensy_adc);
70 }
71 
72 static void startSecondADCReadOnCurrentChannel() {
73  adc->startSingleRead(teensy_pin,teensy_adc);
74 }
75 #endif // MOZZI_ANALOG_READ
76 
77 ////// END analog input code ////////
78 
79 
80 
81 //// BEGIN AUDIO OUTPUT code ///////
82 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
83 } // namespace MozziPrivate
84 #include "IntervalTimer.h"
85 namespace MozziPrivate {
86 IntervalTimer timer1;
87 #endif
88 
89 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC)
90 inline void audioOutput(const AudioOutput f) {
91  analogWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
92 # if (MOZZI_AUDIO_CHANNELS > 1)
93  analogWrite(MOZZI_AUDIO_PIN_2, f.r()+MOZZI_AUDIO_BIAS);
94 # endif
95 }
96 #endif
97 
98 static void startAudio() {
99 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC)
100 # if IS_TEENSY3()
101  analogWriteResolution(12);
102 # elif IS_TEENSY4()
103  analogWriteResolution(10);
104  analogWriteFrequency(MOZZI_AUDIO_PIN_1, 146484.38f);
105 # if (MOZZI_AUDIO_CHANNELS > 1)
106  analogWriteFrequency(MOZZI_AUDIO_PIN_2, 146484.38f);
107 # endif // end #if (MOZZI_AUDIO_CHANNELS > 1)
108 # endif // TEENSY3/4
109 #endif
110 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
111  timer1.begin(defaultAudioOutput, 1000000. / MOZZI_AUDIO_RATE);
112 #endif
113 }
114 
115 void stopMozzi() {
116 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
117  timer1.end();
118 #endif
119  interrupts();
120 }
121 //// END AUDIO OUTPUT code ///////
122 
123 //// BEGIN Random seeding ////////
124 void MozziRandPrivate::autoSeed() {
125 #warning Automatic random seeding is not implemented on this platform
126 }
127 //// END Random seeding ////////
128 
129 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_STM32duino.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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 #if !(IS_TEENSY3() || IS_TEENSY4())
+
13 # error "Wrong implementation included for this platform"
+
14 #endif
+
15 
+
16 #if (IS_TEENSY3() && F_CPU != 48000000)
+
17 #warning
+
18  "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino and 48MHz on Teensy 3! Results may vary with other speeds."
+
19 #endif
+
20 
+
21 namespace MozziPrivate {
+
22 ////// BEGIN analog input code ////////
+
23 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
24 // required from http://github.com/pedvide/ADC for Teensy 3.*
+
25 } //namespace MozziPrivate
+
26 #include <ADC.h>
+
27 namespace MozziPrivate {
+
28 
+
29 ADC *adc; // adc object
+
30 uint8_t teensy_pin; // TODO: this is actually a "channel" according to our terminology, but "channel" and "pin" are equal on this platform
+ +
32 #define getADCReading() adc->readSingle(teensy_adc)
+
33 #define channelNumToIndex(channel) teensyPinMap(channel)
+ +
35  return pin;
+
36 }
+
37 
+ +
39  adc->adc0->setAveraging(0);
+
40  adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED); // could be HIGH_SPEED, noisier
+
41 #ifdef ADC_DUAL_ADCS
+
42  adc->adc1->setAveraging(0);
+ +
44 #endif
+
45 }
+
46 
+
47 } // namespace MozziPrivate
+
48 void adc0_isr(void)
+
49 {
+ +
51 }
+
52 namespace MozziPrivate {
+
53 
+ +
55  adc = new ADC();
+
56  adc->adc0->enableInterrupts(adc0_isr); // TODO: is this even correct? Does the function take a parameter? And is adc0_isr a predefined name, or are we free to move this to MozziPrivate?
+
57 #ifdef ADC_DUAL_ADCS
+ +
59 #endif
+
60 }
+
61 
+ +
63  teensy_pin = channel; // remember for startSecondADCReadOnCurrentChannel()
+
64 #ifdef ADC_DUAL_ADCS
+ +
66  else teensy_adc=1;
+
67 #endif
+ +
69 }
+
70 
+ + +
73 }
+
74 #endif // MOZZI_ANALOG_READ
+
75 
+
76 ////// END analog input code ////////
+
77 
+
78 
+
79 
+
80 //// BEGIN AUDIO OUTPUT code ///////
+
81 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
82 } // namespace MozziPrivate
+
83 #include "IntervalTimer.h"
+
84 namespace MozziPrivate {
+ +
86 #endif
+
87 
+
88 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC)
+
89 inline void audioOutput(const AudioOutput f) {
+ +
91 # if (MOZZI_AUDIO_CHANNELS > 1)
+ +
93 # endif
+
94 }
+
95 #endif
+
96 
+
97 static void startAudio() {
+
98 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC)
+
99 # if IS_TEENSY3()
+
100  analogWriteResolution(12);
+
101 # elif IS_TEENSY4()
+
102  analogWriteResolution(10);
+
103  analogWriteFrequency(MOZZI_AUDIO_PIN_1, 146484.38f);
+
104 # if (MOZZI_AUDIO_CHANNELS > 1)
+
105  analogWriteFrequency(MOZZI_AUDIO_PIN_2, 146484.38f);
+
106 # endif // end #if (MOZZI_AUDIO_CHANNELS > 1)
+
107 # endif // TEENSY3/4
+
108 #endif
+
109 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
110  timer1.begin(defaultAudioOutput, 1000000. / MOZZI_AUDIO_RATE);
+
111 #endif
+
112 }
+
113 
+
114 void stopMozzi() {
+
115 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
116  timer1.end();
+
117 #endif
+
118  interrupts();
+
119 }
+
120 //// END AUDIO OUTPUT code ///////
+
121 
+
122 //// BEGIN Random seeding ////////
+
123 void MozziRandPrivate::autoSeed() {
+
124 #warning Automatic random seeding is not implemented on this platform
+
125 }
+
126 //// END Random seeding ////////
+
127 
+
128 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_guts__impl__template_8hpp_source.html b/extras/doc/html/_mozzi_guts__impl__template_8hpp_source.html index 492c126d1..b71fd8ef1 100644 --- a/extras/doc/html/_mozzi_guts__impl__template_8hpp_source.html +++ b/extras/doc/html/_mozzi_guts__impl__template_8hpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziGuts_impl_template.hpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,195 @@
MozziGuts_impl_template.hpp
-
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 /** README!
14  * This file is meant to be used as a template when adding support for a new platform. Please read these instructions, first.
15  *
16  * Files involved:
17  * 1. Modify hardware_defines.h, adding a macro to detect your target platform
18  * 2. Modify MozziGuts.cpp to include MozziGuts_impl_YOURPLATFORM.hpp
19  * 3. Modify internal/config_checks_generic.h to include internal/config_checks_YOURPLATFORM.h
20  * 4. Copy this file to MozziGuts_impl_YOURPLATFORM.hpp and adjust as necessary, same for internal/config_checks_template.h
21  * (If your platform is very similar to an existing port, it may instead be better to modify the existing MozziGuts_impl_XYZ.hpp/config_checks_XYZ.h,
22  * instead of steps 2-3.).
23  * Some platforms may need small modifications to other files as well, e.g. mozzi_pgmspace.h
24  *
25  * How to implement MozziGuts_impl_YOURPLATFORM.hpp:
26  * - Follow the NOTEs provided in this file
27  * - Read the doc at the top of AudioOutput.h for a better understanding of the basic audio output framework
28  * - Take a peek at existing implementations for other hardware (e.g. TEENSY3/4 is rather complete while also simple at the time of this writing)
29  * - Wait for more documentation to arrive
30  * - Ask when in doubt
31  * - Don't forget to provide a PR when done (it does not have to be perfect; e.g. many ports skip analog input, initially)
32  */
33 
34 // The main point of this check is to document, what platform & variants this implementation file is for.
35 #if !(IS_MYPLATFORM())
36 # error "Wrong implementation included for this platform"
37 #endif
38 // Add platform specific includes and declarations, here
39 
40 //#include <my_hardware_header.h>
41 
42 // In order to allow simple yet efficient user configuration, the entire contents of this file are compiled in the same translation unit
43 // as (the main file of) the user sketch. To avoid name clashes, we encapsulate everyghing in a namespace.
44 // For the most part, this namescape can just extend from the start of the file to the end (as shown, here), and you will not have to
45 // worry about it. However, there may be a few situations, where you have to "leave" the MozziPrivate namespace. This includes:
46 // - When you include a further (hardware-dependent library). Consider gathering all includes at the top of this file, instead.
47 // - When you provide definitions for special names, importantly for ISR-functions. If these would be placed in the namespace, the linker would not
48 // recognize them as the definition of the intended ISR-vector. See MozziGuts_impl_AVR.hpp for examples.
49 
50 namespace MozziPrivate {
51 
52 ////// BEGIN analog input code ////////
53 
54 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
55 /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of MOZZI_AUDIO_INPUT (if enabled).
56  *
57  * It is possible, and even recommended, to skip over this section, initially, when starting a new port. Once you have an implementation, be sure to include something like this
58  * in your platform configuration checks:
59  *
60  * // analog reads shall be enabled by default on platforms that support it
61  * #if not defined(MOZZI_ANALOG_READ)
62  * #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
63  * #endif
64  *
65  * Also, of course, remove the #error line, below
66  */
67 #error not yet implemented
68 
69 // Insert here code to read the result of the latest asynchronous conversion, when it is finished.
70 // You can also provide this as a function returning unsigned int, should it be more complex on your platform
71 #define getADCReading() GET_MY_PLATFORM_ADC_REGISTER
72 
73 /** NOTE: On "pins" vs. "channels" vs. "indices"
74  * "Pin" is the pin number as would usually be specified by the user in mozziAnalogRead().
75  * "Channel" is an internal ADC channel number corresponding to that pin. On many platforms this is simply the same as the pin number, on others it differs.
76  * In other words, this is an internal representation of "pin".
77  * "Index" is the index of the reading for a certain pin/channel in the array of analog_readings, ranging from 0 to NUM_ANALOG_PINS. This, again may be the
78  * same as "channel" (e.g. on AVR), however, on platforms where ADC-capable "channels" are not numbered sequentially starting from 0, the channel needs
79  * to be converted to a suitable index.
80  *
81  * In summary, the semantics are roughly
82  * mozziAnalogRead(pin) -> _ADCimplementation_(channel) -> analog_readings[index]
83  * Implement adcPinToChannelNum() and channelNumToIndex() to perform the appropriate mapping.
84  */
85 // NOTE: Theoretically, adcPinToChannelNum is public API for historical reasons, thus cannot be replaced by a define
86 #define channelNumToIndex(channel) channel
87 uint8_t adcPinToChannelNum(uint8_t pin) {
88  return pin;
89 }
90 
91 /** NOTE: Code needed to trigger a conversion on a new channel */
92 void adcStartConversion(uint8_t channel) {
93 }
94 
95 /** NOTE: Code needed to trigger a subsequent conversion on the latest channel. If your platform has no special code for it, you should store the channel from
96  * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */
97 void startSecondADCReadOnCurrentChannel() {
98 }
99 
100 /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and
101  * possibly calibration. */
102 void setupMozziADC(int8_t speed) {
103  setupFastAnalogRead(speed);
104  // insert further custom code
105 }
106 
107 /* NOTE: Most platforms call a specific function/ISR when conversion is complete. Provide this function, here.
108  * From inside its body, simply call advanceADCStep(). E.g.:
109 void stm32_adc_eoc_handler() {
110  advanceADCStep();
111 }
112 */
113 
114 /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize.
115  * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */
116 void setupFastAnalogRead(int8_t speed) {
117 }
118 
119 #endif
120 
121 ////// END analog input code ////////
122 
123 ////// BEGIN audio output code //////
124 /* NOTE: Some platforms rely on control returning from loop() every so often. However, updateAudio() may take too long (it tries to completely fill the output buffer,
125  * which of course is being drained at the same time, theoretically it may not return at all). If you set this define, it will be called once per audio frame to keep things
126  * running smoothly. */
127 //#define LOOP_YIELD yield();
128 
129 /* NOTE: On some platforms, what can be called in the ISR used to output the sound is limited.
130  * This define can be used, for instance, to output the sound in audioHook() instead to overcome
131  * this limitation (see MozziGuts_impl_MBED.hpp). It can also be used if something needs to be called in audioHook() regarding
132  * analog reads for instance. */
133 //#define AUDIO_HOOK_HOOK
134 
135 /* NOTE: Code sections that are needed for a certain audio mode, only, should be guarded as follows (in this example, code will compile for the
136  * two modes MOZZI_OUTPUT_PWM, and MOZZI_OUTPUT_INTERNAL_DAC (should your port happen to support these two).
137  *
138  * Keep in mind that you probably want to support MOZZI_OUTPUT_EXTERNAL_TIMED, and MOZZI_OUTPUT_EXTERNAL_CUSTOM, too, which is usually very
139  * easy: For both, do *not* provide an audioOutput() function, as this will be provided by the user. For MOZZI_OUTPUT_EXTERNAL_TIMED make sure some
140  * timer is set up to call defaultAudioOutput() at MOZZI_AUDIO_RATE. For MOZZI_OUTPUT_EXTERNAL_CUSTOM, nothing else will be needed. */
141 
142 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC) // just an example!
143 /** NOTE: This is the function that actually write a sample to the output. In case of the two EXTERNAL modes, it is provided by the library user, instead. */
144 inline void audioOutput(const AudioOutput f) {
145  // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_1_PIN, f.l()+MOZZI_AUDIO_BIAS);
146 # if (MOZZI_AUDIO_CHANNELS > 1)
147  // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_2_PIN, f.r()+MOZZI_AUDIO_BIAS);
148 # endif
149 }
150 #endif
151 
152 static void startAudio() {
153  // Add here code to get audio output going. This usually involves:
154  // 1) setting up some DAC mechanism (e.g. setting up a PWM pin with appropriate resolution
155  // 2a) setting up a timer to call defaultAudioOutput() at MOZZI_AUDIO_RATE
156  // OR 2b) setting up a buffered output queue such as I2S (see ESP32 / ESP8266 for examples for this setup)
157 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
158  // [...]
159 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
160  // [...]
161 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
162  // remember that the user may configure MOZZI_OUTPUT_EXTERNAL_TIMED, in which case, you'll want to provide step 2a), and only that.
163 #endif
164 }
165 
166 void stopMozzi() {
167  // Add here code to pause whatever mechanism moves audio samples to the output
168 }
169 ////// END audio output code //////
170 
171 //// BEGIN Random seeding ////////
172 void MozziRandPrivate::autoSeed() {
173  // Add here code to initialize the values of MozziRandPrivate::x, MozziRandPrivate::y, and MozziRandPrivate::z to some random values
174  // This doesn't need to be crypographically safe. If nothing better is available, e.g. try reading an internal temperature sensor
175  // in order to get some noise. It also doesn't have to be fast.
176  // It *should* however ensure that rand() sequences will differ across reboots, after randSeed() has been called.
177  // x, y, and z are already initialized to non-zero, when this function is called.
178  // It's ok to leave this unimplemented, initially.
179 #warning Automatic random seeding is not implemented on this platform
180 }
181 //// END Random seeding ////////
182 
183 } // namespace MozziPrivate
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
+
1 /*
+
2  * MozziGuts_impl_template.hpp
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 /** README!
+
13  * This file is meant to be used as a template when adding support for a new platform. Please read these instructions, first.
+
14  *
+
15  * Files involved:
+
16  * 1. Modify hardware_defines.h, adding a macro to detect your target platform
+
17  * 2. Modify MozziGuts.cpp to include MozziGuts_impl_YOURPLATFORM.hpp
+
18  * 3. Modify internal/config_checks_generic.h to include internal/config_checks_YOURPLATFORM.h
+
19  * 4. Copy this file to MozziGuts_impl_YOURPLATFORM.hpp and adjust as necessary, same for internal/config_checks_template.h
+
20  * (If your platform is very similar to an existing port, it may instead be better to modify the existing MozziGuts_impl_XYZ.hpp/config_checks_XYZ.h,
+
21  * instead of steps 2-3.).
+
22  * Some platforms may need small modifications to other files as well, e.g. mozzi_pgmspace.h
+
23  *
+
24  * How to implement MozziGuts_impl_YOURPLATFORM.hpp:
+
25  * - Follow the NOTEs provided in this file
+
26  * - Read the doc at the top of AudioOutput.h for a better understanding of the basic audio output framework
+
27  * - Take a peek at existing implementations for other hardware (e.g. TEENSY3/4 is rather complete while also simple at the time of this writing)
+
28  * - Wait for more documentation to arrive
+
29  * - Ask when in doubt
+
30  * - Don't forget to provide a PR when done (it does not have to be perfect; e.g. many ports skip analog input, initially)
+
31  */
+
32 
+
33 // The main point of this check is to document, what platform & variants this implementation file is for.
+
34 #if !(IS_MYPLATFORM())
+
35 # error "Wrong implementation included for this platform"
+
36 #endif
+
37 // Add platform specific includes and declarations, here
+
38 
+
39 //#include <my_hardware_header.h>
+
40 
+
41 // In order to allow simple yet efficient user configuration, the entire contents of this file are compiled in the same translation unit
+
42 // as (the main file of) the user sketch. To avoid name clashes, we encapsulate everyghing in a namespace.
+
43 // For the most part, this namescape can just extend from the start of the file to the end (as shown, here), and you will not have to
+
44 // worry about it. However, there may be a few situations, where you have to "leave" the MozziPrivate namespace. This includes:
+
45 // - When you include a further (hardware-dependent library). Consider gathering all includes at the top of this file, instead.
+
46 // - When you provide definitions for special names, importantly for ISR-functions. If these would be placed in the namespace, the linker would not
+
47 // recognize them as the definition of the intended ISR-vector. See MozziGuts_impl_AVR.hpp for examples.
+
48 
+
49 namespace MozziPrivate {
+
50 
+
51 ////// BEGIN analog input code ////////
+
52 
+
53 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
54 /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of MOZZI_AUDIO_INPUT (if enabled).
+
55  *
+
56  * It is possible, and even recommended, to skip over this section, initially, when starting a new port. Once you have an implementation, be sure to include something like this
+
57  * in your platform configuration checks:
+
58  *
+
59  * // analog reads shall be enabled by default on platforms that support it
+
60  * #if not defined(MOZZI_ANALOG_READ)
+
61  * #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
62  * #endif
+
63  *
+
64  * Also, of course, remove the #error line, below
+
65  */
+
66 #error not yet implemented
+
67 
+
68 // Insert here code to read the result of the latest asynchronous conversion, when it is finished.
+
69 // You can also provide this as a function returning unsigned int, should it be more complex on your platform
+
70 #define getADCReading() GET_MY_PLATFORM_ADC_REGISTER
+
71 
+
72 /** NOTE: On "pins" vs. "channels" vs. "indices"
+
73  * "Pin" is the pin number as would usually be specified by the user in mozziAnalogRead().
+
74  * "Channel" is an internal ADC channel number corresponding to that pin. On many platforms this is simply the same as the pin number, on others it differs.
+
75  * In other words, this is an internal representation of "pin".
+
76  * "Index" is the index of the reading for a certain pin/channel in the array of analog_readings, ranging from 0 to NUM_ANALOG_PINS. This, again may be the
+
77  * same as "channel" (e.g. on AVR), however, on platforms where ADC-capable "channels" are not numbered sequentially starting from 0, the channel needs
+
78  * to be converted to a suitable index.
+
79  *
+
80  * In summary, the semantics are roughly
+
81  * mozziAnalogRead(pin) -> _ADCimplementation_(channel) -> analog_readings[index]
+
82  * Implement adcPinToChannelNum() and channelNumToIndex() to perform the appropriate mapping.
+
83  */
+
84 // NOTE: Theoretically, adcPinToChannelNum is public API for historical reasons, thus cannot be replaced by a define
+
85 #define channelNumToIndex(channel) channel
+ +
87  return pin;
+
88 }
+
89 
+
90 /** NOTE: Code needed to trigger a conversion on a new channel */
+ +
92 }
+
93 
+
94 /** NOTE: Code needed to trigger a subsequent conversion on the latest channel. If your platform has no special code for it, you should store the channel from
+
95  * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */
+ +
97 }
+
98 
+
99 /** NOTE: Code needed to initialize the ADC for asynchronous reads. Typically involves setting up an interrupt handler for when conversion is done, and
+
100  * possibly calibration. */
+
101 void setupMozziADC(int8_t speed) {
+ +
103  // insert further custom code
+
104 }
+
105 
+
106 /* NOTE: Most platforms call a specific function/ISR when conversion is complete. Provide this function, here.
+
107  * From inside its body, simply call advanceADCStep(). E.g.:
+
108 void stm32_adc_eoc_handler() {
+
109  advanceADCStep();
+
110 }
+
111 */
+
112 
+
113 /** NOTE: Code needed to set up faster than usual analog reads, e.g. specifying the number of CPU cycles that the ADC waits for the result to stabilize.
+
114  * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */
+ +
116 }
+
117 
+
118 #endif
+
119 
+
120 ////// END analog input code ////////
+
121 
+
122 ////// BEGIN audio output code //////
+
123 /* NOTE: Some platforms rely on control returning from loop() every so often. However, updateAudio() may take too long (it tries to completely fill the output buffer,
+
124  * which of course is being drained at the same time, theoretically it may not return at all). If you set this define, it will be called once per audio frame to keep things
+
125  * running smoothly. */
+
126 //#define LOOP_YIELD yield();
+
127 
+
128 /* NOTE: On some platforms, what can be called in the ISR used to output the sound is limited.
+
129  * This define can be used, for instance, to output the sound in audioHook() instead to overcome
+
130  * this limitation (see MozziGuts_impl_MBED.hpp). It can also be used if something needs to be called in audioHook() regarding
+
131  * analog reads for instance. */
+
132 //#define AUDIO_HOOK_HOOK
+
133 
+
134 /* NOTE: Code sections that are needed for a certain audio mode, only, should be guarded as follows (in this example, code will compile for the
+
135  * two modes MOZZI_OUTPUT_PWM, and MOZZI_OUTPUT_INTERNAL_DAC (should your port happen to support these two).
+
136  *
+
137  * Keep in mind that you probably want to support MOZZI_OUTPUT_EXTERNAL_TIMED, and MOZZI_OUTPUT_EXTERNAL_CUSTOM, too, which is usually very
+
138  * easy: For both, do *not* provide an audioOutput() function, as this will be provided by the user. For MOZZI_OUTPUT_EXTERNAL_TIMED make sure some
+
139  * timer is set up to call defaultAudioOutput() at MOZZI_AUDIO_RATE. For MOZZI_OUTPUT_EXTERNAL_CUSTOM, nothing else will be needed. */
+
140 
+
141 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC) // just an example!
+
142 /** NOTE: This is the function that actually write a sample to the output. In case of the two EXTERNAL modes, it is provided by the library user, instead. */
+
143 inline void audioOutput(const AudioOutput f) {
+
144  // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_1_PIN, f.l()+MOZZI_AUDIO_BIAS);
+
145 # if (MOZZI_AUDIO_CHANNELS > 1)
+
146  // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_2_PIN, f.r()+MOZZI_AUDIO_BIAS);
+
147 # endif
+
148 }
+
149 #endif
+
150 
+
151 static void startAudio() {
+
152  // Add here code to get audio output going. This usually involves:
+
153  // 1) setting up some DAC mechanism (e.g. setting up a PWM pin with appropriate resolution
+
154  // 2a) setting up a timer to call defaultAudioOutput() at MOZZI_AUDIO_RATE
+
155  // OR 2b) setting up a buffered output queue such as I2S (see ESP32 / ESP8266 for examples for this setup)
+
156 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
157  // [...]
+
158 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
159  // [...]
+
160 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
161  // remember that the user may configure MOZZI_OUTPUT_EXTERNAL_TIMED, in which case, you'll want to provide step 2a), and only that.
+
162 #endif
+
163 }
+
164 
+
165 void stopMozzi() {
+
166  // Add here code to pause whatever mechanism moves audio samples to the output
+
167 }
+
168 ////// END audio output code //////
+
169 
+
170 //// BEGIN Random seeding ////////
+
171 void MozziRandPrivate::autoSeed() {
+
172  // Add here code to initialize the values of MozziRandPrivate::x, MozziRandPrivate::y, and MozziRandPrivate::z to some random values
+
173  // This doesn't need to be crypographically safe. If nothing better is available, e.g. try reading an internal temperature sensor
+
174  // in order to get some noise. It also doesn't have to be fast.
+
175  // It *should* however ensure that rand() sequences will differ across reboots, after randSeed() has been called.
+
176  // x, y, and z are already initialized to non-zero, when this function is called.
+
177  // It's ok to leave this unimplemented, initially.
+
178 #warning Automatic random seeding is not implemented on this platform
+
179 }
+
180 //// END Random seeding ////////
+
181 
+
182 } // namespace MozziPrivate
diff --git a/extras/doc/html/_mozzi_headers_only_8h.html b/extras/doc/html/_mozzi_headers_only_8h.html index e2d255524..c7a7c1abe 100644 --- a/extras/doc/html/_mozzi_headers_only_8h.html +++ b/extras/doc/html/_mozzi_headers_only_8h.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziHeadersOnly.h File Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -123,9 +119,7 @@ diff --git a/extras/doc/html/_mozzi_headers_only_8h_source.html b/extras/doc/html/_mozzi_headers_only_8h_source.html index 2d4a6d44e..cc27cd63b 100644 --- a/extras/doc/html/_mozzi_headers_only_8h_source.html +++ b/extras/doc/html/_mozzi_headers_only_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziHeadersOnly.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -103,15 +99,40 @@
MozziHeadersOnly.h
-Go to the documentation of this file.
1 /*
2  * MozziHeadersOnly.h
3  *
4  * Copyright 2024, Tim Barrass and the Mozzi team
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 /** @ingroup core
14  * @file MozziHeadersOnly.h
15  *
16  * This file provides declarations of the \ref core Mozzi functions, but no implementation. Use this only, if you have more than one
17  * translation unit in your project (i.e. you have more than one .cpp-file in your sketch itself). Otherwise include \ref Mozzi.h, instead.
18  *
19  * (Failure to head this advice will lead to "symbol XY undefined" errors.).
20  */
21 
22 #ifndef MOZZI_HEADERS_ONLY_H_
23 #define MOZZI_HEADERS_ONLY_H_
24 
25 #define _MOZZI_HEADER_ONLY
26 #include "MozziGuts.h"
27 
28 #endif
+Go to the documentation of this file.
1 /*
+
2  * MozziHeadersOnly.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-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 /** @ingroup core
+
13  * @file MozziHeadersOnly.h
+
14  *
+
15  * This file provides declarations of the \ref core Mozzi functions, but no implementation. Use this only, if you have more than one
+
16  * translation unit in your project (i.e. you have more than one .cpp-file in your sketch itself). Otherwise include \ref Mozzi.h, instead.
+
17  *
+
18  * (Failure to head this advice will lead to "symbol XY undefined" errors.).
+
19  */
+
20 
+
21 #ifndef MOZZI_HEADERS_ONLY_H_
+
22 #define MOZZI_HEADERS_ONLY_H_
+
23 
+
24 #define _MOZZI_HEADER_ONLY
+
25 #include "MozziGuts.h"
+
26 
+
27 #endif
+
diff --git a/extras/doc/html/_oscil_8h_source.html b/extras/doc/html/_oscil_8h_source.html index 022d0ef25..709573ee2 100644 --- a/extras/doc/html/_oscil_8h_source.html +++ b/extras/doc/html/_oscil_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Oscil.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,37 +99,427 @@
Oscil.h
-
1 /*
2  * Oscil.h
3  *
4  * Oscil.h owes much to AF_precision_synthesis.pde, 2009, Adrian Freed.
5  *
6  * Copyright 2012 Tim Barrass, 2009 Adrian Freed.
7  *
8  * This file is part of Mozzi.
9  *
10  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
11  *
12  */
13 
14 #ifndef OSCIL_H_
15 #define OSCIL_H_
16 
17 #include "Arduino.h"
18 #include "MozziHeadersOnly.h"
19 #include "mozzi_fixmath.h"
20 #include "FixMath.h"
21 #include "mozzi_pgmspace.h"
22 
23 #ifdef OSCIL_DITHER_PHASE
24 #include "mozzi_rand.h"
25 #endif
26 
27 // fractional bits for oscillator index precision
28 #define OSCIL_F_BITS 16
29 #define OSCIL_F_BITS_AS_MULTIPLIER 65536
30 
31 // phmod_proportion is an 15n16 fixed-point number
32 #define OSCIL_PHMOD_BITS 16
33 
34 /**
35 Oscil plays a wavetable, cycling through the table to generate an audio or
36 control signal. The frequency of the signal can be set or changed with
37 setFreq(), and the output of an Oscil can be produced with next() for a simple
38 cycling oscillator, or atIndex() for a particular sample in the table.
39 @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Oscil will be
40 using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a
41 defined macro, rather than a const or int, for the Oscil to run fast enough.
42 @tparam UPDATE_RATE This will be MOZZI_AUDIO_RATE if the Oscil is updated in
43 updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is
44 called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind
45 of cyclic updating in updateControl(), for example, to spread out the processor load.
46 @todo Use conditional compilation to optimise setFreq() variations for different table
47 sizes.
48 @note If you #define OSCIL_DITHER_PHASE before you #include <Oscil.h>,
49 the phase increments will be dithered, which reduces spurious frequency spurs
50 in the audio output, at the cost of some extra processing and memory.
51 @section int8_t2mozzi
52 Converting soundfiles for Mozzi
53 There is a python script called char2mozzi.py in the Mozzi/python folder.
54 The usage is:
55 char2mozzi.py infilename outfilename tablename samplerate
56 */
57 //template <unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, bool DITHER_PHASE=false>
58 template <uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
59 class Oscil
60 {
61 
62 
63 public:
64  /** Constructor.
65  @param TABLE_NAME the name of the array the Oscil will be using. This
66  can be found in the table ".h" file if you are using a table made for
67  Mozzi by the int8_t2mozzi.py python script in Mozzi's python
68  folder.*/
69  Oscil(const int8_t * TABLE_NAME):table(TABLE_NAME)
70  {}
71 
72 
73  /** Constructor.
74  Declare an Oscil with template TABLE_NUM_CELLS and UPDATE_RATE
75  parameters, without specifying a particular wave table for it to play.
76  The table can be set or changed on the fly with setTable(). Any tables
77  used by the Oscil must be the same size.
78  */
80  {}
81 
82 
83  /** Updates the phase according to the current frequency and returns the sample at the new phase position.
84  @return the next sample.
85  */
86  inline
88  {
89  incrementPhase();
90  return readTable();
91  }
92 
93 
94  /** Change the sound table which will be played by the Oscil.
95  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
96  */
97  void setTable(const int8_t * TABLE_NAME)
98  {
99  table = TABLE_NAME;
100  }
101 
102 
103  /** Set the phase of the Oscil. This does the same thing as Sample::start(offset). Just different ways of thinking about oscillators and samples.
104  @param phase a position in the wavetable.
105  */
106  // This could be called in the control interrupt, so phase_fractional should really be volatile,
107  // but that could limit optimisation. Since phase_fractional gets changed often in updateAudio()
108  // (in loop()), it's probably worth keeping it nonvolatile until it causes problems
109  void setPhase(unsigned int phase)
110  {
111  phase_fractional = (uint32_t)phase << OSCIL_F_BITS;
112  }
113 
114  /** Set the phase of the Oscil. Might be useful with getPhaseFractional().
115  @param phase a position in the wavetable.
116  */
117  // This could be called in the control interrupt, so phase_fractional should really be volatile,
118  // but that could limit optimisation. Since phase_fractional gets changed often in updateAudio()
119  // (in loop()), it's probably worth keeping it nonvolatile until it causes problems
120  void setPhaseFractional(uint32_t phase)
121  {
122  phase_fractional = phase;
123  }
124 
125 
126  /** Get the phase of the Oscil in fractional format.
127  @return position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
128  */
130  {
131  return phase_fractional;
132  }
133 
134 
135 
136  /** Returns the next sample given a phase modulation value.
137  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
138  phmod_proportion parameter is a Q15n16 fixed-point number where the fractional
139  n16 part represents almost -1 to almost 1, modulating the phase by one whole table length in
140  each direction.
141  @return a sample from the table.
142  */
143  // PM: cos((angle += incr) + change)
144  // FM: cos(angle += (incr + change))
145  // The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm )
146  inline
148  {
149  incrementPhase();
150  return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
151  }
152 
153 
154  /** Returns the next sample given a phase modulation value.
155  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
156  phmod_proportion parameter is a SFix<NI,NF> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in
157  each direction. This fixed point math number is interpreted as a SFix<15,16> internally.
158  @return a sample from the table.
159  */
160  template <byte NI, byte NF>
161  inline
163  {
164  return phMod(SFix<15,16>(phmod_proportion).asRaw());
165  }
166 
167 
168 
169  /** Returns the next sample given a phase modulation value.
170  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
171  phmod_proportion parameter is a SFix<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in
172  each direction.
173  @return a sample from the table.
174  */
175  inline
177  {
178  return phMod(phmod_proportion.asRaw());
179  }
180 
181 
182  /** Set the oscillator frequency with an unsigned int. This is faster than using a
183  float, so it's useful when processor time is tight, but it can be tricky with
184  low and high frequencies, depending on the size of the wavetable being used. If
185  you're not getting the results you expect, try explicitly using a float, or try
186  setFreq_Q24n8() or or setFreq_Q16n16().
187  @param frequency to play the wave table.
188  */
189  inline
190  void setFreq (int frequency) {
191  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
192  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
193  //phase_increment_fractional = ((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
194  // to this:
195  phase_increment_fractional = ((uint32_t)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
196  }
197 
198 
199  /** Set the oscillator frequency with a float. Using a float is the most reliable
200  way to set frequencies, -Might- be slower than using an int but you need either
201  this, setFreq_Q24n8() or setFreq_Q16n16() for fractional frequencies.
202  @param frequency to play the wave table.
203  */
204  inline
205  void setFreq(float frequency)
206  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
207  phase_increment_fractional = (uint32_t)((((float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * OSCIL_F_BITS_AS_MULTIPLIER);
208  }
209 
210 
211  /** Set the frequency using UFix<NI,NF> fixed-point number format. This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors.
212  @note This should work OK with tables 2048 cells or smaller and
213  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
214  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
215  @param frequency in UFix<NI,NF> fixed-point number format.
216  */
217  template <int8_t NI, int8_t NF>
218  inline
219  void setFreq(UFix<NI,NF> frequency)
220  {
221  setFreq_Q16n16(UFix<16,16>(frequency).asRaw());
222  }
223 
224 
225 
226  /** Set the frequency using Q24n8 fixed-point number format.
227  This might be faster than the float version for setting low frequencies such as
228  1.5 Hz, or other values which may not work well with your table size. A Q24n8
229  representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE
230  less than 64 Hz.
231  @param frequency in Q24n8 fixed-point number format.
232  */
233  inline
234  void setFreq_Q24n8(Q24n8 frequency)
235  {
236  //phase_increment_fractional = (frequency* (NUM_TABLE_CELLS>>3)/(UPDATE_RATE>>6)) << (F_BITS-(8-3+6));
237 // TB2016-10-2 line below might have been left in accidentally while making the 2014 change below, remove for now
238 // phase_increment_fractional = (((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
239 // << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
240 
241  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
242  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
243  if ((256UL*NUM_TABLE_CELLS) >= UPDATE_RATE) {
244  phase_increment_fractional = ((uint32_t)frequency) * ((256UL*NUM_TABLE_CELLS)/UPDATE_RATE);
245  } else {
246  phase_increment_fractional = ((uint32_t)frequency) / (UPDATE_RATE/(256UL*NUM_TABLE_CELLS));
247  }
248  }
249 
250  /** Set the frequency using UFix<24,8> fixed-point number format.
251  This might be faster than the float version for setting low frequencies such as
252  1.5 Hz, or other values which may not work well with your table size. A UFix<24,8>
253  representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE
254  less than 64 Hz.
255  @param frequency in UFix<24,8> fixed-point number format.
256  */
257  inline
258  void setFreq(UFix<24,8> frequency)
259  {
260  setFreq_Q24n8(frequency.asRaw());
261  }
262 
263 
264  /** Set the frequency using Q16n16 fixed-point number format. This is useful in
265  combination with Q16n16_mtof(), a fast alternative to mtof(), using Q16n16
266  fixed-point format instead of floats.
267  @note This should work OK with tables 2048 cells or smaller and
268  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
269  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
270  @param frequency in Q16n16 fixed-point number format.
271  */
272  inline
273  void setFreq_Q16n16(Q16n16 frequency)
274  {
275  //phase_increment_fractional = ((frequency * (NUM_TABLE_CELLS>>7))/(UPDATE_RATE>>6)) << (F_BITS-16+1);
276  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
277  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
278  //phase_increment_fractional = (((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>7)*frequency)/(UPDATE_RATE>>6))
279  // << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - 16 + 1);
280  if (NUM_TABLE_CELLS >= UPDATE_RATE) {
281  phase_increment_fractional = ((uint32_t)frequency) * (NUM_TABLE_CELLS/UPDATE_RATE);
282  } else {
283  phase_increment_fractional = ((uint32_t)frequency) / (UPDATE_RATE/NUM_TABLE_CELLS);
284  }
285  }
286 
287 
288  /** Set the frequency using UFix<16,16> fixed-point number format. This is useful in
289  combination with Q16n16_mtof(), a fast alternative to mtof(), using UFix<16,16>
290  fixed-point format instead of fractional numbers.
291  @note This should work OK with tables 2048 cells or smaller and
292  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
293  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
294  @param frequency in UFix<16,16> fixed-point number format.
295  */
296  inline
297  void setFreq(UFix<16,16> frequency)
298  {
299  setFreq_Q16n16(frequency.asRaw());
300  }
301 
302 
303 
304  /** Set the frequency using SFix<NI,NF> fixed-point number format. This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors.
305  @note This should work OK with tables 2048 cells or smaller and
306  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
307  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
308  @param frequency in SFix<16,16> fixed-point number format.
309  */
310  template <byte NI, byte NF>
311  inline
312  void setFreq(SFix<NI,NF> frequency)
313  {
314  setFreq_Q16n16(UFix<16,16>(frequency).asRaw());
315  }
316 
317 /*
318  inline
319  void setFreqMidi(int8_t note_num) {
320  setFreq_Q16n16(mtof(note_num));
321  }
322 */
323  /** Returns the sample at the given table index.
324  @param index between 0 and the table size.The
325  index rolls back around to 0 if it's larger than the table size.
326  @return the sample at the given table index.
327  */
328  inline
329  int8_t atIndex(unsigned int index)
330  {
331  return FLASH_OR_RAM_READ<const int8_t>(table + (index & (NUM_TABLE_CELLS - 1)));
332  }
333 
334 
335  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
336  Instead of recalculating the phase increment for each
337  frequency in between, you can just calculate the phase increment for each end
338  frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and
339  use setPhaseInc() to set the phase increment at each step. (Note: I should
340  really profile this with the oscilloscope to see if it's worth the extra
341  confusion!)
342  @param frequency for which you want to calculate a phase increment value.
343  @return the phase increment value which will produce a given frequency.
344  */
345  inline
347  {
348  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
349  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
350  //return (((uint32_t)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << OSCIL_F_BITS;
351  return ((uint32_t)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
352  }
353 
354 
355  /** Set a specific phase increment. See phaseIncFromFreq().
356  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
357  */
358  inline
359  void setPhaseInc(uint32_t phaseinc_fractional)
360  {
361  phase_increment_fractional = phaseinc_fractional;
362  }
363 
364 
365 
366 private:
367 
368 
369  /** Used for shift arithmetic in setFreq() and its variations.
370  */
371 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
372 
373 
374  /** Increments the phase of the oscillator without returning a sample.
375  */
376  inline
377  void incrementPhase()
378  {
379  //phase_fractional += (phase_increment_fractional | 1); // odd phase incr, attempt to reduce frequency spurs in output
380  phase_fractional += phase_increment_fractional;
381  }
382 
383 
384  /** Returns the current sample.
385  */
386  inline
387  int8_t readTable()
388  {
389 #ifdef OSCIL_DITHER_PHASE
390  return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional + ((int)(xorshift96()>>16))) >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
391 #else
392  return FLASH_OR_RAM_READ<const int8_t>(table + ((phase_fractional >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
393  //return FLASH_OR_RAM_READ<int8_t>(table + (((phase_fractional >> OSCIL_F_BITS) | 1 ) & (NUM_TABLE_CELLS - 1))); odd phase, attempt to reduce frequency spurs in output
394 #endif
395  }
396 
397 
398  uint32_t phase_fractional;
399  uint32_t phase_increment_fractional;
400  const int8_t * table;
401 
402 };
403 
404 
405 /**
406 @example 01.Basics/Vibrato/Vibrato.ino
407 This is an example using Oscil::phMod to produce vibrato using phase modulation.
408 */
409 
410 #endif /* OSCIL_H_ */
int8_t next()
Updates the phase according to the current frequency and returns the sample at the new phase position...
Definition: Oscil.h:87
-
void setFreq(UFix< 16, 16 > frequency)
Set the frequency using UFix<16,16> fixed-point number format.
Definition: Oscil.h:297
-
int8_t phMod(SFix< NI, NF > phmod_proportion)
Returns the next sample given a phase modulation value.
Definition: Oscil.h:162
-
Oscil plays a wavetable, cycling through the table to generate an audio or control signal...
Definition: Oscil.h:59
-
void setPhaseFractional(uint32_t phase)
Set the phase of the Oscil.
Definition: Oscil.h:120
-
void setPhase(unsigned int phase)
Set the phase of the Oscil.
Definition: Oscil.h:109
-
#define OSCIL_F_BITS
Definition: Oscil.h:28
-
uint32_t phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: Oscil.h:346
-
uint32_t getPhaseFractional()
Get the phase of the Oscil in fractional format.
Definition: Oscil.h:129
-
Oscil(const int8_t *TABLE_NAME)
Constructor.
Definition: Oscil.h:69
-
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Oscil.
Definition: Oscil.h:97
-
void setFreq(float frequency)
Set the oscillator frequency with a float.
Definition: Oscil.h:205
-
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
Definition: Oscil.h:329
-
#define OSCIL_F_BITS_AS_MULTIPLIER
Definition: Oscil.h:29
-
void setFreq(SFix< NI, NF > frequency)
Set the frequency using SFix<NI,NF> fixed-point number format.
Definition: Oscil.h:312
-
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:43
-
void setFreq_Q16n16(Q16n16 frequency)
Set the frequency using Q16n16 fixed-point number format.
Definition: Oscil.h:273
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:44
-
Oscil()
Constructor.
Definition: Oscil.h:79
-
int8_t phMod(SFix< 15, 16 > phmod_proportion)
Returns the next sample given a phase modulation value.
Definition: Oscil.h:176
-
void setFreq_Q24n8(Q24n8 frequency)
Set the frequency using Q24n8 fixed-point number format.
Definition: Oscil.h:234
-
void setPhaseInc(uint32_t phaseinc_fractional)
Set a specific phase increment.
Definition: Oscil.h:359
+
1 /*
+
2  * Oscil.h
+
3  *
+
4  * Oscil.h owes much to AF_precision_synthesis.pde, 2009, Adrian Freed.
+
5  *
+
6  * This file is part of Mozzi.
+
7  *
+
8  * Copyright 20009 Arian Freed
+
9  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
10  *
+
11  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
12  *
+
13  */
+
14 
+
15 
+
16 #ifndef OSCIL_H_
+
17 #define OSCIL_H_
+
18 
+
19 #include "Arduino.h"
+
20 #include "MozziHeadersOnly.h"
+
21 #include "mozzi_fixmath.h"
+
22 #include "FixMath.h"
+
23 #include "mozzi_pgmspace.h"
+
24 
+
25 #ifdef OSCIL_DITHER_PHASE
+
26 #include "mozzi_rand.h"
+
27 #endif
+
28 
+
29 // fractional bits for oscillator index precision
+
30 #define OSCIL_F_BITS 16
+
31 #define OSCIL_F_BITS_AS_MULTIPLIER 65536
+
32 
+
33 // phmod_proportion is an 15n16 fixed-point number
+
34 #define OSCIL_PHMOD_BITS 16
+
35 
+
36 /**
+
37 Oscil plays a wavetable, cycling through the table to generate an audio or
+
38 control signal. The frequency of the signal can be set or changed with
+
39 setFreq(), and the output of an Oscil can be produced with next() for a simple
+
40 cycling oscillator, or atIndex() for a particular sample in the table.
+
41 @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Oscil will be
+
42 using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a
+
43 defined macro, rather than a const or int, for the Oscil to run fast enough.
+
44 @tparam UPDATE_RATE This will be MOZZI_AUDIO_RATE if the Oscil is updated in
+
45 updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is
+
46 called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind
+
47 of cyclic updating in updateControl(), for example, to spread out the processor load.
+
48 @todo Use conditional compilation to optimise setFreq() variations for different table
+
49 sizes.
+
50 @note If you #define OSCIL_DITHER_PHASE before you #include <Oscil.h>,
+
51 the phase increments will be dithered, which reduces spurious frequency spurs
+
52 in the audio output, at the cost of some extra processing and memory.
+
53 @section int8_t2mozzi
+
54 Converting soundfiles for Mozzi
+
55 There is a python script called char2mozzi.py in the Mozzi/python folder.
+
56 The usage is:
+
57 char2mozzi.py infilename outfilename tablename samplerate
+
58 */
+
59 //template <unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, bool DITHER_PHASE=false>
+
60 template <uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
61 class Oscil
+
62 {
+
63 
+
64 
+
65 public:
+
66  /** Constructor.
+
67  @param TABLE_NAME the name of the array the Oscil will be using. This
+
68  can be found in the table ".h" file if you are using a table made for
+
69  Mozzi by the int8_t2mozzi.py python script in Mozzi's python
+
70  folder.*/
+
71  Oscil(const int8_t * TABLE_NAME):table(TABLE_NAME)
+
72  {}
+
73 
+
74 
+
75  /** Constructor.
+
76  Declare an Oscil with template TABLE_NUM_CELLS and UPDATE_RATE
+
77  parameters, without specifying a particular wave table for it to play.
+
78  The table can be set or changed on the fly with setTable(). Any tables
+
79  used by the Oscil must be the same size.
+
80  */
+ +
82  {}
+
83 
+
84 
+
85  /** Updates the phase according to the current frequency and returns the sample at the new phase position.
+
86  @return the next sample.
+
87  */
+
88  inline
+ +
90  {
+
91  incrementPhase();
+
92  return readTable();
+
93  }
+
94 
+
95 
+
96  /** Change the sound table which will be played by the Oscil.
+
97  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
+
98  */
+
99  void setTable(const int8_t * TABLE_NAME)
+
100  {
+
101  table = TABLE_NAME;
+
102  }
+
103 
+
104 
+
105  /** Set the phase of the Oscil. This does the same thing as Sample::start(offset). Just different ways of thinking about oscillators and samples.
+
106  @param phase a position in the wavetable.
+
107  */
+
108  // This could be called in the control interrupt, so phase_fractional should really be volatile,
+
109  // but that could limit optimisation. Since phase_fractional gets changed often in updateAudio()
+
110  // (in loop()), it's probably worth keeping it nonvolatile until it causes problems
+
111  void setPhase(unsigned int phase)
+
112  {
+
113  phase_fractional = (uint32_t)phase << OSCIL_F_BITS;
+
114  }
+
115 
+
116  /** Set the phase of the Oscil. Might be useful with getPhaseFractional().
+
117  @param phase a position in the wavetable.
+
118  */
+
119  // This could be called in the control interrupt, so phase_fractional should really be volatile,
+
120  // but that could limit optimisation. Since phase_fractional gets changed often in updateAudio()
+
121  // (in loop()), it's probably worth keeping it nonvolatile until it causes problems
+
122  void setPhaseFractional(uint32_t phase)
+
123  {
+
124  phase_fractional = phase;
+
125  }
+
126 
+
127 
+
128  /** Get the phase of the Oscil in fractional format.
+
129  @return position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
+
130  */
+ +
132  {
+
133  return phase_fractional;
+
134  }
+
135 
+
136 
+
137 
+
138  /** Returns the next sample given a phase modulation value.
+
139  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
+
140  phmod_proportion parameter is a Q15n16 fixed-point number where the fractional
+
141  n16 part represents almost -1 to almost 1, modulating the phase by one whole table length in
+
142  each direction.
+
143  @return a sample from the table.
+
144  */
+
145  // PM: cos((angle += incr) + change)
+
146  // FM: cos(angle += (incr + change))
+
147  // The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm )
+
148  inline
+ +
150  {
+
151  incrementPhase();
+
152  return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
+
153  }
+
154 
+
155 
+
156  /** Returns the next sample given a phase modulation value.
+
157  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
+
158  phmod_proportion parameter is a SFix<NI,NF> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in
+
159  each direction. This fixed point math number is interpreted as a SFix<15,16> internally.
+
160  @return a sample from the table.
+
161  */
+
162  template <int8_t NI, int8_t NF, uint8_t RANGE>
+
163  inline
+ +
165  {
+
166  return phMod(SFix<15,16>(phmod_proportion).asRaw());
+
167  }
+
168 
+
169 
+
170 
+
171  /** Returns the next sample given a phase modulation value.
+
172  @param phmod_proportion a phase modulation value given as a proportion of the wave. The
+
173  phmod_proportion parameter is a SFix<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in
+
174  each direction.
+
175  @return a sample from the table.
+
176  */
+
177  inline
+ +
179  {
+
180  return phMod(phmod_proportion.asRaw());
+
181  }
+
182 
+
183 
+
184  /** Set the oscillator frequency with an unsigned int. This is faster than using a
+
185  float, so it's useful when processor time is tight, but it can be tricky with
+
186  low and high frequencies, depending on the size of the wavetable being used. If
+
187  you're not getting the results you expect, try explicitly using a float, or try
+
188  setFreq_Q24n8() or or setFreq_Q16n16().
+
189  @param frequency to play the wave table.
+
190  */
+
191  inline
+
192  void setFreq (int frequency) {
+
193  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
+
194  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
+
195  //phase_increment_fractional = ((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
+
196  // to this:
+
197  phase_increment_fractional = ((uint32_t)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
+
198  }
+
199 
+
200 
+
201  /** Set the oscillator frequency with a float. Using a float is the most reliable
+
202  way to set frequencies, -Might- be slower than using an int but you need either
+
203  this, setFreq_Q24n8() or setFreq_Q16n16() for fractional frequencies.
+
204  @param frequency to play the wave table.
+
205  */
+
206  inline
+
207  void setFreq(float frequency)
+
208  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
+
209  phase_increment_fractional = (uint32_t)((((float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * OSCIL_F_BITS_AS_MULTIPLIER);
+
210  }
+
211 
+
212 
+
213  /** Set the frequency using UFix<NI,NF> fixed-point number format. This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors.
+
214  @note This should work OK with tables 2048 cells or smaller and
+
215  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
+
216  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
+
217  @param frequency in UFix<NI,NF> fixed-point number format.
+
218  */
+
219  template <int8_t NI, int8_t NF, uint64_t RANGE>
+
220  inline
+
221  void setFreq(UFix<NI,NF,RANGE> frequency)
+
222  {
+
223  setFreq_Q16n16(UFix<16,16>(frequency).asRaw());
+
224  }
+
225 
+
226 
+
227 
+
228  /** Set the frequency using Q24n8 fixed-point number format.
+
229  This might be faster than the float version for setting low frequencies such as
+
230  1.5 Hz, or other values which may not work well with your table size. A Q24n8
+
231  representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE
+
232  less than 64 Hz.
+
233  @param frequency in Q24n8 fixed-point number format.
+
234  */
+
235  inline
+
236  void setFreq_Q24n8(Q24n8 frequency)
+
237  {
+
238  //phase_increment_fractional = (frequency* (NUM_TABLE_CELLS>>3)/(UPDATE_RATE>>6)) << (F_BITS-(8-3+6));
+
239 // TB2016-10-2 line below might have been left in accidentally while making the 2014 change below, remove for now
+
240 // phase_increment_fractional = (((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
+
241 // << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
+
242 
+
243  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
+
244  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
+
245  if ((256UL*NUM_TABLE_CELLS) >= UPDATE_RATE) {
+
246  phase_increment_fractional = ((uint32_t)frequency) * ((256UL*NUM_TABLE_CELLS)/UPDATE_RATE);
+
247  } else {
+
248  phase_increment_fractional = ((uint32_t)frequency) / (UPDATE_RATE/(256UL*NUM_TABLE_CELLS));
+
249  }
+
250  }
+
251 
+
252  /** Set the frequency using UFix<24,8> fixed-point number format.
+
253  This might be faster than the float version for setting low frequencies such as
+
254  1.5 Hz, or other values which may not work well with your table size. A UFix<24,8>
+
255  representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE
+
256  less than 64 Hz.
+
257  @param frequency in UFix<24,8> fixed-point number format.
+
258  */
+
259  template <uint64_t RANGE>
+
260  inline
+
261  void setFreq(UFix<24,8,RANGE> frequency)
+
262  {
+
263  setFreq_Q24n8(frequency.asRaw());
+
264  }
+
265 
+
266 
+
267  /** Set the frequency using Q16n16 fixed-point number format. This is useful in
+
268  combination with Q16n16_mtof(), a fast alternative to mtof(), using Q16n16
+
269  fixed-point format instead of floats.
+
270  @note This should work OK with tables 2048 cells or smaller and
+
271  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
+
272  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
+
273  @param frequency in Q16n16 fixed-point number format.
+
274  */
+
275  inline
+
276  void setFreq_Q16n16(Q16n16 frequency)
+
277  {
+
278  //phase_increment_fractional = ((frequency * (NUM_TABLE_CELLS>>7))/(UPDATE_RATE>>6)) << (F_BITS-16+1);
+
279  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
+
280  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
+
281  //phase_increment_fractional = (((((uint32_t)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>7)*frequency)/(UPDATE_RATE>>6))
+
282  // << (OSCIL_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - 16 + 1);
+
283  if (NUM_TABLE_CELLS >= UPDATE_RATE) {
+
284  phase_increment_fractional = ((uint32_t)frequency) * (NUM_TABLE_CELLS/UPDATE_RATE);
+
285  } else {
+
286  phase_increment_fractional = ((uint32_t)frequency) / (UPDATE_RATE/NUM_TABLE_CELLS);
+
287  }
+
288  }
+
289 
+
290 
+
291  /** Set the frequency using UFix<16,16> fixed-point number format. This is useful in
+
292  combination with Q16n16_mtof(), a fast alternative to mtof(), using UFix<16,16>
+
293  fixed-point format instead of fractional numbers.
+
294  @note This should work OK with tables 2048 cells or smaller and
+
295  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
+
296  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
+
297  @param frequency in UFix<16,16> fixed-point number format.
+
298  */
+
299  template <uint64_t RANGE>
+
300  inline
+
301  void setFreq(UFix<16,16,RANGE> frequency)
+
302  {
+
303  setFreq_Q16n16(frequency.asRaw());
+
304  }
+
305 
+
306 
+
307 
+
308  /** Set the frequency using SFix<NI,NF> fixed-point number format. This falls back to using UFix<16,16> internally and is provided as a fallout for other UFix types. If possible try to use directly UFix<16,16> or UFix<24,8> for well defined (and well tested) behaviors.
+
309  @note This should work OK with tables 2048 cells or smaller and
+
310  frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
+
311  @note This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
+
312  @param frequency in SFix<16,16> fixed-point number format.
+
313  */
+
314  template <int8_t NI, int8_t NF, uint64_t RANGE>
+
315  inline
+
316  void setFreq(SFix<NI,NF,RANGE> frequency)
+
317  {
+
318  setFreq_Q16n16(UFix<16,16>(frequency).asRaw());
+
319  }
+
320 
+
321 /*
+
322  inline
+
323  void setFreqMidi(int8_t note_num) {
+
324  setFreq_Q16n16(mtof(note_num));
+
325  }
+
326 */
+
327  /** Returns the sample at the given table index.
+
328  @param index between 0 and the table size.The
+
329  index rolls back around to 0 if it's larger than the table size.
+
330  @return the sample at the given table index.
+
331  */
+
332  inline
+
333  int8_t atIndex(unsigned int index)
+
334  {
+
335  return FLASH_OR_RAM_READ<const int8_t>(table + (index & (NUM_TABLE_CELLS - 1)));
+
336  }
+
337 
+
338 
+
339  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
+
340  Instead of recalculating the phase increment for each
+
341  frequency in between, you can just calculate the phase increment for each end
+
342  frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and
+
343  use setPhaseInc() to set the phase increment at each step. (Note: I should
+
344  really profile this with the oscilloscope to see if it's worth the extra
+
345  confusion!)
+
346  @param frequency for which you want to calculate a phase increment value.
+
347  @return the phase increment value which will produce a given frequency.
+
348  */
+
349  inline
+ +
351  {
+
352  // TB2014-8-20 change this following Austin Grossman's suggestion on user list
+
353  // https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mozzi-users/u4D5NMzVnQs/pCmiWInFvrkJ
+
354  //return (((uint32_t)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << OSCIL_F_BITS;
+
355  return ((uint32_t)frequency) * ((OSCIL_F_BITS_AS_MULTIPLIER*NUM_TABLE_CELLS)/UPDATE_RATE);
+
356  }
+
357 
+
358 
+
359  /** Set a specific phase increment. See phaseIncFromFreq().
+
360  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
+
361  */
+
362  inline
+
363  void setPhaseInc(uint32_t phaseinc_fractional)
+
364  {
+
365  phase_increment_fractional = phaseinc_fractional;
+
366  }
+
367 
+
368 
+
369 
+
370 private:
+
371 
+
372 
+
373  /** Used for shift arithmetic in setFreq() and its variations.
+
374  */
+
375 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
+
376 
+
377 
+
378  /** Increments the phase of the oscillator without returning a sample.
+
379  */
+
380  inline
+
381  void incrementPhase()
+
382  {
+
383  //phase_fractional += (phase_increment_fractional | 1); // odd phase incr, attempt to reduce frequency spurs in output
+
384  phase_fractional += phase_increment_fractional;
+
385  }
+
386 
+
387 
+
388  /** Returns the current sample.
+
389  */
+
390  inline
+
391  int8_t readTable()
+
392  {
+
393 #ifdef OSCIL_DITHER_PHASE
+
394  return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional + ((int)(xorshift96()>>16))) >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
+
395 #else
+
396  return FLASH_OR_RAM_READ<const int8_t>(table + ((phase_fractional >> OSCIL_F_BITS) & (NUM_TABLE_CELLS - 1)));
+
397  //return FLASH_OR_RAM_READ<int8_t>(table + (((phase_fractional >> OSCIL_F_BITS) | 1 ) & (NUM_TABLE_CELLS - 1))); odd phase, attempt to reduce frequency spurs in output
+
398 #endif
+
399  }
+
400 
+
401 
+
402  uint32_t phase_fractional;
+
403  uint32_t phase_increment_fractional;
+
404  const int8_t * table;
+
405 
+
406 };
+
407 
+
408 
+
409 /**
+
410 @example 01.Basics/Vibrato/Vibrato.ino
+
411 This is an example using Oscil::phMod to produce vibrato using phase modulation.
+
412 */
+
413 
+
414 #endif /* OSCIL_H_ */
diff --git a/extras/doc/html/_over_sample_8h_source.html b/extras/doc/html/_over_sample_8h_source.html index e27cc648b..a785085bb 100644 --- a/extras/doc/html/_over_sample_8h_source.html +++ b/extras/doc/html/_over_sample_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: OverSample.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,79 @@
OverSample.h
-
1 #ifndef OVERSAMPLE_H
2 #define OVERSAMPLE_H
3 
4 /*
5  * OverSample.h
6  *
7  * Copyright 2013 Tim Barrass.
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 
15  #include "RollingAverage.h"
16 
17 
18 /** @ingroup sensortools
19  Enables the resolution of analog inputs to be increased by oversampling and decimation.
20  Noise should be added to the input before it's digitised, then a succession of input readings are summed and
21  finally divided to give a number with greater resolution than the ADC.
22  Often, noise in the Arduino system will be enough, but there are other practical methods described in
23  [Enhancing ADC Resolution by Oversampling](http://www.atmel.com/images/doc8003.pdf‎),
24  as well as an explanation of the overall approach.
25  @tparam RESOLUTION_INCREASE_BITS how many extra bits of resolution to produce.
26  The window length and the memory it needs increases quickly as the oversampling resolution increases.
27  1 bit = 4 unsigned ints (analog input between 0-1023) = 8 uint8_ts,
28  2 bits = 16 unsigned ints = 32 uint8_ts,
29  3 bits = 64 unsigned ints = 128 uint8_ts,
30  More than 3 bits increase in resolution would require either using longs to store the readings,
31  which would need 1024 uint8_ts for a 4 bit increase and 4096 uint8_ts for 5 bits (do any avr's have that much room?),
32  or the average reading would have to be no more than 128 (for 4 bits increase), because 256 readings would be needed,
33  and the sum of all 256 readings would have to fit into an int. (32767 / 256 = 128).
34  Changing OverSample to use unsigned ints could enable an average reading of 256, but isn't tested properly yet.
35  @note The higher the resolution, the more lag there will be.
36  It's almost a RollingAverage filter, with the difference that
37  OverSample doesn't divide by as much as you would for an average.
38 */
39 
40 
41 template <class T, const uint8_t RESOLUTION_INCREASE_BITS>
43 {
44 
45 public:
46  using RollingAverage<T, (1<<(RESOLUTION_INCREASE_BITS*2))>::add;
47 
48  /** Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;
49  @param input an analog input to oversample.
50  @return the higher resolution result.
51  @note timing 5.7us
52  */
53  T next(T input)
54  {
55  return add(input)>>RESOLUTION_INCREASE_BITS;
56  }
57 
58 };
59 
60 
61 /**
62 @example 05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino
63 This is an example demonstrating the OverSample class.
64 */
65 
66 #endif // #ifndef OVERSAMPLE_H
T next(T input)
Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;.
Definition: OverSample.h:53
-
Enables the resolution of analog inputs to be increased by oversampling and decimation.
Definition: OverSample.h:42
+
1 /*
+
2  * OverSample.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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 OVERSAMPLE_H
+
13 #define OVERSAMPLE_H
+
14 
+
15 #include "RollingAverage.h"
+
16 
+
17 
+
18 /** @ingroup sensortools
+
19  Enables the resolution of analog inputs to be increased by oversampling and decimation.
+
20  Noise should be added to the input before it's digitised, then a succession of input readings are summed and
+
21  finally divided to give a number with greater resolution than the ADC.
+
22  Often, noise in the Arduino system will be enough, but there are other practical methods described in
+
23  [Enhancing ADC Resolution by Oversampling](http://www.atmel.com/images/doc8003.pdf‎),
+
24  as well as an explanation of the overall approach.
+
25  @tparam RESOLUTION_INCREASE_BITS how many extra bits of resolution to produce.
+
26  The window length and the memory it needs increases quickly as the oversampling resolution increases.
+
27  1 bit = 4 unsigned ints (analog input between 0-1023) = 8 uint8_ts,
+
28  2 bits = 16 unsigned ints = 32 uint8_ts,
+
29  3 bits = 64 unsigned ints = 128 uint8_ts,
+
30  More than 3 bits increase in resolution would require either using longs to store the readings,
+
31  which would need 1024 uint8_ts for a 4 bit increase and 4096 uint8_ts for 5 bits (do any avr's have that much room?),
+
32  or the average reading would have to be no more than 128 (for 4 bits increase), because 256 readings would be needed,
+
33  and the sum of all 256 readings would have to fit into an int. (32767 / 256 = 128).
+
34  Changing OverSample to use unsigned ints could enable an average reading of 256, but isn't tested properly yet.
+
35  @note The higher the resolution, the more lag there will be.
+
36  It's almost a RollingAverage filter, with the difference that
+
37  OverSample doesn't divide by as much as you would for an average.
+
38 */
+
39 
+
40 
+
41 template <class T, const uint8_t RESOLUTION_INCREASE_BITS>
+
42 class OverSample: public RollingAverage<T, (1<<(RESOLUTION_INCREASE_BITS*2))>
+
43 {
+
44 
+
45 public:
+
46  using RollingAverage<T, (1<<(RESOLUTION_INCREASE_BITS*2))>::add;
+
47 
+
48  /** Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;
+
49  @param input an analog input to oversample.
+
50  @return the higher resolution result.
+
51  @note timing 5.7us
+
52  */
+
53  T next(T input)
+
54  {
+
55  return add(input)>>RESOLUTION_INCREASE_BITS;
+
56  }
+
57 
+
58 };
+
59 
+
60 
+
61 /**
+
62 @example 05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino
+
63 This is an example demonstrating the OverSample class.
+
64 */
+
65 
+
66 #endif // #ifndef OVERSAMPLE_H
diff --git a/extras/doc/html/_p_d_resonant_8h_source.html b/extras/doc/html/_p_d_resonant_8h_source.html index 8504f0977..eabb98779 100644 --- a/extras/doc/html/_p_d_resonant_8h_source.html +++ b/extras/doc/html/_p_d_resonant_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: PDResonant.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,23 +99,149 @@
PDResonant.h
-
1 /*
2  * PDResonant.h
3  *
4  * This implementation copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 
13 
14 #include <mozzi_midi.h>
15 #include <ADSR.h>
16 #include <Oscil.h>
17 #include <Phasor.h>
18 // wavetable for oscillator:
19 #include <tables/sin2048_int8.h>
20 
21 /**
22  PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on
23  https://en.wikipedia.org/wiki/Phase_distortion_synthesis.
24 
25  The class shows how the Mozzi Phasor class
26  can be used to generate an index into a wavetable, and an ADSR
27  is used to modulate the effect by modifying the Phasor frequency and sync.
28  More complex phase distortion effects could be developed by using
29  precalculated tables, or calcuating tables on the fly using a double buffer,
30  or a line-breakpoint model, a sort of hybridPhasor-Line object.
31 */
32 
34 {
35 
36 public:
37 
38  /** Constructor.
39  */
41  PDM_SCALE(0.05)
42  {
43  aOsc.setTable(SIN2048_DATA);
44  aAmpEnv.setADLevels(255, 255);
45  aAmpEnv.setTimes(50, 300, 60000, 1000);
46  kResonantFreqEnv.setADLevels(255,100);
47  }
48 
49  /** Play a note in response to midi input. Params copied from MIDI library HandleNoteOn().
50  @param channel is the midi channel
51  @param pitch is the midi note
52  @param velocity you know what it is
53  */
54  void noteOn(byte channel, byte pitch, byte velocity)
55  {
56  kResonantFreqEnv.noteOn();
57  aAmpEnv.noteOn();
58  freq = mtof(pitch);
59  aBaseCounter.setFreq(freq); // gets modulated in updateControl()
60  aResonanceFreqCounter.setFreq(freq);
61  }
62 
63 
64  /** Stop a note in response to midi input. Params copied from MIDI library HandleNoteOff()
65  @param channel is the midi channel
66  @param pitch is the midi note
67  @param velocity you know what it is
68  */
69  void noteOff(byte channel, byte pitch, byte velocity)
70  {
71  aAmpEnv.noteOff();
72  kResonantFreqEnv.noteOff();
73  }
74 
75 
76  /** Set the resonant filter sweep parameters.
77  @param attack ADSR attack
78  @param decay ADSR decay
79  */
80  void setPDEnv(int attack, int decay)
81  {
82  // sustain and release timesare hardcoded here but don't need to be
83  kResonantFreqEnv.setTimes(attack, decay, 60000, 1000);
84  kResonantFreqEnv.update();
85 
86  float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
87  aResonanceFreqCounter.setFreq(resonance_freq);
88  }
89 
90 
91  /** Update the filter sweep. Use this in updateControl().
92  */
93  void update()
94  {
95  aAmpEnv.update();
96  kResonantFreqEnv.update();
97  // change freq of resonant freq counter, following the envelope
98  float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
99  aResonanceFreqCounter.setFreq(resonance_freq);
100  }
101 
102  /** Produce the audio output. This goes in updateAudio().
103  */
104  int next()
105  {
106  static byte previous_base_counter;
107  byte base_counter = aBaseCounter.next()>>24;
108 
109  // reset resonance counter (wiki b.)
110  if (base_counter<previous_base_counter) aResonanceFreqCounter.set(0);
111  previous_base_counter= base_counter;
112 
113  // index (phase) needs to end up as 11bit to match 2048 wavetable size
114  unsigned int index = aResonanceFreqCounter.next()>>21; // 11 bits fits 2048 cell sin table
115 
116  // amp ramp smooths the jump when aResonanceFreqCounter is reset (wiki d.)
117  byte amp_ramp = 255-base_counter;
118 
119  // wiki e., with amp envelope added
120  return ((long)aAmpEnv.next() * amp_ramp * aOsc.atIndex(index))>>16;
121 
122  // return ((index>>3)*amp_ramp)>>8; // this also sounds good - squelchy sawtooth
123  }
124 
125 
126 private:
127  const float PDM_SCALE;
128  byte amp;
129  int freq;
130 
131  Phasor <MOZZI_AUDIO_RATE> aBaseCounter;
132  Phasor <MOZZI_AUDIO_RATE> aResonanceFreqCounter;
133 
134  Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aOsc;
136  ADSR <MOZZI_CONTROL_RATE, MOZZI_CONTROL_RATE> kResonantFreqEnv;
137 
138 };
#define MOZZI_CONTROL_RATE
Control rate setting.
-
int next()
Produce the audio output.
Definition: PDResonant.h:104
-
PDResonant()
Constructor.
Definition: PDResonant.h:40
-
void update()
Update the filter sweep.
Definition: PDResonant.h:93
-
PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter...
Definition: PDResonant.h:33
-
void noteOn(byte channel, byte pitch, byte velocity)
Play a note in response to midi input.
Definition: PDResonant.h:54
-
void setPDEnv(int attack, int decay)
Set the resonant filter sweep parameters.
Definition: PDResonant.h:80
-
void noteOff(byte channel, byte pitch, byte velocity)
Stop a note in response to midi input.
Definition: PDResonant.h:69
+
1 /*
+
2  * PDResonant.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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 #include <mozzi_midi.h>
+
13 #include <ADSR.h>
+
14 #include <Oscil.h>
+
15 #include <Phasor.h>
+
16 // wavetable for oscillator:
+
17 #include <tables/sin2048_int8.h>
+
18 
+
19 /**
+
20  PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on
+
21  https://en.wikipedia.org/wiki/Phase_distortion_synthesis.
+
22 
+
23  The class shows how the Mozzi Phasor class
+
24  can be used to generate an index into a wavetable, and an ADSR
+
25  is used to modulate the effect by modifying the Phasor frequency and sync.
+
26  More complex phase distortion effects could be developed by using
+
27  precalculated tables, or calcuating tables on the fly using a double buffer,
+
28  or a line-breakpoint model, a sort of hybridPhasor-Line object.
+
29 */
+
30 
+ +
32 {
+
33 
+
34 public:
+
35 
+
36  /** Constructor.
+
37  */
+ +
39  PDM_SCALE(0.05)
+
40  {
+
41  aOsc.setTable(SIN2048_DATA);
+
42  aAmpEnv.setADLevels(255, 255);
+
43  aAmpEnv.setTimes(50, 300, 60000, 1000);
+
44  kResonantFreqEnv.setADLevels(255,100);
+
45  }
+
46 
+
47  /** Play a note in response to midi input. Params copied from MIDI library HandleNoteOn().
+
48  @param channel is the midi channel
+
49  @param pitch is the midi note
+
50  @param velocity you know what it is
+
51  */
+
52  void noteOn(byte channel, byte pitch, byte velocity)
+
53  {
+
54  kResonantFreqEnv.noteOn();
+
55  aAmpEnv.noteOn();
+
56  freq = mtof(pitch);
+
57  aBaseCounter.setFreq(freq); // gets modulated in updateControl()
+
58  aResonanceFreqCounter.setFreq(freq);
+
59  }
+
60 
+
61 
+
62  /** Stop a note in response to midi input. Params copied from MIDI library HandleNoteOff()
+
63  @param channel is the midi channel
+
64  @param pitch is the midi note
+
65  @param velocity you know what it is
+
66  */
+
67  void noteOff(byte channel, byte pitch, byte velocity)
+
68  {
+
69  aAmpEnv.noteOff();
+
70  kResonantFreqEnv.noteOff();
+
71  }
+
72 
+
73 
+
74  /** Set the resonant filter sweep parameters.
+
75  @param attack ADSR attack
+
76  @param decay ADSR decay
+
77  */
+
78  void setPDEnv(int attack, int decay)
+
79  {
+
80  // sustain and release timesare hardcoded here but don't need to be
+
81  kResonantFreqEnv.setTimes(attack, decay, 60000, 1000);
+
82  kResonantFreqEnv.update();
+
83 
+
84  float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
+
85  aResonanceFreqCounter.setFreq(resonance_freq);
+
86  }
+
87 
+
88 
+
89  /** Update the filter sweep. Use this in updateControl().
+
90  */
+
91  void update()
+
92  {
+
93  aAmpEnv.update();
+
94  kResonantFreqEnv.update();
+
95  // change freq of resonant freq counter, following the envelope
+
96  float resonance_freq = freq + ((float)freq * ((float)kResonantFreqEnv.next()*PDM_SCALE));
+
97  aResonanceFreqCounter.setFreq(resonance_freq);
+
98  }
+
99 
+
100  /** Produce the audio output. This goes in updateAudio().
+
101  */
+
102  int next()
+
103  {
+
104  static byte previous_base_counter;
+
105  byte base_counter = aBaseCounter.next()>>24;
+
106 
+
107  // reset resonance counter (wiki b.)
+
108  if (base_counter<previous_base_counter) aResonanceFreqCounter.set(0);
+
109  previous_base_counter= base_counter;
+
110 
+
111  // index (phase) needs to end up as 11bit to match 2048 wavetable size
+
112  unsigned int index = aResonanceFreqCounter.next()>>21; // 11 bits fits 2048 cell sin table
+
113 
+
114  // amp ramp smooths the jump when aResonanceFreqCounter is reset (wiki d.)
+
115  byte amp_ramp = 255-base_counter;
+
116 
+
117  // wiki e., with amp envelope added
+
118  return ((long)aAmpEnv.next() * amp_ramp * aOsc.atIndex(index))>>16;
+
119 
+
120  // return ((index>>3)*amp_ramp)>>8; // this also sounds good - squelchy sawtooth
+
121  }
+
122 
+
123 
+
124 private:
+
125  const float PDM_SCALE;
+
126  byte amp;
+
127  int freq;
+
128 
+
129  Phasor <MOZZI_AUDIO_RATE> aBaseCounter;
+
130  Phasor <MOZZI_AUDIO_RATE> aResonanceFreqCounter;
+
131 
+
132  Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aOsc;
+
133  ADSR <MOZZI_CONTROL_RATE, MOZZI_AUDIO_RATE> aAmpEnv;
+
134  ADSR <MOZZI_CONTROL_RATE, MOZZI_CONTROL_RATE> kResonantFreqEnv;
+
135 
+
136 };
diff --git a/extras/doc/html/_phasor_8h_source.html b/extras/doc/html/_phasor_8h_source.html index 66dee5839..0195e2c61 100644 --- a/extras/doc/html/_phasor_8h_source.html +++ b/extras/doc/html/_phasor_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Phasor.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,24 +99,129 @@
Phasor.h
-
1 /*
2  * Phasor.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef PHASOR_H_
13 #define PHASOR_H_
14 
15 #include "Arduino.h"
16 #include "mozzi_fixmath.h"
17 
18 #define PHASOR_MAX_VALUE_UL 4294967295UL
19 
20 /** Phasor repeatedly generates a high resolution ramp at a variable frequency.
21 The output of Phasor.next() is an unsigned number between 0 and 4294967295, the
22 maximum that can be expressed by an unsigned 32 bit integer.
23 @tparam UPDATE_RATE the rate at which the Phasor will be updated,
24 usually MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE.
25 */
26 
27 template <unsigned int UPDATE_RATE>
28 class Phasor
29 {
30 private:
31  uint32_t current_value;
32  volatile uint32_t step_size;
33 
34 public:
35  /** Constructor. "Phasor <MOZZI_AUDIO_RATE> myphasor;"
36  makes a Phasor which updates at MOZZI_AUDIO_RATE.
37  */
38  Phasor (){
39  ;
40  }
41 
42  /** Increments one step along the phase.
43  @return the next value.
44  */
45  inline
47  {
48  current_value += step_size; // will wrap
49  return current_value;
50  }
51 
52  /** Set the current value of the phasor. The Phasor will continue incrementing from this
53  value using any previously calculated step size.
54  */
55  inline
56  void set(uint32_t value)
57  {
58  current_value=value;
59  }
60 
61 
62  /** Set the Phasor frequency with an unsigned int.
63  @param frequency is how many times per second to count from
64  0 to the maximum uint32_t value 4294967295.
65  @note Timing 8us
66  */
67  inline
68  void setFreq( int frequency)
69  {
70  step_size = ((((uint32_t)((PHASOR_MAX_VALUE_UL>>8)+1))/(UPDATE_RATE))*frequency)<<8;
71  }
72 
73 
74  /** Set the Phasor frequency with a float.
75  @param frequency is how many times per second to count from
76  0 to the maximum uint32_t value 4294967295.
77  */
78  inline
79  void setFreq(float frequency)
80  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
81  step_size = (uint32_t)(((float)PHASOR_MAX_VALUE_UL/UPDATE_RATE)*frequency);
82  }
83 
84  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
85  Instead of recalculating the phase increment for each frequency in between, you
86  can just calculate the phase increment for each end frequency with
87  phaseIncFromFreq(), then use a Line to interpolate on the fly and use
88  setPhaseInc() to set the phase increment at each step. (Note: I should really
89  profile this with the oscilloscope to see if it's worth the extra confusion!)
90  @param frequency for which you want to calculate a phase increment value.
91  @return the phase increment value which will produce a given frequency.
92  */
93  inline
95  {
96  return ((((uint32_t)((PHASOR_MAX_VALUE_UL>>8)+1))/(UPDATE_RATE))*frequency)<<8;
97  }
98 
99 
100  /** Set a specific phase increment. See phaseIncFromFreq().
101  @param stepsize a phase increment value as calculated by phaseIncFromFreq().
102  */
103  inline
104  void setPhaseInc(uint32_t stepsize)
105  {
106  step_size = stepsize;
107  }
108 
109 };
110 
111 /**
112 @example 06.Synthesis/PWM_Phasing/PWM_Phasing.ino
113 This example demonstrates the Phasor class.
114 */
115 
116 #endif /* PHASOR_H_ */
void set(uint32_t value)
Set the current value of the phasor.
Definition: Phasor.h:56
-
void setFreq(int frequency)
Set the Phasor frequency with an unsigned int.
Definition: Phasor.h:68
-
Phasor()
Constructor.
Definition: Phasor.h:38
-
void setFreq(float frequency)
Set the Phasor frequency with a float.
Definition: Phasor.h:79
-
#define PHASOR_MAX_VALUE_UL
Definition: Phasor.h:18
-
uint32_t phaseIncFromFreq(int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: Phasor.h:94
-
uint32_t next()
Increments one step along the phase.
Definition: Phasor.h:46
-
Phasor repeatedly generates a high resolution ramp at a variable frequency.
Definition: Phasor.h:28
-
void setPhaseInc(uint32_t stepsize)
Set a specific phase increment.
Definition: Phasor.h:104
+
1 /*
+
2  * Phasor.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 PHASOR_H_
+
13 #define PHASOR_H_
+
14 
+
15 #include "Arduino.h"
+
16 #include "mozzi_fixmath.h"
+
17 
+
18 #define PHASOR_MAX_VALUE_UL 4294967295UL
+
19 
+
20 /** Phasor repeatedly generates a high resolution ramp at a variable frequency.
+
21 The output of Phasor.next() is an unsigned number between 0 and 4294967295, the
+
22 maximum that can be expressed by an unsigned 32 bit integer.
+
23 @tparam UPDATE_RATE the rate at which the Phasor will be updated,
+
24 usually MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE.
+
25 */
+
26 
+
27 template <unsigned int UPDATE_RATE>
+
28 class Phasor
+
29 {
+
30 private:
+
31  uint32_t current_value;
+
32  volatile uint32_t step_size;
+
33 
+
34 public:
+
35  /** Constructor. "Phasor <MOZZI_AUDIO_RATE> myphasor;"
+
36  makes a Phasor which updates at MOZZI_AUDIO_RATE.
+
37  */
+
38  Phasor (){
+
39  ;
+
40  }
+
41 
+
42  /** Increments one step along the phase.
+
43  @return the next value.
+
44  */
+
45  inline
+ +
47  {
+
48  current_value += step_size; // will wrap
+
49  return current_value;
+
50  }
+
51 
+
52  /** Set the current value of the phasor. The Phasor will continue incrementing from this
+
53  value using any previously calculated step size.
+
54  */
+
55  inline
+
56  void set(uint32_t value)
+
57  {
+
58  current_value=value;
+
59  }
+
60 
+
61 
+
62  /** Set the Phasor frequency with an unsigned int.
+
63  @param frequency is how many times per second to count from
+
64  0 to the maximum uint32_t value 4294967295.
+
65  @note Timing 8us
+
66  */
+
67  inline
+
68  void setFreq( int frequency)
+
69  {
+
70  step_size = ((((uint32_t)((PHASOR_MAX_VALUE_UL>>8)+1))/(UPDATE_RATE))*frequency)<<8;
+
71  }
+
72 
+
73 
+
74  /** Set the Phasor frequency with a float.
+
75  @param frequency is how many times per second to count from
+
76  0 to the maximum uint32_t value 4294967295.
+
77  */
+
78  inline
+
79  void setFreq(float frequency)
+
80  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
+
81  step_size = (uint32_t)(((float)PHASOR_MAX_VALUE_UL/UPDATE_RATE)*frequency);
+
82  }
+
83 
+
84  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
+
85  Instead of recalculating the phase increment for each frequency in between, you
+
86  can just calculate the phase increment for each end frequency with
+
87  phaseIncFromFreq(), then use a Line to interpolate on the fly and use
+
88  setPhaseInc() to set the phase increment at each step. (Note: I should really
+
89  profile this with the oscilloscope to see if it's worth the extra confusion!)
+
90  @param frequency for which you want to calculate a phase increment value.
+
91  @return the phase increment value which will produce a given frequency.
+
92  */
+
93  inline
+ +
95  {
+
96  return ((((uint32_t)((PHASOR_MAX_VALUE_UL>>8)+1))/(UPDATE_RATE))*frequency)<<8;
+
97  }
+
98 
+
99 
+
100  /** Set a specific phase increment. See phaseIncFromFreq().
+
101  @param stepsize a phase increment value as calculated by phaseIncFromFreq().
+
102  */
+
103  inline
+
104  void setPhaseInc(uint32_t stepsize)
+
105  {
+
106  step_size = stepsize;
+
107  }
+
108 
+
109 };
+
110 
+
111 /**
+
112 @example 06.Synthesis/PWM_Phasing/PWM_Phasing.ino
+
113 This example demonstrates the Phasor class.
+
114 */
+
115 
+
116 #endif /* PHASOR_H_ */
diff --git a/extras/doc/html/_portamento_8h_source.html b/extras/doc/html/_portamento_8h_source.html index 2b866c1aa..fbb958b91 100644 --- a/extras/doc/html/_portamento_8h_source.html +++ b/extras/doc/html/_portamento_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Portamento.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,21 +99,119 @@
Portamento.h
-
1 /*
2  * Portamento.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef PORTAMENTO_H_
13 #define PORTAMENTO_H_
14 
15 #include "mozzi_midi.h"
16 #include "mozzi_fixmath.h"
17 #include "Line.h"
18 
19 /** A simple portamento (pitch slide from one note to the next) effect, useful for note-based applications.
20 */
21 template <unsigned int CONTROL_UPDATE_RATE>
22 class
23  Portamento {
24 
25 public:
26 
27  /** Constructor.
28  */
30  MICROS_PER_CONTROL_STEP(1000000/CONTROL_UPDATE_RATE)
31  {
32  }
33 
34  /** Set how long it will take to slide from note to note, in milliseconds.
35  @param milliseconds
36  */
37  inline
38  void setTime(unsigned int milliseconds){
39  //control_steps_per_portamento = ((long)milliseconds*1000)/MICROS_PER_CONTROL_STEP; // more accurate but slower
40  control_steps_per_portamento = convertMsecToControlSteps(milliseconds);
41  }
42 
43  /** Call this at note-on, it initialises the portamento.
44  @param note a midi note number, a whole number.
45  */
46  inline
47  void start(uint8_t note) {
48  target_freq = Q16n16_mtof(Q8n0_to_Q16n16(note));
49  aPortamentoLine.set(target_freq, control_steps_per_portamento);
50  countdown = control_steps_per_portamento;
51  portamento_on=true;
52  }
53 
54  /** Call this at note-on, it initialises the portamento.
55  @param note a midi note number in Q16n16 fractional format. This is useful for non-whole note or detuned values.
56  */
57  inline
58  void start(Q16n16 note) {
59  target_freq = Q16n16_mtof(note);
60  aPortamentoLine.set(target_freq, control_steps_per_portamento);
61  countdown = control_steps_per_portamento;
62  portamento_on=true;
63  }
64 
65 
66  /** Use this in updateControl() to provide a frequency to the oscillator it's controlling.
67  For example:
68  myOscil.setFreq_Q16n16(myPortamento.next());
69  @return a Q16n16 fractional frequency value, progressing smoothly between successive notes.
70  */
71  inline
73  if (portamento_on==true){
74  if(--countdown < 0) {
75  // stay level when portamento has finished
76  aPortamentoLine.set(target_freq, target_freq, control_steps_per_portamento);
77  portamento_on=false;
78  }
79  }
80  return aPortamentoLine.next();
81  }
82 
83  private:
84 
85  int countdown;
86  int control_steps_per_portamento;
87  Q16n16 target_freq;
88  bool portamento_on;
89  const unsigned int MICROS_PER_CONTROL_STEP;
90  Line <Q16n16> aPortamentoLine;
91 
92 
93  // copied from ADSR.h
94  inline
95  static const unsigned int convertMsecToControlSteps(unsigned int msec){
96  return (uint16_t) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
97  }
98 
99 };
100 
101 /**
102 @example 05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino
103 This example demonstrates the Portamento class.
104 */
105 
106 #endif /* PORTAMENTO_H_ */
Q16n16 Q16n16_mtof(Q16n16 midival_fractional)
Converts midi note number to frequency with speed and accuracy.
Definition: mozzi_midi.h:97
-
void setTime(unsigned int milliseconds)
Set how long it will take to slide from note to note, in milliseconds.
Definition: Portamento.h:38
-
void start(Q16n16 note)
Call this at note-on, it initialises the portamento.
Definition: Portamento.h:58
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:44
-
Q16n16 next()
Use this in updateControl() to provide a frequency to the oscillator it&#39;s controlling.
Definition: Portamento.h:72
-
Portamento()
Constructor.
Definition: Portamento.h:29
+
1 /*
+
2  * Portamento.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 PORTAMENTO_H_
+
13 #define PORTAMENTO_H_
+
14 
+
15 #include "mozzi_midi.h"
+
16 #include "mozzi_fixmath.h"
+
17 #include "Line.h"
+
18 
+
19 /** A simple portamento (pitch slide from one note to the next) effect, useful for note-based applications.
+
20 */
+
21 template <unsigned int CONTROL_UPDATE_RATE>
+
22 class
+
23  Portamento {
+
24 
+
25 public:
+
26 
+
27  /** Constructor.
+
28  */
+ +
30  MICROS_PER_CONTROL_STEP(1000000/CONTROL_UPDATE_RATE)
+
31  {
+
32  }
+
33 
+
34  /** Set how long it will take to slide from note to note, in milliseconds.
+
35  @param milliseconds
+
36  */
+
37  inline
+
38  void setTime(unsigned int milliseconds){
+
39  //control_steps_per_portamento = ((long)milliseconds*1000)/MICROS_PER_CONTROL_STEP; // more accurate but slower
+
40  control_steps_per_portamento = convertMsecToControlSteps(milliseconds);
+
41  }
+
42 
+
43  /** Call this at note-on, it initialises the portamento.
+
44  @param note a midi note number, a whole number.
+
45  */
+
46  inline
+
47  void start(uint8_t note) {
+
48  target_freq = Q16n16_mtof(Q8n0_to_Q16n16(note));
+
49  aPortamentoLine.set(target_freq, control_steps_per_portamento);
+
50  countdown = control_steps_per_portamento;
+
51  portamento_on=true;
+
52  }
+
53 
+
54  /** Call this at note-on, it initialises the portamento.
+
55  @param note a midi note number in Q16n16 fractional format. This is useful for non-whole note or detuned values.
+
56  */
+
57  inline
+
58  void start(Q16n16 note) {
+
59  target_freq = Q16n16_mtof(note);
+
60  aPortamentoLine.set(target_freq, control_steps_per_portamento);
+
61  countdown = control_steps_per_portamento;
+
62  portamento_on=true;
+
63  }
+
64 
+
65 
+
66  /** Use this in updateControl() to provide a frequency to the oscillator it's controlling.
+
67  For example:
+
68  myOscil.setFreq_Q16n16(myPortamento.next());
+
69  @return a Q16n16 fractional frequency value, progressing smoothly between successive notes.
+
70  */
+
71  inline
+ +
73  if (portamento_on==true){
+
74  if(--countdown < 0) {
+
75  // stay level when portamento has finished
+
76  aPortamentoLine.set(target_freq, target_freq, control_steps_per_portamento);
+
77  portamento_on=false;
+
78  }
+
79  }
+
80  return aPortamentoLine.next();
+
81  }
+
82 
+
83  private:
+
84 
+
85  int countdown;
+
86  int control_steps_per_portamento;
+
87  Q16n16 target_freq;
+
88  bool portamento_on;
+
89  const unsigned int MICROS_PER_CONTROL_STEP;
+
90  Line <Q16n16> aPortamentoLine;
+
91 
+
92 
+
93  // copied from ADSR.h
+
94  inline
+
95  static const unsigned int convertMsecToControlSteps(unsigned int msec){
+
96  return (uint16_t) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
+
97  }
+
98 
+
99 };
+
100 
+
101 /**
+
102 @example 05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino
+
103 This example demonstrates the Portamento class.
+
104 */
+
105 
+
106 #endif /* PORTAMENTO_H_ */
diff --git a/extras/doc/html/_r_cpoll_8h_source.html b/extras/doc/html/_r_cpoll_8h_source.html index e1ff2b771..ed47ca438 100644 --- a/extras/doc/html/_r_cpoll_8h_source.html +++ b/extras/doc/html/_r_cpoll_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: RCpoll.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,18 +99,79 @@
RCpoll.h
-
1 #ifndef RCPOLL_H
2 #define RCPOLL_H
3 
4 
5 /**
6 A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.
7 This is designed to be used in updateControl(). Each time it is called, it checks if a capacitor has charged,
8 and returns an output reflecting how long it took for the most recent charge.
9 */
10 
11 template <unsigned char SENSOR_PIN>
12 class RCpoll
13 {
14 
15 public:
16  /** Constructor.
17  */
18  RCpoll():result(0),rc_cued(true), output(0)
19  {
20  ;
21  }
22 
23  /** Checks whether the capacitor has charged, and returns how long it took for the most recent charge.
24  This would preferably be called in updateControl(), but if the resolution isn't fine enough or the
25  pin charges too fast for updateControl() to catch, try it in updateAudio().
26  @return the sensor value, reflected in how many checking cycles it took to charge the capacitor.
27  */
28  inline
29  unsigned int next(){
30  if (rc_cued){
31  pinMode(SENSOR_PIN, INPUT); // turn pin into an input and time till pin goes low
32  digitalWrite(SENSOR_PIN, LOW); // turn pullups off - or it won't work
33  rc_cued = false;
34  }
35  if(digitalRead(SENSOR_PIN)){ // wait for pin to go low
36  result++;
37  }
38  else{
39  output = result;
40  result = 0;
41  pinMode(SENSOR_PIN, OUTPUT); // make pin OUTPUT
42  digitalWrite(SENSOR_PIN, HIGH); // make pin HIGH to discharge capacitor - see the schematic
43  rc_cued = true;
44  }
45  return output;
46  }
47 
48 private:
49  unsigned int result;
50  boolean rc_cued;
51  unsigned int output;
52 
53 };
54 
55 #endif // #ifndef RCPOLL_H
unsigned int next()
Checks whether the capacitor has charged, and returns how long it took for the most recent charge...
Definition: RCpoll.h:29
-
A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.
Definition: RCpoll.h:12
-
RCpoll()
Constructor.
Definition: RCpoll.h:18
+
1 /*
+
2  * RCpoll.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2014-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 RCPOLL_H
+
13 #define RCPOLL_H
+
14 
+
15 
+
16 /**
+
17 A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.
+
18 This is designed to be used in updateControl(). Each time it is called, it checks if a capacitor has charged,
+
19 and returns an output reflecting how long it took for the most recent charge.
+
20 */
+
21 
+
22 template <unsigned char SENSOR_PIN>
+
23 class RCpoll
+
24 {
+
25 
+
26 public:
+
27  /** Constructor.
+
28  */
+
29  RCpoll():result(0),rc_cued(true), output(0)
+
30  {
+
31  ;
+
32  }
+
33 
+
34  /** Checks whether the capacitor has charged, and returns how long it took for the most recent charge.
+
35  This would preferably be called in updateControl(), but if the resolution isn't fine enough or the
+
36  pin charges too fast for updateControl() to catch, try it in updateAudio().
+
37  @return the sensor value, reflected in how many checking cycles it took to charge the capacitor.
+
38  */
+
39  inline
+
40  unsigned int next(){
+
41  if (rc_cued){
+
42  pinMode(SENSOR_PIN, INPUT); // turn pin into an input and time till pin goes low
+
43  digitalWrite(SENSOR_PIN, LOW); // turn pullups off - or it won't work
+
44  rc_cued = false;
+
45  }
+
46  if(digitalRead(SENSOR_PIN)){ // wait for pin to go low
+
47  result++;
+
48  }
+
49  else{
+
50  output = result;
+
51  result = 0;
+
52  pinMode(SENSOR_PIN, OUTPUT); // make pin OUTPUT
+
53  digitalWrite(SENSOR_PIN, HIGH); // make pin HIGH to discharge capacitor - see the schematic
+
54  rc_cued = true;
+
55  }
+
56  return output;
+
57  }
+
58 
+
59 private:
+
60  unsigned int result;
+
61  boolean rc_cued;
+
62  unsigned int output;
+
63 
+
64 };
+
65 
+
66 #endif // #ifndef RCPOLL_H
diff --git a/extras/doc/html/_resonant_filter_8h_source.html b/extras/doc/html/_resonant_filter_8h_source.html index 20eb08478..f80dbada1 100644 --- a/extras/doc/html/_resonant_filter_8h_source.html +++ b/extras/doc/html/_resonant_filter_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: ResonantFilter.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,30 +99,253 @@
ResonantFilter.h
-
1 /*
2  * ResonantFilter.h
3  *
4  * Copyright 2012 Tim Barrass
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #ifndef RESONANTFILTER_H_
14 #define RESONANTFILTER_H_
15 
16 #include "IntegerType.h"
17 #include "AudioOutput.h"
18 #include "meta.h"
19 
20 
21 
22 /*
23 simple resonant filter posted to musicdsp.org by Paul Kellett
24 http://www.musicdsp.org/archive.php?classid=3#259, applying the
25 modification from Peter Schoffhauzer to make it able to output
26 all filter types (LowPass, HighPass, Notch and BandPass).
27 
28 The generic filter is ResonantFilter<unsigned_t type, FILTER_TYPE>.
29  - type specifies the type expected for the cutoff and resonance. Only uint8_t and uint16_t have been tested. These are denoted 8bits and 16bits versions of the filter in the following.
30  - FILTER_TYPE specifies the filter type. LOWPASS, BANDPASS, HIGHPASS and NOTCH are available types.
31 
32 Two versions are available: the 8bits and 16bits versions (see above).
33 The 8bits version is an optimized version that uses 8bits values to set
34 the resonance and the cutoff_freq. It can works on 8bits samples only
35 on 8bits platforms.
36 The 16bits version consumes more CPU ressources but uses 16bits values
37 for resonance and cutoff_freq and can work on samples up to 16bits on
38 8bits platforms and up to 32 on 32bits platforms.
39 
40 The filter can be instanciated using the template version ResonantFilter<unsigned_t type, FILTER_TYPE>. For ease of use, the following types are also accepted:
41 
42 8bits versions: LowPassFilter, HighPassFilter, BandPassFilter, NotchFilter
43 16bits versions: LowPassFilter16, HighPassFilter16, BandPassFilter16, NotchFilter16
44 
45 
46 
47 //// ALGORITHM ////
48 // set feedback amount given f and q between 0 and 1
49 fb = q + q/(1.0 - f);
50 In order to avoid a slow division we use the use a Taylor expansion to approximate 1/(1.0 - f):
51 Close to f=0: 1/(1.0-f) approx 1.0+f.
52 Hence: fb = q + q * (1.0 + f)
53 This approximation is less and less valid with an increasing cutoff, leading to a reduction of the resonance of the filter at high cutoff frequencies.
54 
55 // for each sample...
56 buf0 = buf0 + f * (in - buf0 + fb * (buf0 - buf1));
57 buf1 = buf1 + f * (buf0 - buf1);
58 out = buf1; // LowPass
59 out = in - buf0; // HighPass
60 out = buf0 - buf1; // BandPass
61 out = in - buf0 + buf1; // Notch
62 
63 fixed point version of the filter
64 "dave's blog of art and programming" http://www.pawfal.org/dave/blog/2011/09/
65 */
66 
67 
68 
69 
70 
71 enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
72 
73 /** A generic resonant filter for audio signals.
74  */
75 template<int8_t FILTER_TYPE, typename su=uint8_t>
77 {
78 
79 public:
80  /** Constructor.
81  */
83 
84 
85  /** deprecated. Use setCutoffFreqAndResonance(su cutoff, su
86  resonance).
87 
88  Set the cut off frequency,
89  @param cutoff use the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2.
90  Be careful of distortion at the lower end, especially with high resonance.
91  */
92  void setCutoffFreq(su cutoff)
93  {
94  f = cutoff;
95  fb = q + ucfxmul(q, (typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type) SHIFTED_1 + cutoff);
96  }
97 
98  /** deprecated. Use setCutoffFreqAndResonance(su cutoff, su
99  resonance).
100 
101  Set the resonance. If you hear unwanted distortion, back off the resonance.
102  After setting resonance, you need to call setCuttoffFreq() to hear the change!
103  @param resonance in the range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, with 255/65535 being most resonant
104  @note Remember to call setCuttoffFreq() after resonance is changed!
105  */
106  void setResonance(su resonance) { q = resonance; }
107 
108  /**
109  Set the cut off frequency and resonance. Replaces setCutoffFreq() and
110  setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)
111  @param cutoff range 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16
112  Be careful of distortion at the lower end, especially with high resonance.
113  @param resonance range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
114  */
115  void setCutoffFreqAndResonance(su cutoff, su resonance)
116  {
117  f = cutoff;
118  q = resonance; // hopefully optimised away when compiled, just here for
119  // backwards compatibility
120  fb = q + ucfxmul(q,(typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type) SHIFTED_1 + cutoff);
121  }
122 
123  /** Calculate the next sample, given an input signal.
124  @param in the signal input. Should not be more than 8bits on 8bits platforms (Arduino) if using the 8bits version and not 16bits version.
125  @return the signal output.
126  @note Timing: about 11us.
127  */
128  // 10.5 to 12.5 us, mostly 10.5 us (was 14us)
130  {
131  advanceBuffers(in);
132  return current(in, Int2Type<FILTER_TYPE>());
133  }
134 
135 protected:
136  su q;
137  su f;
138  typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type fb;
139  AudioOutputStorage_t buf0, buf1;
140  const uint8_t FX_SHIFT = sizeof(su) << 3;
141  const uint8_t FX_SHIFT_M_1 = FX_SHIFT-1;
142  const su SHIFTED_1 = (1<<FX_SHIFT)-1;
143 
144  // // multiply two fixed point numbers (returns fixed point)
145  // inline
146  // long fxmul(long a, long b)
147  // {
148  // return (a*b)>>FX_SHIFT;
149  // }
150 
151  inline void advanceBuffers(AudioOutputStorage_t in)
152  {
153  buf0 += fxmul(((in - buf0) + fxmul(fb, buf0 - buf1)), f);
154  buf1 += ifxmul(buf0 - buf1, f); // could overflow if input changes fast
155  }
156 
157  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<LOWPASS>) {return buf1;}
158 
159  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<HIGHPASS>) {return in - buf0;}
160 
161  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<BANDPASS>) {return buf0-buf1;}
162 
163  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<NOTCH>) {return in - buf0 + buf1;}
164 
165  // multiply two fixed point numbers (returns fixed point)
166  inline typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type ucfxmul(su a, typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type b)
167  {
168  return (((typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type)a * (b >> 1)) >> (FX_SHIFT_M_1));
169  }
170 
171  // multiply two fixed point numbers (returns fixed point)
172  inline typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(su)-1>::signed_type ifxmul(typename IntegerType<sizeof(AudioOutputStorage_t )+sizeof(su)-1>::signed_type a, su b) { return ((a * b) >> FX_SHIFT); }
173 
174  // multiply two fixed point numbers (returns fixed point)
175  inline typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type fxmul(typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(su)-1>::signed_type b) { return ((a * b) >> FX_SHIFT); }
176 };
177 
178 /** A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime.
179 Behaves like ResonantFilter for setting the resonance and cutoff frequency.
180 Like ResonantFilter, it can be used on different sample sizes: MultiResonantFilter<uint8_t> and MultiResonantFilter<uint16_t> have been tested.
181 For the former, both cutoff and resonance are uint8_t, hence between 0-255.
182 For the later, both cutoff and resonance are uint16_t, hence between 0-65535.
183  */
184 template<typename su=uint8_t>
185 class MultiResonantFilter: public ResonantFilter<LOWPASS,su>
186 {
187 public:
188  /** Compute the filters, given an input signal.
189  @param in the signal input. Should not be more than 8bits on 8bits platforms (Arduino) if using the 8bits version and not 16bits version.
190  */
191 inline void next (AudioOutputStorage_t in)
192  {
193  last_in = in;
194  ResonantFilter<LOWPASS,su>::advanceBuffers(in);
195  }
196  /** Return the input filtered with a lowpass filter
197  @return the filtered signal output.
198  */
199  inline AudioOutputStorage_t low() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<LOWPASS>());}
200  /** Return the input filtered with a highpass filter
201  @return the filtered signal output.
202  */
203  inline AudioOutputStorage_t high() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<HIGHPASS>());}
204  /** Return the input filtered with a bandpass filter
205  @return the filtered signal output.
206  */
207  inline AudioOutputStorage_t band() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<BANDPASS>());}
208  /** Return the input filtered with a notch filter
209  @return the filtered signal output.
210  */
211  inline AudioOutputStorage_t notch() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<NOTCH>());}
212 
213 private:
214  AudioOutputStorage_t last_in;
215 };
216 
217 
218 typedef ResonantFilter<LOWPASS> LowPassFilter;
219 typedef ResonantFilter<LOWPASS, uint16_t> LowPassFilter16;
220 /*
221 typedef ResonantFilter<uint8_t, HIGHPASS> HighPassFilter;
222 typedef ResonantFilter<uint16_t, HIGHPASS> HighPassFilter16;
223 typedef ResonantFilter<uint8_t, BANDPASS> BandPassFilter;
224 typedef ResonantFilter<uint16_t, BANDPASS> BandPassFilter16;
225 typedef ResonantFilter<uint8_t, NOTCH> NotchFilter;
226 typedef ResonantFilter<uint16_t, NOTCH> NotchFilter16;
227 */
228 
229 
230 /**
231 @example 10.Audio_Filters/ResonantFilter/ResonantFilter.ino
232 This example demonstrates the ResonantFilter specification of this class.
233 
234 @example 10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino
235 This example demonstrates the ResonantFilter16 specification of this class.
236 
237 @example 10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino
238 This example demonstrates the MultiResonantFilter specification of this class.
239 */
240 
241 #endif /* RESONANTFILTER_H_ */
void setCutoffFreqAndResonance(su cutoff, su resonance)
Set the cut off frequency and resonance.
-
AudioOutputStorage_t next(AudioOutputStorage_t in)
Calculate the next sample, given an input signal.
-
AudioOutputStorage_t notch()
Return the input filtered with a notch filter.
-
Provides appropriate integer types that can bit the given number of bytes on this platform (at most 6...
Definition: IntegerType.h:9
-
Enables you to instantiate a template based on an integer value.
Definition: meta.h:22
-
void next(AudioOutputStorage_t in)
Compute the filters, given an input signal.
-
A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at ...
-
AudioOutputStorage_t low()
Return the input filtered with a lowpass filter.
-
AudioOutputStorage_t high()
Return the input filtered with a highpass filter.
-
AudioOutputStorage_t band()
Return the input filtered with a bandpass filter.
-
void setResonance(su resonance)
deprecated.
-
A generic resonant filter for audio signals.
-
void setCutoffFreq(su cutoff)
deprecated.
-
ResonantFilter()
Constructor.
-
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:53
+
1 /*
+
2  * ResonantFilter.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 RESONANTFILTER_H_
+
13 #define RESONANTFILTER_H_
+
14 
+
15 #include "IntegerType.h"
+
16 #include "AudioOutput.h"
+
17 #include "meta.h"
+
18 
+
19 
+
20 
+
21 /*
+
22 simple resonant filter posted to musicdsp.org by Paul Kellett
+
23 http://www.musicdsp.org/archive.php?classid=3#259, applying the
+
24 modification from Peter Schoffhauzer to make it able to output
+
25 all filter types (LowPass, HighPass, Notch and BandPass).
+
26 
+
27 The generic filter is ResonantFilter<unsigned_t type, FILTER_TYPE>.
+
28  - type specifies the type expected for the cutoff and resonance. Only uint8_t and uint16_t have been tested. These are denoted 8bits and 16bits versions of the filter in the following.
+
29  - FILTER_TYPE specifies the filter type. LOWPASS, BANDPASS, HIGHPASS and NOTCH are available types.
+
30 
+
31 Two versions are available: the 8bits and 16bits versions (see above).
+
32 The 8bits version is an optimized version that uses 8bits values to set
+
33 the resonance and the cutoff_freq. It can works on 8bits samples only
+
34 on 8bits platforms.
+
35 The 16bits version consumes more CPU ressources but uses 16bits values
+
36 for resonance and cutoff_freq and can work on samples up to 16bits on
+
37 8bits platforms and up to 32 on 32bits platforms.
+
38 
+
39 The filter can be instanciated using the template version ResonantFilter<unsigned_t type, FILTER_TYPE>. For ease of use, the following types are also accepted:
+
40 
+
41 8bits versions: LowPassFilter, HighPassFilter, BandPassFilter, NotchFilter
+
42 16bits versions: LowPassFilter16, HighPassFilter16, BandPassFilter16, NotchFilter16
+
43 
+
44 
+
45 
+
46 //// ALGORITHM ////
+
47 // set feedback amount given f and q between 0 and 1
+
48 fb = q + q/(1.0 - f);
+
49 In order to avoid a slow division we use the use a Taylor expansion to approximate 1/(1.0 - f):
+
50 Close to f=0: 1/(1.0-f) approx 1.0+f.
+
51 Hence: fb = q + q * (1.0 + f)
+
52 This approximation is less and less valid with an increasing cutoff, leading to a reduction of the resonance of the filter at high cutoff frequencies.
+
53 
+
54 // for each sample...
+
55 buf0 = buf0 + f * (in - buf0 + fb * (buf0 - buf1));
+
56 buf1 = buf1 + f * (buf0 - buf1);
+
57 out = buf1; // LowPass
+
58 out = in - buf0; // HighPass
+
59 out = buf0 - buf1; // BandPass
+
60 out = in - buf0 + buf1; // Notch
+
61 
+
62 fixed point version of the filter
+
63 "dave's blog of art and programming" http://www.pawfal.org/dave/blog/2011/09/
+
64 */
+
65 
+
66 
+
67 
+
68 
+
69 
+
70 enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
+
71 
+
72 /** A generic resonant filter for audio signals.
+
73  */
+
74 template<int8_t FILTER_TYPE, typename su=uint8_t>
+ +
76 {
+
77 
+
78 public:
+
79  /** Constructor.
+
80  */
+ +
82 
+
83 
+
84  /** deprecated. Use setCutoffFreqAndResonance(su cutoff, su
+
85  resonance).
+
86 
+
87  Set the cut off frequency,
+
88  @param cutoff use the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2.
+
89  Be careful of distortion at the lower end, especially with high resonance.
+
90  */
+
91  void setCutoffFreq(su cutoff)
+
92  {
+
93  f = cutoff;
+
94  fb = q + ucfxmul(q, (typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type) SHIFTED_1 + cutoff);
+
95  }
+
96 
+
97  /** deprecated. Use setCutoffFreqAndResonance(su cutoff, su
+
98  resonance).
+
99 
+
100  Set the resonance. If you hear unwanted distortion, back off the resonance.
+
101  After setting resonance, you need to call setCuttoffFreq() to hear the change!
+
102  @param resonance in the range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, with 255/65535 being most resonant
+
103  @note Remember to call setCuttoffFreq() after resonance is changed!
+
104  */
+
105  void setResonance(su resonance) { q = resonance; }
+
106 
+
107  /**
+
108  Set the cut off frequency and resonance. Replaces setCutoffFreq() and
+
109  setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)
+
110  @param cutoff range 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16
+
111  Be careful of distortion at the lower end, especially with high resonance.
+
112  @param resonance range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
+
113  */
+
114  void setCutoffFreqAndResonance(su cutoff, su resonance)
+
115  {
+
116  f = cutoff;
+
117  q = resonance; // hopefully optimised away when compiled, just here for
+
118  // backwards compatibility
+
119  fb = q + ucfxmul(q,(typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type) SHIFTED_1 + cutoff);
+
120  }
+
121 
+
122  /** Calculate the next sample, given an input signal.
+
123  @param in the signal input. Should not be more than 8bits on 8bits platforms (Arduino) if using the 8bits version and not 16bits version.
+
124  @return the signal output.
+
125  @note Timing: about 11us.
+
126  */
+
127  // 10.5 to 12.5 us, mostly 10.5 us (was 14us)
+ +
129  {
+
130  advanceBuffers(in);
+
131  return current(in, Int2Type<FILTER_TYPE>());
+
132  }
+
133 
+
134 protected:
+
135  su q;
+
136  su f;
+
137  typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type fb;
+
138  AudioOutputStorage_t buf0, buf1;
+
139  const uint8_t FX_SHIFT = sizeof(su) << 3;
+
140  const uint8_t FX_SHIFT_M_1 = FX_SHIFT-1;
+
141  const su SHIFTED_1 = (1<<FX_SHIFT)-1;
+
142 
+
143  // // multiply two fixed point numbers (returns fixed point)
+
144  // inline
+
145  // long fxmul(long a, long b)
+
146  // {
+
147  // return (a*b)>>FX_SHIFT;
+
148  // }
+
149 
+
150  inline void advanceBuffers(AudioOutputStorage_t in)
+
151  {
+
152  buf0 += fxmul(((in - buf0) + fxmul(fb, buf0 - buf1)), f);
+
153  buf1 += ifxmul(buf0 - buf1, f); // could overflow if input changes fast
+
154  }
+
155 
+
156  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<LOWPASS>) {return buf1;}
+
157 
+
158  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<HIGHPASS>) {return in - buf0;}
+
159 
+
160  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<BANDPASS>) {return buf0-buf1;}
+
161 
+
162  inline AudioOutputStorage_t current(AudioOutputStorage_t in, Int2Type<NOTCH>) {return in - buf0 + buf1;}
+
163 
+
164  // multiply two fixed point numbers (returns fixed point)
+
165  inline typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type ucfxmul(su a, typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type b)
+
166  {
+
167  return (((typename IntegerType<sizeof(su)+sizeof(su)>::unsigned_type)a * (b >> 1)) >> (FX_SHIFT_M_1));
+
168  }
+
169 
+
170  // multiply two fixed point numbers (returns fixed point)
+
171  inline typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(su)-1>::signed_type ifxmul(typename IntegerType<sizeof(AudioOutputStorage_t )+sizeof(su)-1>::signed_type a, su b) { return ((a * b) >> FX_SHIFT); }
+
172 
+
173  // multiply two fixed point numbers (returns fixed point)
+
174  inline typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type fxmul(typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType<sizeof(AudioOutputStorage_t)+sizeof(su)-1>::signed_type b) { return ((a * b) >> FX_SHIFT); }
+
175 };
+
176 
+
177 /** A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime.
+
178 Behaves like ResonantFilter for setting the resonance and cutoff frequency.
+
179 Like ResonantFilter, it can be used on different sample sizes: MultiResonantFilter<uint8_t> and MultiResonantFilter<uint16_t> have been tested.
+
180 For the former, both cutoff and resonance are uint8_t, hence between 0-255.
+
181 For the later, both cutoff and resonance are uint16_t, hence between 0-65535.
+
182  */
+
183 template<typename su=uint8_t>
+
184 class MultiResonantFilter: public ResonantFilter<LOWPASS,su>
+
185 {
+
186 public:
+
187  /** Compute the filters, given an input signal.
+
188  @param in the signal input. Should not be more than 8bits on 8bits platforms (Arduino) if using the 8bits version and not 16bits version.
+
189  */
+
190 inline void next (AudioOutputStorage_t in)
+
191  {
+
192  last_in = in;
+
193  ResonantFilter<LOWPASS,su>::advanceBuffers(in);
+
194  }
+
195  /** Return the input filtered with a lowpass filter
+
196  @return the filtered signal output.
+
197  */
+
198  inline AudioOutputStorage_t low() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<LOWPASS>());}
+
199  /** Return the input filtered with a highpass filter
+
200  @return the filtered signal output.
+
201  */
+
202  inline AudioOutputStorage_t high() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<HIGHPASS>());}
+
203  /** Return the input filtered with a bandpass filter
+
204  @return the filtered signal output.
+
205  */
+
206  inline AudioOutputStorage_t band() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<BANDPASS>());}
+
207  /** Return the input filtered with a notch filter
+
208  @return the filtered signal output.
+
209  */
+
210  inline AudioOutputStorage_t notch() {return ResonantFilter<LOWPASS,su>::current(last_in,Int2Type<NOTCH>());}
+
211 
+
212 private:
+
213  AudioOutputStorage_t last_in;
+
214 };
+
215 
+
216 
+
217 typedef ResonantFilter<LOWPASS> LowPassFilter;
+
218 typedef ResonantFilter<LOWPASS, uint16_t> LowPassFilter16;
+
219 /*
+
220 typedef ResonantFilter<uint8_t, HIGHPASS> HighPassFilter;
+
221 typedef ResonantFilter<uint16_t, HIGHPASS> HighPassFilter16;
+
222 typedef ResonantFilter<uint8_t, BANDPASS> BandPassFilter;
+
223 typedef ResonantFilter<uint16_t, BANDPASS> BandPassFilter16;
+
224 typedef ResonantFilter<uint8_t, NOTCH> NotchFilter;
+
225 typedef ResonantFilter<uint16_t, NOTCH> NotchFilter16;
+
226 */
+
227 
+
228 
+
229 /**
+
230 @example 10.Audio_Filters/ResonantFilter/ResonantFilter.ino
+
231 This example demonstrates the ResonantFilter specification of this class.
+
232 
+
233 @example 10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino
+
234 This example demonstrates the ResonantFilter16 specification of this class.
+
235 
+
236 @example 10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino
+
237 This example demonstrates the MultiResonantFilter specification of this class.
+
238 */
+
239 
+
240 #endif /* RESONANTFILTER_H_ */
diff --git a/extras/doc/html/_reverb_tank_8h_source.html b/extras/doc/html/_reverb_tank_8h_source.html index b15f7d516..d583caeba 100644 --- a/extras/doc/html/_reverb_tank_8h_source.html +++ b/extras/doc/html/_reverb_tank_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: ReverbTank.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,22 +99,146 @@
ReverbTank.h
-
1 #ifndef REVERBTANK_H
2 #define REVERBTANK_H
3 
4 /*
5  * ReverbTank.h
6  *
7  * Copyright 2013 Tim Barrass.
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 
15 #include "AudioDelay.h"
16 /**
17 A reverb which sounds like the inside of a tin can.
18 ReverbTank is small enough to fit on the Arduino Nano, which for some reason
19 wasn't able to fit a larger version which did fit on other 328 based boards. For
20 simplicity, ReverbTank has hardcoded maximum delay sizes but also has default
21 delay times which can be changed in the constructor or by setting during run
22 time to allow live tweaking.
23 This is a highly simplified design drawing on and probably misinterpreting
24 Miller Puckette's G08.reverb recirculating reverb example for Pure Data.
25 
26 The room size according to the maximum delay lengths corresponds to:
27 
28 early reflections and recirculating delay 1: 128/16384 seconds * 340.29 m/s speed of sound = 3.5 metres
29 recirculating delay 2: 7 metres
30 It looks bigger on paper than it sounds.
31 */
32 class
33  ReverbTank {
34 
35 public:
36  /** Constructor. This has default values for the early reflection times, recirculating delay lengths and feedback level,
37  which can be changed here in the constructor or set with other functions during run time.
38  @param early_reflection1 how long in delay cells till the first early reflection, from 0 to 127
39  @param early_reflection2 how long in delay cells till the second early reflection, from early_reflection1 to 127
40  @param early_reflection3 how long in delay cells till the third early reflection, from early_reflection2 to 127
41  @param loop1_delay how long in delay cells for the first recirculating delay, form 0 to 127
42  @param loop2_delay how long in delay cells for the first recirculating delay, form 0 to 255
43  @param feedback_level how much recirculation, from -128 to 127
44  */
46  int8_t early_reflection1 = 37,
47  int8_t early_reflection2 = 77,
48  int8_t early_reflection3 = 127,
49  int8_t loop1_delay=117,
50  uint8_t loop2_delay=255,
51  int8_t feedback_level = 85):
54  {
55  aLoopDel1.set(loop1_delay);
56  aLoopDel2.set(loop2_delay);
57  }
58 
59 
60  /** Process the next audio sample and return the reverbed signal. This returns only the "wet" signal,
61  which can be combined with the dry input signal in the sketch.
62  @param input the audio signal to process
63  @return the processed signal
64  */
65  int next(int input){
66  static int recycle1, recycle2;
67 
68  // early reflections
69  int asig = aLoopDel0.next(input, _early_reflection1);
70  asig += aLoopDel0.read(_early_reflection2);
71  asig += aLoopDel0.read(_early_reflection3);
72  asig >>= 2;
73 
74  // recirculating delays
75  int8_t feedback_sig1 = (int8_t) min(max(((recycle1 * _feedback_level)>>7),-128),127); // feedback clipped
76  int8_t feedback_sig2 = (int8_t) min(max(((recycle2 * _feedback_level)>>7),-128),127); // feedback clipped
77  int sig3 = aLoopDel1.next(asig+feedback_sig1);
78  int sig4 = aLoopDel2.next(asig+feedback_sig2);
79  recycle1 = sig3 + sig4;
80  recycle2 = sig3 - sig4;
81 
82  return recycle1;
83  }
84 
85 
86  /** Set the early reflection times in terms of delay cells.
87  @param early_reflection1 how long in delay cells till the first early reflection, from 0 to 127
88  @param early_reflection2 how long in delay cells till the second early reflection, from early_reflection1 to 127
89  @param early_reflection3 how long in delay cells till the third early reflection, from early_reflection2 to 127
90  */
91  void setEarlyReflections(int8_t early_reflection1, int8_t early_reflection2, int8_t early_reflection3){
92  _early_reflection1=early_reflection1;
93  _early_reflection2=early_reflection2;
94  _early_reflection3=early_reflection3;
95  }
96 
97 
98  /** Set the loop delay times in terms of delay cells.
99  @param loop1_delay how long in delay cells for the first recirculating delay, form 0 to 127
100  @param loop2_delay how long in delay cells for the first recirculating delay, form 0 to 255
101  */
102  void setLoopDelays(int8_t loop1_delay, uint8_t loop2_delay){
103  aLoopDel1.set(loop1_delay);
104  aLoopDel2.set(loop2_delay);
105  }
106 
107  /** Set the feedback level for the recirculating delays.
108  @param feedback_level how much recirculation, from -128 to 127
109  */
110  void setFeebackLevel(int8_t feedback_level){
111  _feedback_level=feedback_level;
112  }
113 
114 
115 private:
116  int8_t _early_reflection1;
117  int8_t _early_reflection2;
118  int8_t _early_reflection3;
119 
120  int8_t _feedback_level;
121 
122  AudioDelay <128> aLoopDel0; // 128/16384 seconds * 340.29 m/s speed of sound = 3.5 metres
123  AudioDelay <128,int> aLoopDel1;
124  AudioDelay <256,int> aLoopDel2; // 7 metres
125 
126 };
127 
128 /**
129 @example 09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino
130 This example demonstrates the ReverbTank class.
131 */
132 
133 #endif // #ifndef REVERBTANK_H
void setEarlyReflections(int8_t early_reflection1, int8_t early_reflection2, int8_t early_reflection3)
Set the early reflection times in terms of delay cells.
Definition: ReverbTank.h:91
-
Audio delay line for comb filter, flange, chorus and short echo effects.
Definition: AudioDelay.h:27
-
A reverb which sounds like the inside of a tin can.
Definition: ReverbTank.h:32
-
int next(int input)
Process the next audio sample and return the reverbed signal.
Definition: ReverbTank.h:65
-
void setFeebackLevel(int8_t feedback_level)
Set the feedback level for the recirculating delays.
Definition: ReverbTank.h:110
-
void setLoopDelays(int8_t loop1_delay, uint8_t loop2_delay)
Set the loop delay times in terms of delay cells.
Definition: ReverbTank.h:102
-
ReverbTank(int8_t early_reflection1=37, int8_t early_reflection2=77, int8_t early_reflection3=127, int8_t loop1_delay=117, uint8_t loop2_delay=255, int8_t feedback_level=85)
Constructor.
Definition: ReverbTank.h:45
+
1 /*
+
2  * ReverbTank.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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 REVERBTANK_H
+
13 #define REVERBTANK_H
+
14 
+
15 #include "AudioDelay.h"
+
16 /**
+
17 A reverb which sounds like the inside of a tin can.
+
18 ReverbTank is small enough to fit on the Arduino Nano, which for some reason
+
19 wasn't able to fit a larger version which did fit on other 328 based boards. For
+
20 simplicity, ReverbTank has hardcoded maximum delay sizes but also has default
+
21 delay times which can be changed in the constructor or by setting during run
+
22 time to allow live tweaking.
+
23 This is a highly simplified design drawing on and probably misinterpreting
+
24 Miller Puckette's G08.reverb recirculating reverb example for Pure Data.
+
25 
+
26 The room size according to the maximum delay lengths corresponds to:
+
27 
+
28 early reflections and recirculating delay 1: 128/16384 seconds * 340.29 m/s speed of sound = 3.5 metres
+
29 recirculating delay 2: 7 metres
+
30 It looks bigger on paper than it sounds.
+
31 */
+
32 class
+
33  ReverbTank {
+
34 
+
35 public:
+
36  /** Constructor. This has default values for the early reflection times, recirculating delay lengths and feedback level,
+
37  which can be changed here in the constructor or set with other functions during run time.
+
38  @param early_reflection1 how long in delay cells till the first early reflection, from 0 to 127
+
39  @param early_reflection2 how long in delay cells till the second early reflection, from early_reflection1 to 127
+
40  @param early_reflection3 how long in delay cells till the third early reflection, from early_reflection2 to 127
+
41  @param loop1_delay how long in delay cells for the first recirculating delay, form 0 to 127
+
42  @param loop2_delay how long in delay cells for the first recirculating delay, form 0 to 255
+
43  @param feedback_level how much recirculation, from -128 to 127
+
44  */
+ +
46  int8_t early_reflection1 = 37,
+
47  int8_t early_reflection2 = 77,
+
48  int8_t early_reflection3 = 127,
+
49  int8_t loop1_delay=117,
+
50  uint8_t loop2_delay=255,
+
51  int8_t feedback_level = 85):
+ + +
54  {
+
55  aLoopDel1.set(loop1_delay);
+
56  aLoopDel2.set(loop2_delay);
+
57  }
+
58 
+
59 
+
60  /** Process the next audio sample and return the reverbed signal. This returns only the "wet" signal,
+
61  which can be combined with the dry input signal in the sketch.
+
62  @param input the audio signal to process
+
63  @return the processed signal
+
64  */
+
65  int next(int input){
+
66  static int recycle1, recycle2;
+
67 
+
68  // early reflections
+
69  int asig = aLoopDel0.next(input, _early_reflection1);
+
70  asig += aLoopDel0.read(_early_reflection2);
+
71  asig += aLoopDel0.read(_early_reflection3);
+
72  asig >>= 2;
+
73 
+
74  // recirculating delays
+
75  int8_t feedback_sig1 = (int8_t) min(max(((recycle1 * _feedback_level)>>7),-128),127); // feedback clipped
+
76  int8_t feedback_sig2 = (int8_t) min(max(((recycle2 * _feedback_level)>>7),-128),127); // feedback clipped
+
77  int sig3 = aLoopDel1.next(asig+feedback_sig1);
+
78  int sig4 = aLoopDel2.next(asig+feedback_sig2);
+
79  recycle1 = sig3 + sig4;
+
80  recycle2 = sig3 - sig4;
+
81 
+
82  return recycle1;
+
83  }
+
84 
+
85 
+
86  /** Set the early reflection times in terms of delay cells.
+
87  @param early_reflection1 how long in delay cells till the first early reflection, from 0 to 127
+
88  @param early_reflection2 how long in delay cells till the second early reflection, from early_reflection1 to 127
+
89  @param early_reflection3 how long in delay cells till the third early reflection, from early_reflection2 to 127
+
90  */
+
91  void setEarlyReflections(int8_t early_reflection1, int8_t early_reflection2, int8_t early_reflection3){
+
92  _early_reflection1=early_reflection1;
+
93  _early_reflection2=early_reflection2;
+
94  _early_reflection3=early_reflection3;
+
95  }
+
96 
+
97 
+
98  /** Set the loop delay times in terms of delay cells.
+
99  @param loop1_delay how long in delay cells for the first recirculating delay, form 0 to 127
+
100  @param loop2_delay how long in delay cells for the first recirculating delay, form 0 to 255
+
101  */
+
102  void setLoopDelays(int8_t loop1_delay, uint8_t loop2_delay){
+
103  aLoopDel1.set(loop1_delay);
+
104  aLoopDel2.set(loop2_delay);
+
105  }
+
106 
+
107  /** Set the feedback level for the recirculating delays.
+
108  @param feedback_level how much recirculation, from -128 to 127
+
109  */
+
110  void setFeebackLevel(int8_t feedback_level){
+
111  _feedback_level=feedback_level;
+
112  }
+
113 
+
114 
+
115 private:
+
116  int8_t _early_reflection1;
+
117  int8_t _early_reflection2;
+
118  int8_t _early_reflection3;
+
119 
+
120  int8_t _feedback_level;
+
121 
+
122  AudioDelay <128> aLoopDel0; // 128/16384 seconds * 340.29 m/s speed of sound = 3.5 metres
+
123  AudioDelay <128,int> aLoopDel1;
+
124  AudioDelay <256,int> aLoopDel2; // 7 metres
+
125 
+
126 };
+
127 
+
128 /**
+
129 @example 09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino
+
130 This example demonstrates the ReverbTank class.
+
131 */
+
132 
+
133 #endif // #ifndef REVERBTANK_H
diff --git a/extras/doc/html/_rolling_average_8h_source.html b/extras/doc/html/_rolling_average_8h_source.html index c3f228a5f..e29efccee 100644 --- a/extras/doc/html/_rolling_average_8h_source.html +++ b/extras/doc/html/_rolling_average_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: RollingAverage.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,226 @@
RollingAverage.h
-
1 #ifndef ROLLINGAVERAGE_H
2 #define ROLLINGAVERAGE_H
3 
4 /*
5  * RollingAverage.h
6  *
7  * Copyright 2013 Tim Barrass.
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 /*
15  Draws on Arduino Smoothing example,
16  Created 22 April 2007
17  By David A. Mellis <dam@mellis.org>
18  modified 9 Apr 2012
19  by Tom Igoe
20  http://www.arduino.cc/en/Tutorial/Smoothing
21 */
22 
23 #include "mozzi_utils.h" // for trailingZeros()
24 
25 
26 /** @ingroup sensortools
27  Calculates a running average over a
28  specified number of the most recent readings.
29  Like Smooth(), this is good for smoothing analog inputs in updateControl().
30  @tparam WINDOW_LENGTH the number of readings to include in the rolling average.
31  It must be a power of two (unless you're averaging floats). The higher the
32  number, the more the readings will be smoothed, but the slower the output
33  will respond to the input.
34 */
35 
36 template <class T, int WINDOW_LENGTH>
37 class
38  RollingAverage {
39 
40 public:
41 
42  /** Constructor.
43  @tparam T the type of numbers to average, eg. int, unsigned int, float etc. It will be relatively slow with
44  floating point numbers, as it will use a divide operation for the averaging.
45  Nevertheless, there might be a time when it's useful.
46  @tparam WINDOW_LENGTH the number of readings to keep track of. It must be a power of two (unless
47  you're averaging floats). The higher the number, the more the readings will be
48  smoothed, but the slower the output will respond to the input.
49  @note Watch out for overflows!
50  */
51  RollingAverage():index(0),total(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
52  {
53  // initialize all the readings to 0:
54  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
55  readings[thisReading] = 0;
56  }
57 
58 
59  /** Give the average of the last WINDOW_LENGTH.
60  @param input a control signal such as an analog input which needs smoothing.
61  @return the smoothed result.
62  @note unsigned int timing 5.7us
63  */
64  T next(T input)
65  {
66  return add(input)>>WINDOW_LENGTH_AS_RSHIFT;
67  }
68 
69 
70 protected:
71 
72  inline
73  T add(T input){
74  // out with the old
75  total -= readings[index];
76  // in with the new
77  total += input;
78  readings[index] = input;
79 
80  // advance and wrap index
81  ++index &= WINDOW_LENGTH -1;
82  return total;
83  }
84 
85 
86 private:
87  T readings[WINDOW_LENGTH]; // the readings from the analog input
88  unsigned int index; // the index of the current reading
89  long total; // the running total
90  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
91 
92 };
93 
94 // no need to show the specialisations
95 /** @cond */
96 
97 /** unsigned int partial specialisation of RollingAverage template.
98 This is needed because unsigned types need to remind (unsigned) for rshift.
99 */
100 template <int WINDOW_LENGTH>
101 class RollingAverage <unsigned int, WINDOW_LENGTH>
102 {
103 public:
104  /** Constructor.
105  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
106  The higher the number, the more the readings will be smoothed, but the slower the output will
107  respond to the input.
108  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
109  However, watch out for overflows if you are averaging a long number types!
110  */
111  RollingAverage():index(0),total(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
112  {
113  // initialize all the readings to 0:
114  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
115  readings[thisReading] = 0;
116  }
117 
118  /** Give the average of the last WINDOW_LENGTH.
119  @param a control signal such as an analog input which needs smoothing.
120  @return the smoothed result.
121  @note timing for int 6us
122  */
123  unsigned int next(unsigned int input)
124  {
125  // calculate the average:
126  // this unsigned cast is the only difference between the int and unsigned int specialisations
127  // it tells the shift not to sign extend in from the left
128  return (unsigned)add(input)>>WINDOW_LENGTH_AS_RSHIFT;
129  }
130 
131 protected:
132 
133 
134  inline
135  unsigned int add(unsigned int input){
136  // out with the old
137  total -= readings[index];
138  // in with the new
139  total += input;
140  readings[index] = input;
141 
142  // advance and wrap index
143  ++index &= WINDOW_LENGTH -1;
144  return total;
145  }
146 
147 
148 private:
149  unsigned int readings[WINDOW_LENGTH]; // the readings from the analog input
150  unsigned int index; // the index of the current reading
151  long total; // the running total
152  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
153 
154 };
155 
156 
157 
158 /** float partial specialisation of RollingAverage template*/
159 template <int WINDOW_LENGTH>
160 class RollingAverage <float, WINDOW_LENGTH>
161 {
162 public:
163  /** Constructor.
164  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
165  The higher the number, the more the readings will be smoothed, but the slower the output will
166  respond to the input.
167  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
168  However, watch out for overflows if you are averaging a long number types!
169  */
170  RollingAverage():index(0),total(0.0)
171  {
172  // initialize all the readings to 0:
173  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
174  readings[thisReading] = 0.0;
175  }
176 
177  /** Give the average of the last WINDOW_LENGTH.
178  @param a control signal such as an analog input which needs smoothing.
179  @return the smoothed result.
180  @note timing for float 37us
181  */
182  float next(float input)
183  {
184  // out with the old
185  total -= readings[index];
186  // in with the new
187  total += input;
188  readings[index] = input;
189 
190  // advance and wrap index
191  ++index &= WINDOW_LENGTH -1;
192 
193  // calculate the average:
194  return total/WINDOW_LENGTH;
195  }
196 
197 private:
198  float readings[WINDOW_LENGTH]; // the readings from the analog input
199  unsigned int index; // the index of the current reading
200  float total; // the running total
201 
202 };
203 
204 
205 // no need to show the specialisations
206 /** @endcond
207 */
208 
209 /**
210 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
211 This example demonstrates the RollingAverage class.
212 */
213 
214 #endif // #ifndef ROLLINGAVERAGE_H
+
1 /*
+
2  * RollingAverage.h
+
3  *
+
4  Draws on Arduino Smoothing example,
+
5  Created 22 April 2007
+
6  By David A. Mellis <dam@mellis.org>
+
7  modified 9 Apr 2012
+
8  by Tom Igoe
+
9  http://www.arduino.cc/en/Tutorial/Smoothing
+
10 
+
11  * This file is part of Mozzi.
+
12  *
+
13  * Copyright 2013-2024 Tim Barrass and the Mozzi Team
+
14  *
+
15  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
16  *
+
17  */
+
18 
+
19 #ifndef ROLLINGAVERAGE_H
+
20 #define ROLLINGAVERAGE_H
+
21 
+
22 #include "mozzi_utils.h" // for trailingZeros()
+
23 
+
24 
+
25 /** @ingroup sensortools
+
26  Calculates a running average over a
+
27  specified number of the most recent readings.
+
28  Like Smooth(), this is good for smoothing analog inputs in updateControl().
+
29  @tparam WINDOW_LENGTH the number of readings to include in the rolling average.
+
30  It must be a power of two (unless you're averaging floats). The higher the
+
31  number, the more the readings will be smoothed, but the slower the output
+
32  will respond to the input.
+
33 */
+
34 
+
35 template <class T, int WINDOW_LENGTH>
+
36 class
+ +
38 
+
39 public:
+
40 
+
41  /** Constructor.
+
42  @tparam T the type of numbers to average, eg. int, unsigned int, float etc. It will be relatively slow with
+
43  floating point numbers, as it will use a divide operation for the averaging.
+
44  Nevertheless, there might be a time when it's useful.
+
45  @tparam WINDOW_LENGTH the number of readings to keep track of. It must be a power of two (unless
+
46  you're averaging floats). The higher the number, the more the readings will be
+
47  smoothed, but the slower the output will respond to the input.
+
48  @note Watch out for overflows!
+
49  */
+ +
51  {
+
52  // initialize all the readings to 0:
+
53  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
+
54  readings[thisReading] = 0;
+
55  }
+
56 
+
57 
+
58  /** Give the average of the last WINDOW_LENGTH.
+
59  @param input a control signal such as an analog input which needs smoothing.
+
60  @return the smoothed result.
+
61  @note unsigned int timing 5.7us
+
62  */
+
63  T next(T input)
+
64  {
+
65  return add(input)>>WINDOW_LENGTH_AS_RSHIFT;
+
66  }
+
67 
+
68 
+
69 protected:
+
70 
+
71  inline
+
72  T add(T input){
+
73  // out with the old
+
74  total -= readings[index];
+
75  // in with the new
+
76  total += input;
+
77  readings[index] = input;
+
78 
+
79  // advance and wrap index
+
80  ++index &= WINDOW_LENGTH -1;
+
81  return total;
+
82  }
+
83 
+
84 
+
85 private:
+
86  T readings[WINDOW_LENGTH]; // the readings from the analog input
+
87  unsigned int index; // the index of the current reading
+
88  long total; // the running total
+
89  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
+
90 
+
91 };
+
92 
+
93 // no need to show the specialisations
+
94 /** @cond */
+
95 
+
96 /** unsigned int partial specialisation of RollingAverage template.
+
97 This is needed because unsigned types need to remind (unsigned) for rshift.
+
98 */
+
99 template <int WINDOW_LENGTH>
+
100 class RollingAverage <unsigned int, WINDOW_LENGTH>
+
101 {
+
102 public:
+
103  /** Constructor.
+
104  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
+
105  The higher the number, the more the readings will be smoothed, but the slower the output will
+
106  respond to the input.
+
107  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
+
108  However, watch out for overflows if you are averaging a long number types!
+
109  */
+
110  RollingAverage():index(0),total(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
+
111  {
+
112  // initialize all the readings to 0:
+
113  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
+
114  readings[thisReading] = 0;
+
115  }
+
116 
+
117  /** Give the average of the last WINDOW_LENGTH.
+
118  @param a control signal such as an analog input which needs smoothing.
+
119  @return the smoothed result.
+
120  @note timing for int 6us
+
121  */
+
122  unsigned int next(unsigned int input)
+
123  {
+
124  // calculate the average:
+
125  // this unsigned cast is the only difference between the int and unsigned int specialisations
+
126  // it tells the shift not to sign extend in from the left
+
127  return (unsigned)add(input)>>WINDOW_LENGTH_AS_RSHIFT;
+
128  }
+
129 
+
130 protected:
+
131 
+
132 
+
133  inline
+
134  unsigned int add(unsigned int input){
+
135  // out with the old
+
136  total -= readings[index];
+
137  // in with the new
+
138  total += input;
+
139  readings[index] = input;
+
140 
+
141  // advance and wrap index
+
142  ++index &= WINDOW_LENGTH -1;
+
143  return total;
+
144  }
+
145 
+
146 
+
147 private:
+
148  unsigned int readings[WINDOW_LENGTH]; // the readings from the analog input
+
149  unsigned int index; // the index of the current reading
+
150  long total; // the running total
+
151  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
+
152 
+
153 };
+
154 
+
155 
+
156 
+
157 /** float partial specialisation of RollingAverage template*/
+
158 template <int WINDOW_LENGTH>
+
159 class RollingAverage <float, WINDOW_LENGTH>
+
160 {
+
161 public:
+
162  /** Constructor.
+
163  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
+
164  The higher the number, the more the readings will be smoothed, but the slower the output will
+
165  respond to the input.
+
166  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
+
167  However, watch out for overflows if you are averaging a long number types!
+
168  */
+
169  RollingAverage():index(0),total(0.0)
+
170  {
+
171  // initialize all the readings to 0:
+
172  for (int thisReading = 0; thisReading < WINDOW_LENGTH; thisReading++)
+
173  readings[thisReading] = 0.0;
+
174  }
+
175 
+
176  /** Give the average of the last WINDOW_LENGTH.
+
177  @param a control signal such as an analog input which needs smoothing.
+
178  @return the smoothed result.
+
179  @note timing for float 37us
+
180  */
+
181  float next(float input)
+
182  {
+
183  // out with the old
+
184  total -= readings[index];
+
185  // in with the new
+
186  total += input;
+
187  readings[index] = input;
+
188 
+
189  // advance and wrap index
+
190  ++index &= WINDOW_LENGTH -1;
+
191 
+
192  // calculate the average:
+
193  return total/WINDOW_LENGTH;
+
194  }
+
195 
+
196 private:
+
197  float readings[WINDOW_LENGTH]; // the readings from the analog input
+
198  unsigned int index; // the index of the current reading
+
199  float total; // the running total
+
200 
+
201 };
+
202 
+
203 
+
204 // no need to show the specialisations
+
205 /** @endcond
+
206 */
+
207 
+
208 /**
+
209 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
+
210 This example demonstrates the RollingAverage class.
+
211 */
+
212 
+
213 #endif // #ifndef ROLLINGAVERAGE_H
+
diff --git a/extras/doc/html/_rolling_stat_8h_source.html b/extras/doc/html/_rolling_stat_8h_source.html index 5b27dde9f..80d5fccce 100644 --- a/extras/doc/html/_rolling_stat_8h_source.html +++ b/extras/doc/html/_rolling_stat_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: RollingStat.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,22 +99,161 @@
RollingStat.h
-
1 #ifndef ROLLINGSTAT_H
2 #define ROLLINGSTAT_H
3 
4 /*
5  * RollingStat.h
6  *
7  * WARNING: this code is incomplete, it doesn't work yet
8  *
9  * Copyright 2013 Tim Barrass.
10  *
11  * This file is part of Mozzi.
12  *
13  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
14  *
15  */
16 
17 #include "RollingAverage.h"
18 #include "mozzi_fixmath.h"
19 
20 // adapted from RunningStat, http://www.johndcook.com/standard_deviation.html
21 /** @ingroup sensortools
22 WARNING: this class is work in progress, don't use it yet.
23 Calculates an approximation of the variance and standard deviation for a window of recent inputs.
24 @tparam T the type of numbers to use. Choose unsigned int, int , uint8_t, int8_t, or float
25 @tparam WINDOW_LENGTH how many recent input values to include in the calculations.
26 */
27 template <class T, int WINDOW_LENGTH>
29 {
30 public:
31 
32  /** Constructor */
33  RollingStat() : _previous_mean(0), _mean(0), _variance(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
34  {}
35 
36 
37  /** Update the mean and variance given a new input value.
38  @param x the next input value
39  @note timing for unsigned int 10us, int 22us
40  */
41  void update(T x) {
42  _mean = rollingMean.next(x);
43  _variance = (((long)x - _previous_mean)*((long)x - _mean))>>WINDOW_LENGTH_AS_RSHIFT; // should really be div by (WINDOW_LENGTH-1), but exact values are not important for this application
44  _previous_mean = _mean;
45  }
46 
47 
48  /** Update the mean and variance given a new input value.
49  @param x the next input value
50  */
51  void update(int8_t x) {
52  _mean = rollingMean.next(x);
53  _variance = (((int)x - _previous_mean)*((int)x - _mean))>>WINDOW_LENGTH_AS_RSHIFT; // should really be div by (WINDOW_LENGTH-1), but exact values are not important for this application
54  _previous_mean = _mean;
55  }
56 
57 
58  /** Return the mean of the last WINDOW_LENGTH number of inputs.
59  @return mean
60  */
61  T getMean() const {
62  return _mean;
63  }
64 
65 
66  /** Return the approximate variance of the last WINDOW_LENGTH number of inputs.
67  @return variance
68  @note This should really be calculated using WINDOW_LENGTH-1, but sacrificing accuracy for speed
69  we use the power of two value of WINDOW_LENGTH.
70  */
71  T getVariance() const {
72  return _variance;
73  }
74 
75  /** Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
76  @return standard deviation.
77  */
79  return isqrt16(_variance);
80  }
81 
82 
83 
84 private:
85  T _previous_mean, _mean, _variance;
86  RollingAverage <T, WINDOW_LENGTH> rollingMean;
87  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
88 };
89 
90 // no need to show the specialisations
91 /** @cond */
92 
93 /** float specialisation of RollingStat template */
94 template <int WINDOW_LENGTH>
95 class RollingStat <float, WINDOW_LENGTH>
96 {
97 public:
98 
99  /** Constructor */
100  RollingStat() : _previous_mean(0), _mean(0), _variance(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
101  {}
102 
103 
104  /** Update the mean and variance given a new input value.
105  @param x the next input value
106  @note timing for float: 60 to 90us
107  */
108  void update(float x) {
109  _mean = rollingMean.next(x);
110  _variance = ((x - _previous_mean)*(x - _mean))/(WINDOW_LENGTH-1);
111  _previous_mean = _mean;
112  }
113 
114 
115  /** Return the mean of the last WINDOW_LENGTH number of inputs.
116  @return mean
117  */
118  float getMean() const {
119  return _mean;
120  }
121 
122 
123  /** Return the approximate variance of the last WINDOW_LENGTH number of inputs.
124  @return variance
125  */
126  float getVariance() const {
127  return _variance;
128  }
129 
130  /** Calculate and return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
131  @return standard deviation.
132  @note this is probably too slow to use!
133  */
134  float getStandardDeviation() const {
135  return sqrt(_variance);
136  }
137 
138 
139 
140 private:
141  float _previous_mean, _mean, _variance;
142  RollingAverage <float, WINDOW_LENGTH> rollingMean;
143  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
144 };
145 
146 // no need to show the specialisations
147 /** @endcond */
148 
149 #endif // #ifndef ROLLINGSTAT_H
WARNING: this class is work in progress, don&#39;t use it yet.
Definition: RollingStat.h:28
-
T getMean() const
Return the mean of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:61
-
RollingStat()
Constructor.
Definition: RollingStat.h:33
-
T getStandardDeviation() const
Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:78
-
T getVariance() const
Return the approximate variance of the last WINDOW_LENGTH number of inputs.
Definition: RollingStat.h:71
-
void update(int8_t x)
Update the mean and variance given a new input value.
Definition: RollingStat.h:51
-
void update(T x)
Update the mean and variance given a new input value.
Definition: RollingStat.h:41
+
1 /*
+
2  * RollingStat.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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  * WARNING: this code is incomplete, it doesn't work yet
+
11  */
+
12 
+
13 #ifndef ROLLINGSTAT_H
+
14 #define ROLLINGSTAT_H
+
15 
+
16 #include "RollingAverage.h"
+
17 #include "mozzi_fixmath.h"
+
18 
+
19 // adapted from RunningStat, http://www.johndcook.com/standard_deviation.html
+
20 /** @ingroup sensortools
+
21 WARNING: this class is work in progress, don't use it yet.
+
22 Calculates an approximation of the variance and standard deviation for a window of recent inputs.
+
23 @tparam T the type of numbers to use. Choose unsigned int, int , uint8_t, int8_t, or float
+
24 @tparam WINDOW_LENGTH how many recent input values to include in the calculations.
+
25 */
+
26 template <class T, int WINDOW_LENGTH>
+ +
28 {
+
29 public:
+
30 
+
31  /** Constructor */
+
32  RollingStat() : _previous_mean(0), _mean(0), _variance(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
+
33  {}
+
34 
+
35 
+
36  /** Update the mean and variance given a new input value.
+
37  @param x the next input value
+
38  @note timing for unsigned int 10us, int 22us
+
39  */
+
40  void update(T x) {
+
41  _mean = rollingMean.next(x);
+
42  _variance = (((long)x - _previous_mean)*((long)x - _mean))>>WINDOW_LENGTH_AS_RSHIFT; // should really be div by (WINDOW_LENGTH-1), but exact values are not important for this application
+
43  _previous_mean = _mean;
+
44  }
+
45 
+
46 
+
47  /** Update the mean and variance given a new input value.
+
48  @param x the next input value
+
49  */
+
50  void update(int8_t x) {
+
51  _mean = rollingMean.next(x);
+
52  _variance = (((int)x - _previous_mean)*((int)x - _mean))>>WINDOW_LENGTH_AS_RSHIFT; // should really be div by (WINDOW_LENGTH-1), but exact values are not important for this application
+
53  _previous_mean = _mean;
+
54  }
+
55 
+
56 
+
57  /** Return the mean of the last WINDOW_LENGTH number of inputs.
+
58  @return mean
+
59  */
+
60  T getMean() const {
+
61  return _mean;
+
62  }
+
63 
+
64 
+
65  /** Return the approximate variance of the last WINDOW_LENGTH number of inputs.
+
66  @return variance
+
67  @note This should really be calculated using WINDOW_LENGTH-1, but sacrificing accuracy for speed
+
68  we use the power of two value of WINDOW_LENGTH.
+
69  */
+
70  T getVariance() const {
+
71  return _variance;
+
72  }
+
73 
+
74  /** Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
+
75  @return standard deviation.
+
76  */
+ +
78  return isqrt16(_variance);
+
79  }
+
80 
+
81 
+
82 
+
83 private:
+
84  T _previous_mean, _mean, _variance;
+
85  RollingAverage <T, WINDOW_LENGTH> rollingMean;
+
86  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
+
87 };
+
88 
+
89 // no need to show the specialisations
+
90 /** @cond */
+
91 
+
92 /** float specialisation of RollingStat template */
+
93 template <int WINDOW_LENGTH>
+
94 class RollingStat <float, WINDOW_LENGTH>
+
95 {
+
96 public:
+
97 
+
98  /** Constructor */
+
99  RollingStat() : _previous_mean(0), _mean(0), _variance(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
+
100  {}
+
101 
+
102 
+
103  /** Update the mean and variance given a new input value.
+
104  @param x the next input value
+
105  @note timing for float: 60 to 90us
+
106  */
+
107  void update(float x) {
+
108  _mean = rollingMean.next(x);
+
109  _variance = ((x - _previous_mean)*(x - _mean))/(WINDOW_LENGTH-1);
+
110  _previous_mean = _mean;
+
111  }
+
112 
+
113 
+
114  /** Return the mean of the last WINDOW_LENGTH number of inputs.
+
115  @return mean
+
116  */
+
117  float getMean() const {
+
118  return _mean;
+
119  }
+
120 
+
121 
+
122  /** Return the approximate variance of the last WINDOW_LENGTH number of inputs.
+
123  @return variance
+
124  */
+
125  float getVariance() const {
+
126  return _variance;
+
127  }
+
128 
+
129  /** Calculate and return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.
+
130  @return standard deviation.
+
131  @note this is probably too slow to use!
+
132  */
+
133  float getStandardDeviation() const {
+
134  return sqrt(_variance);
+
135  }
+
136 
+
137 
+
138 
+
139 private:
+
140  float _previous_mean, _mean, _variance;
+
141  RollingAverage <float, WINDOW_LENGTH> rollingMean;
+
142  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
+
143 };
+
144 
+
145 // no need to show the specialisations
+
146 /** @endcond */
+
147 
+
148 #endif // #ifndef ROLLINGSTAT_H
diff --git a/extras/doc/html/_sample_8h_source.html b/extras/doc/html/_sample_8h_source.html index 37be8856f..60fdbdde8 100644 --- a/extras/doc/html/_sample_8h_source.html +++ b/extras/doc/html/_sample_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Sample.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,37 +99,340 @@
Sample.h
-
1 /*
2  * Sample.h
3  *
4  * Copyright 2012 Tim Barrass
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef SAMPLE_H_
13 #define SAMPLE_H_
14 
15 #include "MozziHeadersOnly.h"
16 #include "mozzi_fixmath.h"
17 #include "mozzi_pgmspace.h"
18 
19 // fractional bits for sample index precision
20 #define SAMPLE_F_BITS 16
21 #define SAMPLE_F_BITS_AS_MULTIPLIER 65536
22 
23 // phmod_proportion is an 1n15 fixed-point number only using
24 // the fractional part and the sign bit
25 #define SAMPLE_PHMOD_BITS 16
26 
27 enum interpolation {INTERP_NONE, INTERP_LINEAR};
28 
29 /** Sample is like Oscil, it plays a wavetable. However, Sample can be
30 set to play once through only, with variable start and end points,
31 or can loop, also with variable start and end points.
32 It defaults to playing once through the whole sound table, from start to finish.
33 @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Sample will be
34 using. The sound table can be arbitrary length for Sample.
35 It's important that NUM_TABLE_CELLS is either a literal number (eg. "8192") or a
36 defined macro, rather than a const or int, for the Sample to run fast enough.
37 @tparam UPDATE_RATE This will be MOZZI_AUDIO_RATE if the Sample is updated in
38 updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is
39 called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind
40 of cyclic updating in updateControl(), for example, to spread out the processor load.
41 @section int8_t2mozzi
42 Converting soundfiles for Mozzi.
43 There is a python script called int8_t2mozzi.py in the Mozzi/python folder.
44 The script converts raw sound data saved from a program like Audacity.
45 Instructions are in the int8_t2mozzi.py file.
46 */
47 template <unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, uint8_t INTERP=INTERP_NONE>
48 class Sample
49 {
50 
51 public:
52 
53  /** Constructor.
54  @param TABLE_NAME the name of the array the Sample will be using. This
55  can be found in the table ".h" file if you are using a table made for
56  Mozzi by the int8_t2mozzi.py python script in Mozzi's python
57  folder. Sound tables can be of arbitrary lengths for Sample().
58  */
59  Sample(const int8_t * TABLE_NAME):table(TABLE_NAME),endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS) // so isPlaying() will work
60  {
62  //rangeWholeSample();
63  }
64 
65 
66 
67  /** Constructor.
68  Declare a Sample with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play.
69  The table can be set or changed on the fly with setTable().
70  */
71  Sample():endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS)
72  {
74  //rangeWholeSample();
75  }
76 
77 
78  /** Change the sound table which will be played by the Sample.
79  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
80  */
81  inline
82  void setTable(const int8_t * TABLE_NAME)
83  {
84  table = TABLE_NAME;
85  }
86 
87 
88  /** Sets the starting position in samples.
89  @param startpos offset position in samples.
90  */
91  inline
92  void setStart(unsigned int startpos)
93  {
94  startpos_fractional = (unsigned long) startpos << SAMPLE_F_BITS;
95  }
96 
97 
98  /** Resets the phase (the playhead) to the start position, which will be 0 unless set to another value with setStart();
99  */
100  inline
101  void start()
102  {
103  phase_fractional = startpos_fractional;
104  }
105 
106 
107  /** Sets a new start position plays the sample from that position.
108  @param startpos position in samples from the beginning of the sound.
109  */
110  inline
111  void start(unsigned int startpos)
112  {
113  setStart(startpos);
114  start();
115  }
116 
117 
118  /** Sets the end position in samples from the beginning of the sound.
119  @param end position in samples.
120  */
121  inline
122  void setEnd(unsigned int end)
123  {
124  endpos_fractional = (unsigned long) end << SAMPLE_F_BITS;
125  }
126 
127 
128  /** Sets the start and end points to include the range of the whole sound table.
129  */
130  inline
132  {
133  startpos_fractional = 0;
134  endpos_fractional = (unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS;
135  }
136 
137 
138  /** Turns looping on.
139  */
140  inline
142  {
143  looping=true;
144  }
145 
146 
147  /** Turns looping off.
148  */
149  inline
151  {
152  looping=false;
153  }
154 
155 
156 
157  /**
158  Returns the sample at the current phase position, or 0 if looping is off
159  and the phase overshoots the end of the sample. Updates the phase
160  according to the current frequency.
161  @return the next sample value from the table, or 0 if it's finished playing.
162  @todo in next(), incrementPhase() happens in a different position than for Oscil - check if it can be standardised
163  */
164  inline
165  int8_t next() { // 4us
166 
167  if (phase_fractional>endpos_fractional){
168  if (looping) {
169  phase_fractional = startpos_fractional + (phase_fractional - endpos_fractional);
170  }else{
171  return 0;
172  }
173  }
174  int8_t out;
175  if(INTERP==INTERP_LINEAR){
176  // WARNNG this is hard coded for when SAMPLE_F_BITS is 16
177  unsigned int index = phase_fractional >> SAMPLE_F_BITS;
178  out = FLASH_OR_RAM_READ<const int8_t>(table + index);
179  int8_t difference = FLASH_OR_RAM_READ<const int8_t>((table + 1) + index) - out;
180  int8_t diff_fraction = (int8_t)(((((unsigned int) phase_fractional)>>8)*difference)>>8); // (unsigned int) phase_fractional keeps low word, then>> for only 8 bit precision
181  out += diff_fraction;
182  }else{
183  out = FLASH_OR_RAM_READ<const int8_t>(table + (phase_fractional >> SAMPLE_F_BITS));
184  }
185  incrementPhase();
186  return out;
187  }
188 
189 
190  /** Checks if the sample is playing by seeing if the phase is within the limits of its end position.
191  @return true if the sample is playing
192  */
193  inline
195  return phase_fractional<endpos_fractional;
196  }
197 
198 
199  // Not readjusted for arbitrary table length yet
200  //
201  // Returns the next sample given a phase modulation value.
202  // @param phmod_proportion phase modulation value given as a proportion of the wave. The
203  // phmod_proportion parameter is a Q15n16 fixed-point number where to fractional
204  // n16 part represents -1 to 1, modulating the phase by one whole table length in
205  // each direction.
206  // @return a sample from the table.
207  //
208  // inline
209  // int8_t phMod(long phmod_proportion)
210  // {
211  // incrementPhase();
212  // return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>SAMPLE_SAMPLE_F_BITS) & (NUM_TABLE_CELLS - 1)));
213  // }
214 
215 
216 
217  /** Set the oscillator frequency with an unsigned int.
218  This is faster than using a float, so it's useful when processor time is tight,
219  but it can be tricky with low and high frequencies, depending on the size of the
220  wavetable being used. If you're not getting the results you expect, try
221  explicitly using a float, or try setFreq_Q24n8.
222  @param frequency to play the wave table.
223  */
224  inline
225  void setFreq (int frequency) {
226  phase_increment_fractional = ((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
227  }
228 
229 
230  /** Set the sample frequency with a float. Using a float is the most reliable
231  way to set frequencies, -Might- be slower than using an int but you need either
232  this or setFreq_Q24n8 for fractional frequencies.
233  @param frequency to play the wave table.
234  */
235  inline
236  void setFreq(float frequency)
237  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
238  phase_increment_fractional = (unsigned long)((((float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * SAMPLE_F_BITS_AS_MULTIPLIER);
239  }
240 
241 
242  /** Set the frequency using Q24n8 fixed-point number format.
243  This might be faster than the float version for setting low frequencies
244  such as 1.5 Hz, or other values which may not work well with your table
245  size. Note: use with caution because it's prone to overflow with higher
246  frequencies and larger table sizes. An Q24n8 representation of 1.5 is 384
247  (ie. 1.5 * 256).
248  @param frequency in Q24n8 fixed-point number format.
249  */
250  inline
251  void setFreq_Q24n8(Q24n8 frequency)
252  {
253  //phase_increment_fractional = (frequency* (NUM_TABLE_CELLS>>3)/(UPDATE_RATE>>6)) << (F_BITS-(8-3+6));
254  phase_increment_fractional = (((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
255  << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
256  }
257 
258 
259  /** Returns the sample at the given table index.
260  @param index between 0 and the table size.
261  @return the sample at the given table index.
262  */
263  inline
264  int8_t atIndex(unsigned int index)
265  {
266  return FLASH_OR_RAM_READ<const int8_t>(table + index);
267  }
268 
269 
270  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
271  Instead of recalculating the phase increment for each
272  frequency in between, you can just calculate the phase increment for each end
273  frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and
274  use setPhaseInc() to set the phase increment at each step. (Note: I should
275  really profile this with the oscilloscope to see if it's worth the extra
276  confusion!)
277  @param frequency for which you want to calculate a phase increment value.
278  @return the phase increment value which will produce a given frequency.
279  */
280  inline
281  unsigned long phaseIncFromFreq(unsigned int frequency)
282  {
283  return (((unsigned long)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << SAMPLE_F_BITS;
284  }
285 
286 
287  /** Set a specific phase increment. See phaseIncFromFreq().
288  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
289  */
290  inline
291  void setPhaseInc(unsigned long phaseinc_fractional)
292  {
293  phase_increment_fractional = phaseinc_fractional;
294  }
295 
296 
297 private:
298 
299 
300  /** Used for shift arithmetic in setFreq() and its variations.
301  */
302 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
303 
304 
305  /** Increments the phase of the oscillator without returning a sample.
306  */
307  inline
308  void incrementPhase()
309  {
310  phase_fractional += phase_increment_fractional;
311  }
312 
313 
314  volatile unsigned long phase_fractional;
315  volatile unsigned long phase_increment_fractional;
316  const int8_t * table;
317  bool looping;
318  unsigned long startpos_fractional, endpos_fractional;
319 };
320 
321 
322 /**
323 @example 08.Samples/Sample/Sample.ino
324 This example demonstrates the Sample class.
325 */
326 
327 #endif /* SAMPLE_H_ */
void setFreq_Q24n8(Q24n8 frequency)
Set the frequency using Q24n8 fixed-point number format.
Definition: Sample.h:251
-
void setLoopingOn()
Turns looping on.
Definition: Sample.h:141
-
void setFreq(int frequency)
Set the oscillator frequency with an unsigned int.
Definition: Sample.h:225
-
void setEnd(unsigned int end)
Sets the end position in samples from the beginning of the sound.
Definition: Sample.h:122
-
Sample(const int8_t *TABLE_NAME)
Constructor.
Definition: Sample.h:59
-
void rangeWholeSample()
Sets the start and end points to include the range of the whole sound table.
Definition: Sample.h:131
-
unsigned long phaseIncFromFreq(unsigned int frequency)
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies...
Definition: Sample.h:281
-
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
Definition: Sample.h:264
-
void setPhaseInc(unsigned long phaseinc_fractional)
Set a specific phase increment.
Definition: Sample.h:291
-
void setStart(unsigned int startpos)
Sets the starting position in samples.
Definition: Sample.h:92
-
void start(unsigned int startpos)
Sets a new start position plays the sample from that position.
Definition: Sample.h:111
-
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Sample.
Definition: Sample.h:82
-
#define SAMPLE_F_BITS
Definition: Sample.h:20
-
int8_t next()
Returns the sample at the current phase position, or 0 if looping is off and the phase overshoots th...
Definition: Sample.h:165
-
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:43
-
boolean isPlaying()
Checks if the sample is playing by seeing if the phase is within the limits of its end position...
Definition: Sample.h:194
-
void start()
Resets the phase (the playhead) to the start position, which will be 0 unless set to another value wi...
Definition: Sample.h:101
-
void setFreq(float frequency)
Set the sample frequency with a float.
Definition: Sample.h:236
-
Sample is like Oscil, it plays a wavetable.
Definition: Sample.h:48
-
#define SAMPLE_F_BITS_AS_MULTIPLIER
Definition: Sample.h:21
-
Sample()
Constructor.
Definition: Sample.h:71
-
void setLoopingOff()
Turns looping off.
Definition: Sample.h:150
+
1 /*
+
2  * Sample.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 SAMPLE_H_
+
13 #define SAMPLE_H_
+
14 
+
15 #include "MozziHeadersOnly.h"
+
16 #include "mozzi_fixmath.h"
+
17 #include "mozzi_pgmspace.h"
+
18 
+
19 // fractional bits for sample index precision
+
20 #define SAMPLE_F_BITS 16
+
21 #define SAMPLE_F_BITS_AS_MULTIPLIER 65536
+
22 
+
23 // phmod_proportion is an 1n15 fixed-point number only using
+
24 // the fractional part and the sign bit
+
25 #define SAMPLE_PHMOD_BITS 16
+
26 
+
27 enum interpolation {INTERP_NONE, INTERP_LINEAR};
+
28 
+
29 /** Sample is like Oscil, it plays a wavetable. However, Sample can be
+
30 set to play once through only, with variable start and end points,
+
31 or can loop, also with variable start and end points.
+
32 It defaults to playing once through the whole sound table, from start to finish.
+
33 @tparam NUM_TABLE_CELLS This is defined in the table ".h" file the Sample will be
+
34 using. The sound table can be arbitrary length for Sample.
+
35 It's important that NUM_TABLE_CELLS is either a literal number (eg. "8192") or a
+
36 defined macro, rather than a const or int, for the Sample to run fast enough.
+
37 @tparam UPDATE_RATE This will be MOZZI_AUDIO_RATE if the Sample is updated in
+
38 updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is
+
39 called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind
+
40 of cyclic updating in updateControl(), for example, to spread out the processor load.
+
41 @section int8_t2mozzi
+
42 Converting soundfiles for Mozzi.
+
43 There is a python script called int8_t2mozzi.py in the Mozzi/python folder.
+
44 The script converts raw sound data saved from a program like Audacity.
+
45 Instructions are in the int8_t2mozzi.py file.
+
46 */
+
47 template <unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, uint8_t INTERP=INTERP_NONE>
+
48 class Sample
+
49 {
+
50 
+
51 public:
+
52 
+
53  /** Constructor.
+
54  @param TABLE_NAME the name of the array the Sample will be using. This
+
55  can be found in the table ".h" file if you are using a table made for
+
56  Mozzi by the int8_t2mozzi.py python script in Mozzi's python
+
57  folder. Sound tables can be of arbitrary lengths for Sample().
+
58  */
+
59  Sample(const int8_t * TABLE_NAME):table(TABLE_NAME),endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS) // so isPlaying() will work
+
60  {
+ +
62  //rangeWholeSample();
+
63  }
+
64 
+
65 
+
66 
+
67  /** Constructor.
+
68  Declare a Sample with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play.
+
69  The table can be set or changed on the fly with setTable().
+
70  */
+
71  Sample():endpos_fractional((unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS)
+
72  {
+ +
74  //rangeWholeSample();
+
75  }
+
76 
+
77 
+
78  /** Change the sound table which will be played by the Sample.
+
79  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
+
80  */
+
81  inline
+
82  void setTable(const int8_t * TABLE_NAME)
+
83  {
+
84  table = TABLE_NAME;
+
85  }
+
86 
+
87 
+
88  /** Sets the starting position in samples.
+
89  @param startpos offset position in samples.
+
90  */
+
91  inline
+
92  void setStart(unsigned int startpos)
+
93  {
+
94  startpos_fractional = (unsigned long) startpos << SAMPLE_F_BITS;
+
95  }
+
96 
+
97 
+
98  /** Resets the phase (the playhead) to the start position, which will be 0 unless set to another value with setStart();
+
99  */
+
100  inline
+
101  void start()
+
102  {
+
103  phase_fractional = startpos_fractional;
+
104  }
+
105 
+
106 
+
107  /** Sets a new start position plays the sample from that position.
+
108  @param startpos position in samples from the beginning of the sound.
+
109  */
+
110  inline
+
111  void start(unsigned int startpos)
+
112  {
+
113  setStart(startpos);
+
114  start();
+
115  }
+
116 
+
117 
+
118  /** Sets the end position in samples from the beginning of the sound.
+
119  @param end position in samples.
+
120  */
+
121  inline
+
122  void setEnd(unsigned int end)
+
123  {
+
124  endpos_fractional = (unsigned long) end << SAMPLE_F_BITS;
+
125  }
+
126 
+
127 
+
128  /** Sets the start and end points to include the range of the whole sound table.
+
129  */
+
130  inline
+ +
132  {
+
133  startpos_fractional = 0;
+
134  endpos_fractional = (unsigned long) NUM_TABLE_CELLS << SAMPLE_F_BITS;
+
135  }
+
136 
+
137 
+
138  /** Turns looping on.
+
139  */
+
140  inline
+ +
142  {
+
143  looping=true;
+
144  }
+
145 
+
146 
+
147  /** Turns looping off.
+
148  */
+
149  inline
+ +
151  {
+
152  looping=false;
+
153  }
+
154 
+
155 
+
156 
+
157  /**
+
158  Returns the sample at the current phase position, or 0 if looping is off
+
159  and the phase overshoots the end of the sample. Updates the phase
+
160  according to the current frequency.
+
161  @return the next sample value from the table, or 0 if it's finished playing.
+
162  @todo in next(), incrementPhase() happens in a different position than for Oscil - check if it can be standardised
+
163  */
+
164  inline
+
165  int8_t next() { // 4us
+
166 
+
167  if (phase_fractional>endpos_fractional){
+
168  if (looping) {
+
169  phase_fractional = startpos_fractional + (phase_fractional - endpos_fractional);
+
170  }else{
+
171  return 0;
+
172  }
+
173  }
+
174  int8_t out;
+
175  if(INTERP==INTERP_LINEAR){
+
176  // WARNNG this is hard coded for when SAMPLE_F_BITS is 16
+
177  unsigned int index = phase_fractional >> SAMPLE_F_BITS;
+
178  out = FLASH_OR_RAM_READ<const int8_t>(table + index);
+
179  int8_t difference = FLASH_OR_RAM_READ<const int8_t>((table + 1) + index) - out;
+
180  int8_t diff_fraction = (int8_t)(((((unsigned int) phase_fractional)>>8)*difference)>>8); // (unsigned int) phase_fractional keeps low word, then>> for only 8 bit precision
+
181  out += diff_fraction;
+
182  }else{
+
183  out = FLASH_OR_RAM_READ<const int8_t>(table + (phase_fractional >> SAMPLE_F_BITS));
+
184  }
+
185  incrementPhase();
+
186  return out;
+
187  }
+
188 
+
189 
+
190  /** Checks if the sample is playing by seeing if the phase is within the limits of its end position.
+
191  @return true if the sample is playing
+
192  */
+
193  inline
+ +
195  return phase_fractional<endpos_fractional;
+
196  }
+
197 
+
198 
+
199  // Not readjusted for arbitrary table length yet
+
200  //
+
201  // Returns the next sample given a phase modulation value.
+
202  // @param phmod_proportion phase modulation value given as a proportion of the wave. The
+
203  // phmod_proportion parameter is a Q15n16 fixed-point number where to fractional
+
204  // n16 part represents -1 to 1, modulating the phase by one whole table length in
+
205  // each direction.
+
206  // @return a sample from the table.
+
207  //
+
208  // inline
+
209  // int8_t phMod(long phmod_proportion)
+
210  // {
+
211  // incrementPhase();
+
212  // return FLASH_OR_RAM_READ<const int8_t>(table + (((phase_fractional+(phmod_proportion * NUM_TABLE_CELLS))>>SAMPLE_SAMPLE_F_BITS) & (NUM_TABLE_CELLS - 1)));
+
213  // }
+
214 
+
215 
+
216 
+
217  /** Set the oscillator frequency with an unsigned int.
+
218  This is faster than using a float, so it's useful when processor time is tight,
+
219  but it can be tricky with low and high frequencies, depending on the size of the
+
220  wavetable being used. If you're not getting the results you expect, try
+
221  explicitly using a float, or try setFreq_Q24n8.
+
222  @param frequency to play the wave table.
+
223  */
+
224  inline
+
225  void setFreq (int frequency) {
+
226  phase_increment_fractional = ((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)*frequency)/UPDATE_RATE) << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS);
+
227  }
+
228 
+
229 
+
230  /** Set the sample frequency with a float. Using a float is the most reliable
+
231  way to set frequencies, -Might- be slower than using an int but you need either
+
232  this or setFreq_Q24n8 for fractional frequencies.
+
233  @param frequency to play the wave table.
+
234  */
+
235  inline
+
236  void setFreq(float frequency)
+
237  { // 1 us - using float doesn't seem to incur measurable overhead with the oscilloscope
+
238  phase_increment_fractional = (unsigned long)((((float)NUM_TABLE_CELLS * frequency)/UPDATE_RATE) * SAMPLE_F_BITS_AS_MULTIPLIER);
+
239  }
+
240 
+
241 
+
242  /** Set the frequency using Q24n8 fixed-point number format.
+
243  This might be faster than the float version for setting low frequencies
+
244  such as 1.5 Hz, or other values which may not work well with your table
+
245  size. Note: use with caution because it's prone to overflow with higher
+
246  frequencies and larger table sizes. An Q24n8 representation of 1.5 is 384
+
247  (ie. 1.5 * 256).
+
248  @param frequency in Q24n8 fixed-point number format.
+
249  */
+
250  inline
+
251  void setFreq_Q24n8(Q24n8 frequency)
+
252  {
+
253  //phase_increment_fractional = (frequency* (NUM_TABLE_CELLS>>3)/(UPDATE_RATE>>6)) << (F_BITS-(8-3+6));
+
254  phase_increment_fractional = (((((unsigned long)NUM_TABLE_CELLS<<ADJUST_FOR_NUM_TABLE_CELLS)>>3)*frequency)/(UPDATE_RATE>>6))
+
255  << (SAMPLE_F_BITS - ADJUST_FOR_NUM_TABLE_CELLS - (8-3+6));
+
256  }
+
257 
+
258 
+
259  /** Returns the sample at the given table index.
+
260  @param index between 0 and the table size.
+
261  @return the sample at the given table index.
+
262  */
+
263  inline
+
264  int8_t atIndex(unsigned int index)
+
265  {
+
266  return FLASH_OR_RAM_READ<const int8_t>(table + index);
+
267  }
+
268 
+
269 
+
270  /** phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.
+
271  Instead of recalculating the phase increment for each
+
272  frequency in between, you can just calculate the phase increment for each end
+
273  frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and
+
274  use setPhaseInc() to set the phase increment at each step. (Note: I should
+
275  really profile this with the oscilloscope to see if it's worth the extra
+
276  confusion!)
+
277  @param frequency for which you want to calculate a phase increment value.
+
278  @return the phase increment value which will produce a given frequency.
+
279  */
+
280  inline
+
281  unsigned long phaseIncFromFreq(unsigned int frequency)
+
282  {
+
283  return (((unsigned long)frequency * NUM_TABLE_CELLS)/UPDATE_RATE) << SAMPLE_F_BITS;
+
284  }
+
285 
+
286 
+
287  /** Set a specific phase increment. See phaseIncFromFreq().
+
288  @param phaseinc_fractional a phase increment value as calculated by phaseIncFromFreq().
+
289  */
+
290  inline
+
291  void setPhaseInc(unsigned long phaseinc_fractional)
+
292  {
+
293  phase_increment_fractional = phaseinc_fractional;
+
294  }
+
295 
+
296 
+
297 private:
+
298 
+
299 
+
300  /** Used for shift arithmetic in setFreq() and its variations.
+
301  */
+
302 static const uint8_t ADJUST_FOR_NUM_TABLE_CELLS = (NUM_TABLE_CELLS<2048) ? 8 : 0;
+
303 
+
304 
+
305  /** Increments the phase of the oscillator without returning a sample.
+
306  */
+
307  inline
+
308  void incrementPhase()
+
309  {
+
310  phase_fractional += phase_increment_fractional;
+
311  }
+
312 
+
313 
+
314  volatile unsigned long phase_fractional;
+
315  volatile unsigned long phase_increment_fractional;
+
316  const int8_t * table;
+
317  bool looping;
+
318  unsigned long startpos_fractional, endpos_fractional;
+
319 };
+
320 
+
321 
+
322 /**
+
323 @example 08.Samples/Sample/Sample.ino
+
324 This example demonstrates the Sample class.
+
325 */
+
326 
+
327 #endif /* SAMPLE_H_ */
diff --git a/extras/doc/html/_sample_huffman_8h_source.html b/extras/doc/html/_sample_huffman_8h_source.html index 912cae639..732d1b919 100644 --- a/extras/doc/html/_sample_huffman_8h_source.html +++ b/extras/doc/html/_sample_huffman_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: SampleHuffman.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,20 +99,173 @@
SampleHuffman.h
-
1 /*
2  * SampleHuffman.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 #ifndef SAMPLEHUFFMAN_H
12 #define SAMPLEHUFFMAN_H
13 
14 #include "mozzi_pgmspace.h"
15 
16 /** A sample player for samples encoded with Huffman compression.
17 
18 This class and the audio2huff.py script are adapted from "audioout",
19 an Arduino sketch by Thomas Grill, 2011 http//grrrr.org
20 
21 Huffman decoding is used on sample differentials,
22 saving 50-70% of space for 8 bit data, depending on the sample rate.
23 
24 This implementation just plays back one sample each time next() is called, with no
25 speed or other adjustments.
26 It's slow, so it's likely you will only be able to play one sound at a time.
27 
28 Audio data, Huffman decoder table, sample rate and bit depth are defined
29 in a sounddata.h header file. This file can be generated for a sound file with the
30 accompanying Python script audio2huff.py, in Mozzi/extras/python/
31 
32 Invoke with:
33 python audio2huff.py --sndfile=arduinosnd.wav --hdrfile=sounddata.h --bits=8 --name=soundtablename
34 
35 You can resample and dither your audio file with SOX,
36 e.g. to 8 bits depth @ Mozzi's 16384 Hz sample rate:
37 sox fullglory.wav -b 8 -r 16384 arduinosnd.wav
38 
39 Alternatively you can export a sound from Audacity, which seems to have less noticeable or no dithering,
40 using Project Rate 16384 Hz and these output options:
41 Other uncompressed files, Header: WAV(Microsoft), Encoding: Unsigned 8 bit PCM
42 
43 The header file contains two lengthy arrays:
44 One is "SOUNDDATA" which must fit into Flash RAM (available in total: 32k for ATMega328)
45 The other is "HUFFMAN" which must also fit into Flash RAM
46 
47 */
48 
49 class SampleHuffman
50 {
51 
52 public:
53 
54  /** Constructor
55  @param SOUNDDATA the name of the SOUNDDATA table in the huffman sample .h file
56  @param HUFFMAN_DATA the name of the HUFFMAN table in the huffman sample .h file
57  @param SOUNDDATA_BITS from the huffman sample .h file
58  */
60  {
62  }
63 
64 
65  /** Update and return the next audio sample. So far it just plays back one sample at a time without any variable tuning or speed.
66  @return the next audio sample
67  @note timing: about 5 to 40 us, varies continuously depending on data
68  */
69  inline
71  {
72  if(datapos >= sounddata_bits){
73  if(looping){
74  // at end of sample, restart from zero, looping the sound
75  datapos = 0;
76  }else{
77  return 0;
78  }
79  }
80 
81  int16_t dif = decode();
82  current += dif; // add differential
83  return current;
84  }
85 
86 
87  /** Turns looping on, with the whole sample length as the loop range.
88  */
89  inline
90  void setLoopingOn()
91  {
92  looping=true;
93  }
94 
95 
96  /** Turns looping off.
97  */
98  inline
100  {
101  looping=false;
102  }
103 
104  /** Sets the playhead to the beginning of the sample.
105  */
106  inline
107  void start()
108  {
109  current = 0;
110  datapos = 0;
111  bt = 0;
112  }
113 
114 private:
115  uint8_t const * sounddata;
116  int16_t const * huffman;
117  uint32_t const sounddata_bits;
118  uint32_t datapos; // current sample position
119  int16_t current; // current amplitude value
120  bool looping;
121  uint8_t bt;
122 
123  // Get one bit from sound data
124  inline
125  bool getbit()
126  {
127  const uint8_t b = datapos&7;
128  //static uint8_t bt;
129  if(!b) bt = FLASH_OR_RAM_READ<const uint8_t>(sounddata+((uint32_t)datapos>>3));
130  // extract the indexed bit
131  return ((uint8_t)bt>>(7-b))&1;
132  }
133 
134 
135  // Decode bit stream using Huffman codes
136  inline
137  int16_t decode()
138  {
139  int16_t const * huffcode = huffman;
140  do {
141  if(getbit()) {
142  const int16_t offs = FLASH_OR_RAM_READ<const int16_t>(huffcode);
143  huffcode += offs?offs+1:2;
144  }
145  datapos++;
146  }
147  while(FLASH_OR_RAM_READ<const int16_t>(huffcode++));
148  return FLASH_OR_RAM_READ<const int16_t>(huffcode);
149  }
150 
151 
152 };
153 
154 /**
155 @example 08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino
156 This example demonstrates the Sample class.
157 */
158 
159 #endif // #ifndef SAMPLEHUFFMAN_H
void setLoopingOn()
Turns looping on, with the whole sample length as the loop range.
Definition: SampleHuffman.h:90
-
SampleHuffman(uint8_t const *SOUNDDATA, int16_t const *HUFFMAN_DATA, uint32_t const SOUNDDATA_BITS)
Constructor.
Definition: SampleHuffman.h:59
-
void start()
Sets the playhead to the beginning of the sample.
-
void setLoopingOff()
Turns looping off.
Definition: SampleHuffman.h:99
-
int16_t next()
Update and return the next audio sample.
Definition: SampleHuffman.h:70
+
1 /*
+
2  * SampleHuffman.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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 SAMPLEHUFFMAN_H
+
13 #define SAMPLEHUFFMAN_H
+
14 
+
15 #include "mozzi_pgmspace.h"
+
16 
+
17 /** A sample player for samples encoded with Huffman compression.
+
18 
+
19 This class and the audio2huff.py script are adapted from "audioout",
+
20 an Arduino sketch by Thomas Grill, 2011 http//grrrr.org
+
21 
+
22 Huffman decoding is used on sample differentials,
+
23 saving 50-70% of space for 8 bit data, depending on the sample rate.
+
24 
+
25 This implementation just plays back one sample each time next() is called, with no
+
26 speed or other adjustments.
+
27 It's slow, so it's likely you will only be able to play one sound at a time.
+
28 
+
29 Audio data, Huffman decoder table, sample rate and bit depth are defined
+
30 in a sounddata.h header file. This file can be generated for a sound file with the
+
31 accompanying Python script audio2huff.py, in Mozzi/extras/python/
+
32 
+
33 Invoke with:
+
34 python audio2huff.py --sndfile=arduinosnd.wav --hdrfile=sounddata.h --bits=8 --name=soundtablename
+
35 
+
36 You can resample and dither your audio file with SOX,
+
37 e.g. to 8 bits depth @ Mozzi's 16384 Hz sample rate:
+
38 sox fullglory.wav -b 8 -r 16384 arduinosnd.wav
+
39 
+
40 Alternatively you can export a sound from Audacity, which seems to have less noticeable or no dithering,
+
41 using Project Rate 16384 Hz and these output options:
+
42 Other uncompressed files, Header: WAV(Microsoft), Encoding: Unsigned 8 bit PCM
+
43 
+
44 The header file contains two lengthy arrays:
+
45 One is "SOUNDDATA" which must fit into Flash RAM (available in total: 32k for ATMega328)
+
46 The other is "HUFFMAN" which must also fit into Flash RAM
+
47 
+
48 */
+
49 
+ +
51 {
+
52 
+
53 public:
+
54 
+
55  /** Constructor
+
56  @param SOUNDDATA the name of the SOUNDDATA table in the huffman sample .h file
+
57  @param HUFFMAN_DATA the name of the HUFFMAN table in the huffman sample .h file
+
58  @param SOUNDDATA_BITS from the huffman sample .h file
+
59  */
+
60  SampleHuffman(uint8_t const * SOUNDDATA, int16_t const * HUFFMAN_DATA, uint32_t const SOUNDDATA_BITS):sounddata(SOUNDDATA),huffman(HUFFMAN_DATA),sounddata_bits(SOUNDDATA_BITS)
+
61  {
+ +
63  }
+
64 
+
65 
+
66  /** Update and return the next audio sample. So far it just plays back one sample at a time without any variable tuning or speed.
+
67  @return the next audio sample
+
68  @note timing: about 5 to 40 us, varies continuously depending on data
+
69  */
+
70  inline
+ +
72  {
+
73  if(datapos >= sounddata_bits){
+
74  if(looping){
+
75  // at end of sample, restart from zero, looping the sound
+
76  datapos = 0;
+
77  }else{
+
78  return 0;
+
79  }
+
80  }
+
81 
+
82  int16_t dif = decode();
+
83  current += dif; // add differential
+
84  return current;
+
85  }
+
86 
+
87 
+
88  /** Turns looping on, with the whole sample length as the loop range.
+
89  */
+
90  inline
+
91  void setLoopingOn()
+
92  {
+
93  looping=true;
+
94  }
+
95 
+
96 
+
97  /** Turns looping off.
+
98  */
+
99  inline
+ +
101  {
+
102  looping=false;
+
103  }
+
104 
+
105  /** Sets the playhead to the beginning of the sample.
+
106  */
+
107  inline
+
108  void start()
+
109  {
+
110  current = 0;
+
111  datapos = 0;
+
112  bt = 0;
+
113  }
+
114 
+
115 private:
+
116  uint8_t const * sounddata;
+
117  int16_t const * huffman;
+
118  uint32_t const sounddata_bits;
+
119  uint32_t datapos; // current sample position
+
120  int16_t current; // current amplitude value
+
121  bool looping;
+
122  uint8_t bt;
+
123 
+
124  // Get one bit from sound data
+
125  inline
+
126  bool getbit()
+
127  {
+
128  const uint8_t b = datapos&7;
+
129  //static uint8_t bt;
+
130  if(!b) bt = FLASH_OR_RAM_READ<const uint8_t>(sounddata+((uint32_t)datapos>>3));
+
131  // extract the indexed bit
+
132  return ((uint8_t)bt>>(7-b))&1;
+
133  }
+
134 
+
135 
+
136  // Decode bit stream using Huffman codes
+
137  inline
+
138  int16_t decode()
+
139  {
+
140  int16_t const * huffcode = huffman;
+
141  do {
+
142  if(getbit()) {
+
143  const int16_t offs = FLASH_OR_RAM_READ<const int16_t>(huffcode);
+
144  huffcode += offs?offs+1:2;
+
145  }
+
146  datapos++;
+
147  }
+
148  while(FLASH_OR_RAM_READ<const int16_t>(huffcode++));
+
149  return FLASH_OR_RAM_READ<const int16_t>(huffcode);
+
150  }
+
151 
+
152 
+
153 };
+
154 
+
155 /**
+
156 @example 08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino
+
157 This example demonstrates the Sample class.
+
158 */
+
159 
+
160 #endif // #ifndef SAMPLEHUFFMAN_H
diff --git a/extras/doc/html/_skeleton___multi___unit2_8cpp_source.html b/extras/doc/html/_skeleton___multi___unit2_8cpp_source.html index 362c3b4ae..325e02885 100644 --- a/extras/doc/html/_skeleton___multi___unit2_8cpp_source.html +++ b/extras/doc/html/_skeleton___multi___unit2_8cpp_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Skeleton_Multi_Unit2.cpp Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,20 @@
Skeleton_Multi_Unit2.cpp
-
1 #include <MozziHeadersOnly.h> // <Mozzi.h> should be included only once in the whole program. Sketches needing
2  // core Mozzi functions in more than one .cpp file, shall include MozziHeadersOnly.h
3  // in all but one.
4 
5 AudioOutput_t updateAudio() {
6  return MonoOutput::from8Bit(0); // just a dummy
7 }
AudioOutput_t updateAudio()
This is where you put your audio code.
+
1 #include <MozziHeadersOnly.h> // <Mozzi.h> should be included only once in the whole program. Sketches needing
+
2  // core Mozzi functions in more than one .cpp file, shall include MozziHeadersOnly.h
+
3  // in all but one.
+
4 
+
5 AudioOutput_t updateAudio() {
+
6  return MonoOutput::from8Bit(0); // just a dummy
+
7 }
diff --git a/extras/doc/html/_smooth_8h_source.html b/extras/doc/html/_smooth_8h_source.html index a7f69f729..90245eefb 100644 --- a/extras/doc/html/_smooth_8h_source.html +++ b/extras/doc/html/_smooth_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Smooth.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,23 +99,443 @@
Smooth.h
-
1 /*
2  * Smooth.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef SMOOTH_H_
13 #define SMOOTH_H_
14 
15 #include "Arduino.h"
16 #include "mozzi_fixmath.h"
17 
18 /** A simple infinite impulse response low pass filter for smoothing control or audio signals.
19 This algorithm comes from http://en.wikipedia.org/wiki/Low-pass_filter:
20 y[i] := y[i-1] + α * (x[i] - y[i-1]),
21 translated as
22 out = last_out + a * (in - last_out).
23 It's not calibrated to any real-world update rate, so if you use it at
24 MOZZI_CONTROL_RATE and you change MOZZI_CONTROL_RATE, you'll need to adjust the smoothness
25 value to suit.
26 @tparam T the type of numbers being smoothed. Watch out for numbers overflowing the
27 internal calculations. Some experimentation is recommended.
28 @note Timing: ~5us for 16 bit types, ~1us for 8 bit types.
29 @todo Check if 8 bit templates can work efficiently with a higher res smoothness -
30  as is they don't have enough resolution to work well at audio rate. See if Line might be
31  more useful in most cases.
32 */
33 
34 template <class T>
35 class Smooth
36 {
37 private:
38  long last_out;
39  Q0n16 a;
40 
41 public:
42  /** Constructor.
43  @param smoothness sets how much smoothing the filter will apply to
44  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
45  very smooth.
46  */
47  Smooth(float smoothness)
48  {
49  setSmoothness(smoothness);
50  }
51 
52  /** Constructor.
53  This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition.
54  You need to call setSmoothness(float) for your object before using Smooth.
55  @note there's probably a better way to do this...
56  */
58  {}
59 
60 
61  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
62  @param in the signal to be smoothed.
63  @return the filtered signal.
64  */
65  inline
66  T next(T in)
67  {
68  long out = ((((((long)in - (last_out>>8)) * a))>>8) + last_out);
69  last_out = out;
70  return (T)(out>>8);
71  }
72 
73 
74  /** Filters the input and returns the filtered value. Same as next(input-value).
75  @param in the signal to be smoothed.
76  @return the filtered signal.
77  */
78  inline
79  T operator()(T n) {
80  return next(n);
81  }
82 
83 
84  /** Sets how much smoothing the filter will apply to its input.
85  @param smoothness sets how much smoothing the filter will apply to
86  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
87  very smooth.
88  */
89  inline
90  void setSmoothness(float smoothness)
91  {
92  a=float_to_Q0n16(1.f-smoothness);
93  }
94 
95 };
96 
97 
98 /** @cond */ // doxygen can ignore the specialisations
99 
100 /** uint8_t specialisation of Smooth template*/
101 template <>
102 class Smooth <uint8_t>
103 {
104 private:
105  unsigned int last_out;
106  Q0n8 a;
107 
108 public:
109  /** Constructor.
110  @param smoothness sets how much smoothing the filter will apply to
111  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
112  very smooth.
113  */
114  Smooth(float smoothness)
115  {
116  setSmoothness(smoothness);
117  }
118 
119  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
120  @param in the signal to be smoothed.
121  @return the filtered signal.
122  */
123  inline
124  uint8_t next(uint8_t in)
125  {
126  unsigned int out = (((((int)in - (last_out>>8)) * a)) + last_out);
127  last_out = out;
128  return (uint8_t)(out>>8);
129  }
130 
131 
132  /** Filters the input and returns the filtered value. Same as next(input-value).
133  @param in the signal to be smoothed.
134  @return the filtered signal.
135  */
136  inline
137  uint8_t operator()(uint8_t n) {
138  return next(n);
139  }
140 
141 
142  /** Sets how much smoothing the filter will apply to its input.
143  @param smoothness sets how much smoothing the filter will apply to
144  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
145  very smooth.
146  */
147  inline
148  void setSmoothness(float smoothness)
149  {
150  a=float_to_Q0n8(1.f-smoothness);
151  }
152 
153 };
154 
155 
156 /** int8_t specialisation of Smooth template*/
157 template <>
158 class Smooth <int8_t>
159 {
160 private:
161  int last_out;
162  Q0n8 a;
163 
164 public:
165  /** Constructor.
166  @param smoothness sets how much smoothing the filter will apply to
167  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
168  very smooth.
169  */
170  Smooth(float smoothness)
171  {
172  setSmoothness(smoothness);
173  }
174 
175 
176  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
177  @param in the signal to be smoothed.
178  @return the filtered signal.
179  */
180  inline
181  int8_t next(int8_t in)
182  {
183  int out = (((((int)in - (last_out>>8)) * a)) + last_out);
184  last_out = out;
185  return (int8_t)(out>>8);
186  }
187 
188 
189  /** Filters the input and returns the filtered value. Same as next(input-value).
190  @param in the signal to be smoothed.
191  @return the filtered signal.
192  */
193  inline
194  int8_t operator()(int8_t n) {
195  return next(n);
196  }
197 
198 
199  /** Sets how much smoothing the filter will apply to its input.
200  @param smoothness sets how much smoothing the filter will apply to
201  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
202  very smooth.
203  */
204  inline
205  void setSmoothness(float smoothness)
206  {
207  a=float_to_Q0n8(1.f-smoothness);
208  }
209 
210 };
211 
212 /** float specialisation of Smooth template*/
213 template <>
214 class Smooth <float>
215 {
216 private:
217  float last_out;
218  float a;
219 
220 public:
221  /** Constructor.
222  @param smoothness sets how much smoothing the filter will apply to
223  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
224  very smooth.
225  */
226  Smooth(float smoothness)
227  {
228  setSmoothness(smoothness);
229  }
230 
231  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
232  @param in the signal to be smoothed.
233  @return the filtered signal.
234  */
235  inline
236  float next(float in)
237  {
238  float out = last_out + a * (in - last_out);
239  //float out = (in - last_out * a) + last_out;
240  last_out = out;
241  return out;
242  }
243 
244 
245  /** Filters the input and returns the filtered value. Same as next(input-value).
246  @param in the signal to be smoothed.
247  @return the filtered signal.
248  */
249  inline
250  float operator()(float n) {
251  return next(n);
252  }
253 
254 
255  /** Sets how much smoothing the filter will apply to its input.
256  @param smoothness sets how much smoothing the filter will apply to
257  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
258  very smooth.
259  */
260  inline
261  void setSmoothness(float smoothness)
262  {
263  a=1.f-smoothness;
264  }
265 
266 };
267 
268 
269 /** @endcond */
270 
271 /**
272 @example 05.Control_Filters/Smooth/Smooth.ino
273 This example demonstrates the Smooth class.
274 */
275 
276 #endif /* SMOOTH_H_ */
void setSmoothness(float smoothness)
Sets how much smoothing the filter will apply to its input.
Definition: Smooth.h:90
-
Smooth(float smoothness)
Constructor.
Definition: Smooth.h:47
-
uint16_t Q0n16
unsigned fractional number using 16 fractional bits, represents 0.0 to 0.999
Definition: mozzi_fixmath.h:27
-
A simple infinite impulse response low pass filter for smoothing control or audio signals...
Definition: Smooth.h:35
-
T operator()(T n)
Filters the input and returns the filtered value.
Definition: Smooth.h:79
-
Q0n16 float_to_Q0n16(float a)
Convert float to Q0n16 fix.
-
T next(T in)
Filters the input and returns the filtered value.
Definition: Smooth.h:66
-
Smooth()
Constructor.
Definition: Smooth.h:57
+
1 /*
+
2  * Smooth.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 SMOOTH_H_
+
13 #define SMOOTH_H_
+
14 
+
15 #include "Arduino.h"
+
16 #include "mozzi_fixmath.h"
+
17 
+
18 /** A simple infinite impulse response low pass filter for smoothing control or audio signals.
+
19 This algorithm comes from http://en.wikipedia.org/wiki/Low-pass_filter:
+
20 y[i] := y[i-1] + α * (x[i] - y[i-1]),
+
21 translated as
+
22 out = last_out + a * (in - last_out).
+
23 It's not calibrated to any real-world update rate, so if you use it at
+
24 MOZZI_CONTROL_RATE and you change MOZZI_CONTROL_RATE, you'll need to adjust the smoothness
+
25 value to suit.
+
26 @tparam T the type of numbers being smoothed. Watch out for numbers overflowing the
+
27 internal calculations. Some experimentation is recommended.
+
28 @note Timing: ~5us for 16 bit types, ~1us for 8 bit types.
+
29 @todo Check if 8 bit templates can work efficiently with a higher res smoothness -
+
30  as is they don't have enough resolution to work well at audio rate. See if Line might be
+
31  more useful in most cases.
+
32 */
+
33 
+
34 template <class T>
+
35 class Smooth
+
36 {
+
37 private:
+
38  long last_out;
+
39  Q0n16 a;
+
40 
+
41 public:
+
42  /** Constructor.
+
43  @param smoothness sets how much smoothing the filter will apply to
+
44  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
45  very smooth.
+
46  */
+
47  Smooth(float smoothness)
+
48  {
+
49  setSmoothness(smoothness);
+
50  }
+
51 
+
52  /** Constructor.
+
53  This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition.
+
54  You need to call setSmoothness(float) for your object before using Smooth.
+
55  @note there's probably a better way to do this...
+
56  */
+ +
58  {}
+
59 
+
60 
+
61  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
+
62  @param in the signal to be smoothed.
+
63  @return the filtered signal.
+
64  */
+
65  inline
+
66  T next(T in)
+
67  {
+
68  long out = ((((((long)in - (last_out>>8)) * a))>>8) + last_out);
+
69  last_out = out;
+
70  return (T)(out>>8);
+
71  }
+
72 
+
73 
+
74  /** Filters the input and returns the filtered value. Same as next(input-value).
+
75  @param in the signal to be smoothed.
+
76  @return the filtered signal.
+
77  */
+
78  inline
+
79  T operator()(T n) {
+
80  return next(n);
+
81  }
+
82 
+
83 
+
84  /** Sets how much smoothing the filter will apply to its input.
+
85  @param smoothness sets how much smoothing the filter will apply to
+
86  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
87  very smooth.
+
88  */
+
89  inline
+
90  void setSmoothness(float smoothness)
+
91  {
+
92  a=float_to_Q0n16(1.f-smoothness);
+
93  }
+
94 
+
95 };
+
96 
+
97 
+
98 /** @cond */ // doxygen can ignore the specialisations
+
99 
+
100 /** uint8_t specialisation of Smooth template*/
+
101 template <>
+
102 class Smooth <uint8_t>
+
103 {
+
104 private:
+
105  unsigned int last_out;
+
106  Q0n8 a;
+
107 
+
108 public:
+
109  /** Constructor.
+
110  @param smoothness sets how much smoothing the filter will apply to
+
111  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
112  very smooth.
+
113  */
+
114  Smooth(float smoothness)
+
115  {
+
116  setSmoothness(smoothness);
+
117  }
+
118 
+
119  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
+
120  @param in the signal to be smoothed.
+
121  @return the filtered signal.
+
122  */
+
123  inline
+
124  uint8_t next(uint8_t in)
+
125  {
+
126  unsigned int out = (((((int)in - (last_out>>8)) * a)) + last_out);
+
127  last_out = out;
+
128  return (uint8_t)(out>>8);
+
129  }
+
130 
+
131 
+
132  /** Filters the input and returns the filtered value. Same as next(input-value).
+
133  @param in the signal to be smoothed.
+
134  @return the filtered signal.
+
135  */
+
136  inline
+
137  uint8_t operator()(uint8_t n) {
+
138  return next(n);
+
139  }
+
140 
+
141 
+
142  /** Sets how much smoothing the filter will apply to its input.
+
143  @param smoothness sets how much smoothing the filter will apply to
+
144  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
145  very smooth.
+
146  */
+
147  inline
+
148  void setSmoothness(float smoothness)
+
149  {
+
150  a=float_to_Q0n8(1.f-smoothness);
+
151  }
+
152 
+
153 };
+
154 
+
155 
+
156 /** int8_t specialisation of Smooth template*/
+
157 template <>
+
158 class Smooth <int8_t>
+
159 {
+
160 private:
+
161  int last_out;
+
162  Q0n8 a;
+
163 
+
164 public:
+
165  /** Constructor.
+
166  @param smoothness sets how much smoothing the filter will apply to
+
167  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
168  very smooth.
+
169  */
+
170  Smooth(float smoothness)
+
171  {
+
172  setSmoothness(smoothness);
+
173  }
+
174 
+
175 
+
176  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
+
177  @param in the signal to be smoothed.
+
178  @return the filtered signal.
+
179  */
+
180  inline
+
181  int8_t next(int8_t in)
+
182  {
+
183  int out = (((((int)in - (last_out>>8)) * a)) + last_out);
+
184  last_out = out;
+
185  return (int8_t)(out>>8);
+
186  }
+
187 
+
188 
+
189  /** Filters the input and returns the filtered value. Same as next(input-value).
+
190  @param in the signal to be smoothed.
+
191  @return the filtered signal.
+
192  */
+
193  inline
+
194  int8_t operator()(int8_t n) {
+
195  return next(n);
+
196  }
+
197 
+
198 
+
199  /** Sets how much smoothing the filter will apply to its input.
+
200  @param smoothness sets how much smoothing the filter will apply to
+
201  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
202  very smooth.
+
203  */
+
204  inline
+
205  void setSmoothness(float smoothness)
+
206  {
+
207  a=float_to_Q0n8(1.f-smoothness);
+
208  }
+
209 
+
210 };
+
211 
+
212 /** float specialisation of Smooth template*/
+
213 template <>
+
214 class Smooth <float>
+
215 {
+
216 private:
+
217  float last_out;
+
218  float a;
+
219 
+
220 public:
+
221  /** Constructor.
+
222  @param smoothness sets how much smoothing the filter will apply to
+
223  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
224  very smooth.
+
225  */
+
226  Smooth(float smoothness)
+
227  {
+
228  setSmoothness(smoothness);
+
229  }
+
230 
+
231  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
+
232  @param in the signal to be smoothed.
+
233  @return the filtered signal.
+
234  */
+
235  inline
+
236  float next(float in)
+
237  {
+
238  float out = last_out + a * (in - last_out);
+
239  //float out = (in - last_out * a) + last_out;
+
240  last_out = out;
+
241  return out;
+
242  }
+
243 
+
244 
+
245  /** Filters the input and returns the filtered value. Same as next(input-value).
+
246  @param in the signal to be smoothed.
+
247  @return the filtered signal.
+
248  */
+
249  inline
+
250  float operator()(float n) {
+
251  return next(n);
+
252  }
+
253 
+
254 
+
255  /** Sets how much smoothing the filter will apply to its input.
+
256  @param smoothness sets how much smoothing the filter will apply to
+
257  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
258  very smooth.
+
259  */
+
260  inline
+
261  void setSmoothness(float smoothness)
+
262  {
+
263  a=1.f-smoothness;
+
264  }
+
265 
+
266 };
+
267 
+
268 
+
269 /** @endcond */
+
270 
+
271 
+
272 /* Specialization for UFix */
+
273 template<int8_t NI, int8_t NF>
+
274 class Smooth<UFix<NI,NF>>
+
275 {
+
276 private:
+
277  typedef UFix<NI, NF> internal_type;
+
278  internal_type last_out;
+
279  UFix<0,16> a;
+
280 
+
281 public:
+
282 
+
283 
+
284  /** Constructor.
+
285  @param smoothness sets how much smoothing the filter will apply to
+
286  its input. Use a float or a UFix<0,NF> in the range 0~1, where 0 is not very smooth and 0.99 is
+
287  very smooth.
+
288  */
+
289  template<typename T>
+
290  Smooth(T smoothness)
+
291  {
+
292  setSmoothness(smoothness);
+
293  }
+
294 
+
295  /** Constructor.
+
296  This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition.
+
297  You need to call setSmoothness(float) for your object before using Smooth.
+
298  @note there's probably a better way to do this...
+
299  */
+
300  Smooth()
+
301  {}
+
302 
+
303 
+
304  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
+
305  @param in the signal to be smoothed.
+
306  @return the filtered signal.
+
307  */
+
308  inline
+
309  internal_type next(internal_type in)
+
310  {
+
311  internal_type out = last_out + a * (in - last_out); // With FixMath, the syntax is actually the same than with floats :)
+
312  last_out = out;
+
313  return out;
+
314  }
+
315 
+
316 
+
317 
+
318  inline
+
319  internal_type operator()(internal_type n) {
+
320  return next(n);
+
321  }
+
322 
+
323  /** Sets how much smoothing the filter will apply to its input.
+
324  @param smoothness sets how much smoothing the filter will apply to
+
325  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
326  very smooth.
+
327  */
+
328  inline
+
329  void setSmoothness(float smoothness)
+
330  {
+
331  a=internal_type(1.f-smoothness);
+
332  }
+
333 
+
334  /** Sets how much smoothing the filter will apply to its input.
+
335  @param smoothness sets how much smoothing the filter will apply to
+
336  its input. Use a UFix<0,NF> in the range 0~1, where 0 is not very smooth and 0.99 is
+
337  very smooth.
+
338  */
+
339  template<int8_t _NF>
+
340  void setSmoothness(UFix<0,_NF> smoothness)
+
341  {
+
342  a = UFix<1,0>(1) - smoothness;
+
343  }
+
344 
+
345 };
+
346 
+
347 
+
348 
+
349 
+
350 /* Specialization for SFix */
+
351 template<int8_t NI, int8_t NF>
+
352 class Smooth<SFix<NI,NF>>
+
353 {
+
354 private:
+
355  typedef SFix<NI, NF> internal_type;
+
356  internal_type last_out;
+
357  UFix<0,16> a;
+
358 
+
359 public:
+
360 
+
361 
+
362  /** Constructor.
+
363  @param smoothness sets how much smoothing the filter will apply to
+
364  its input. Use a float or a UFix<0,NF> in the range 0~1, where 0 is not very smooth and 0.99 is
+
365  very smooth.
+
366  */
+
367  template<typename T>
+
368  Smooth(T smoothness)
+
369  {
+
370  setSmoothness(smoothness);
+
371  }
+
372 
+
373  /** Constructor.
+
374  This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition.
+
375  You need to call setSmoothness(float) for your object before using Smooth.
+
376  @note there's probably a better way to do this...
+
377  */
+
378  Smooth()
+
379  {}
+
380 
+
381 
+
382  /** Filters the input and returns the filtered value. You can also use the operator() function, eg. something like mySmoother(input-value).
+
383  @param in the signal to be smoothed.
+
384  @return the filtered signal.
+
385  */
+
386  inline
+
387  internal_type next(internal_type in)
+
388  {
+
389  internal_type out = last_out + a * (in - last_out);
+
390  last_out = out;
+
391  return out;
+
392  }
+
393 
+
394 
+
395 
+
396  inline
+
397  internal_type operator()(internal_type n) {
+
398  return next(n);
+
399  }
+
400 
+
401  /** Sets how much smoothing the filter will apply to its input.
+
402  @param smoothness sets how much smoothing the filter will apply to
+
403  its input. Use a float in the range 0~1, where 0 is not very smooth and 0.99 is
+
404  very smooth.
+
405  */
+
406  inline
+
407  void setSmoothness(float smoothness)
+
408  {
+
409  a=internal_type(1.f-smoothness);
+
410  }
+
411 
+
412  /** Sets how much smoothing the filter will apply to its input.
+
413  @param smoothness sets how much smoothing the filter will apply to
+
414  its input. Use a UFix<0,NF> in the range 0~1, where 0 is not very smooth and 0.99 is
+
415  very smooth.
+
416  */
+
417  template<int8_t _NF>
+
418  void setSmoothness(UFix<0,_NF> smoothness)
+
419  {
+
420  a = UFix<1,0>(1) - smoothness;
+
421  }
+
422 
+
423 };
+
424 
+
425 /**
+
426 @example 05.Control_Filters/Smooth/Smooth.ino
+
427 This example demonstrates the Smooth class.
+
428 */
+
429 
+
430 #endif /* SMOOTH_H_ */
diff --git a/extras/doc/html/_stack_8h_source.html b/extras/doc/html/_stack_8h_source.html index 3a3bb82a3..6bfb75d56 100644 --- a/extras/doc/html/_stack_8h_source.html +++ b/extras/doc/html/_stack_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: Stack.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,19 +99,66 @@
Stack.h
-
1 /*
2  * Stack.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12  /** A simple stack, used internally for keeping track of analog input channels as they are read.
13  This stack is really just an array with a pointer to the most recent item, and memory is allocated at compile time.
14 @tparam T the kind of numbers (or other things) to store.
15 @tparam NUM_ITEMS the maximum number of items the stack will need to hold.
16  */
17 template <class T, int NUM_ITEMS>
18 class Stack
19 {
20 private:
21  T _array[NUM_ITEMS];
22  int top;
23 
24 public:
25  /** Constructor
26  */
27  Stack(): top(-1)
28  {
29  }
30 
31 /** Put an item on the stack.
32 @param item the thing you want to put on the stack.
33 */
34  void push(T item)
35  {
36  if (top< (NUM_ITEMS-1)){
37  top++;
38  _array[top]=item;
39  }
40  }
41 
42 /** Get the item on top of the stack.
43 @return T the item
44 */
45  T pop()
46  {
47  if(top==-1) return -1;
48  T item =_array[top];
49  top--;
50  return item;
51  }
52 
53 };
A simple stack, used internally for keeping track of analog input channels as they are read...
Definition: Stack.h:18
-
T pop()
Get the item on top of the stack.
Definition: Stack.h:45
-
void push(T item)
Put an item on the stack.
Definition: Stack.h:34
-
Stack()
Constructor.
Definition: Stack.h:27
+
1 /*
+
2  * Stack.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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  /** A simple stack, used internally for keeping track of analog input channels as they are read.
+
13  This stack is really just an array with a pointer to the most recent item, and memory is allocated at compile time.
+
14 @tparam T the kind of numbers (or other things) to store.
+
15 @tparam NUM_ITEMS the maximum number of items the stack will need to hold.
+
16  */
+
17 template <class T, int NUM_ITEMS>
+
18 class Stack
+
19 {
+
20 private:
+
21  T _array[NUM_ITEMS];
+
22  int top;
+
23 
+
24 public:
+
25  /** Constructor
+
26  */
+
27  Stack(): top(-1)
+
28  {
+
29  }
+
30 
+
31 /** Put an item on the stack.
+
32 @param item the thing you want to put on the stack.
+
33 */
+
34  void push(T item)
+
35  {
+
36  if (top< (NUM_ITEMS-1)){
+
37  top++;
+
38  _array[top]=item;
+
39  }
+
40  }
+
41 
+
42 /** Get the item on top of the stack.
+
43 @return T the item
+
44 */
+
45  T pop()
+
46  {
+
47  if(top==-1) return -1;
+
48  T item =_array[top];
+
49  top--;
+
50  return item;
+
51  }
+
52 
+
53 };
diff --git a/extras/doc/html/_state_variable_8h_source.html b/extras/doc/html/_state_variable_8h_source.html index d00e3224f..23a948900 100644 --- a/extras/doc/html/_state_variable_8h_source.html +++ b/extras/doc/html/_state_variable_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: StateVariable.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,24 +99,203 @@
StateVariable.h
-
1 /*
2  * StateVariable.h
3  *
4  * This implementation copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 /**
14 State Variable Filter (approximation of Chamberlin version)
15 Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and
16 http://www.musicdsp.org/showone.php?id=142. Here's the original:
17 ---------------------
18 cutoff = cutoff freq in Hz
19 fs = sampling frequency //(e.g. 44100Hz)
20 f = 2 sin (pi * cutoff / fs) //[approximately]
21 q = resonance/bandwidth [0 < q <= 1] most res: q=1, less: q=0
22 low = lowpass output
23 high = highpass output
24 band = bandpass output
25 notch = notch output
26 
27 scale = q
28 
29 low=high=band=0;
30 
31 //--beginloop
32 low = low + f * band;
33 high = scale * input - low - q*band;
34 band = f * high + band;
35 notch = high + low;
36 //--endloop
37 ----------------------
38 References :
39 Hal Chamberlin, Musical Applications of Microprocessors, 2nd Ed, Hayden Book
40 Company 1985. pp 490-492. Jon Dattorro, Effect Design Part 1, J. Audio Eng.
41 Soc., Vol 45, No. 9, 1997 September
42 */
43 
44 #ifndef STATEVARIABLE_H_
45 #define STATEVARIABLE_H_
46 
47 #include "Arduino.h"
48 #include "math.h"
49 #include "meta.h"
50 #include "mozzi_fixmath.h"
51 #include "mozzi_utils.h"
52 #include "ResonantFilter.h"
53 
54 //enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
55 
56 /** A State Variable filter which offers 12db resonant low, high, bandpass and
57 notch modes.
58 @tparam FILTER_TYPE choose between LOWPASS, BANDPASS, HIGHPASS and NOTCH.
59 @note To save processing time, this version of the filter does not saturate
60 internally, so any resonant peaks are unceremoniously truncated. It may be
61 worth adding code to constrain the internal variables to enable resonant
62 saturating effects.
63 @todo Try adding code to constrain the internal variables to enable resonant
64 saturating effects.
65 */
66 template <int8_t FILTER_TYPE> class StateVariable {
67 
68 public:
69  /** Constructor.
70  */
72 
73  /** Set how resonant the filter will be.
74  @param resonance a byte value between 1 and 255.
75  The lower this value is, the more resonant the filter.
76  At very low values, the filter can output loud peaks which can exceed
77  Mozzi's output range, so you may need to attenuate the output in your sketch.
78  @note Timing < 500 ns
79  */
80  void setResonance(Q0n8 resonance) {
81  // qvalue goes from 255 to 0, representing .999 to 0 in fixed point
82  // lower q, more resonance
83  q = resonance;
84  scale = (Q0n8)sqrt((unsigned int)resonance << 8);
85  }
86 
87  /** Set the centre or corner frequency of the filter.
88  @param centre_freq 20 - 4096 Hz (MOZZI_AUDIO_RATE/4).
89  This will be the cut-off frequency for LOWPASS and HIGHPASS, and the
90  centre frequency to pass or reduce for BANDPASS and NOTCH.
91  @note Timing 25-30us
92  @note The frequency calculation is VERY "approximate". This really needs to
93  be fixed.
94  */
95  void setCentreFreq(unsigned int centre_freq) {
96  // simple frequency tuning with error towards nyquist (reference? where did
97  // this come from?)
98  // f = (Q1n15)(((Q16n16_2PI*centre_freq)>>AUDIO_RATE_AS_LSHIFT)>>1);
99  f = (Q15n16)((Q16n16_2PI * centre_freq) >>
100  (AUDIO_RATE_AS_LSHIFT)); // this works best for now
101  // f = (Q15n16)(((Q16n16_2PI*centre_freq)<<(16-AUDIO_RATE_AS_LSHIFT))>>16);
102  // // a small shift left and a round 16 right is faster than big
103  // non-byte-aligned right in one go float ff =
104  // Q16n16_to_float(((Q16n16_PI*centre_freq))>>AUDIO_RATE_AS_LSHIFT); f =
105  // float_to_Q15n16(2.0f *sin(ff));
106  }
107 
108  /** Calculate the next sample, given an input signal.
109  @param input the signal input.
110  @return the signal output.
111  @note Timing: 16 - 20 us
112  */
113  inline int next(int input) {
114  // chooses a different next() function depending on whether the
115  // filter is declared as LOWPASS, BANDPASS, HIGHPASS or NOTCH.
116  // See meta.h.
117  return next(input, Int2Type<FILTER_TYPE>());
118  }
119 
120 private:
121  int low, band;
122  Q0n8 q, scale;
123  volatile Q15n16 f;
124 
125  /** Calculate the next sample, given an input signal.
126  @param in the signal input.
127  @return the signal output.
128  @note Timing: 16 - 20 us
129  */
130  inline int next(int input, Int2Type<LOWPASS>) {
131  // setPin13High();
132  low += ((f * band) >> 16);
133  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
134  band += ((f * high) >> 16);
135  // int notch = high + low;
136  // setPin13Low();
137  return low;
138  }
139 
140  /** Calculate the next sample, given an input signal.
141  @param input the signal input.
142  @return the signal output.
143  @note Timing:
144  */
145  inline int next(int input, Int2Type<BANDPASS>) {
146  // setPin13High();
147  low += ((f * band) >> 16);
148  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
149  band += ((f * high) >> 16);
150  // int notch = high + low;
151  // setPin13Low();
152  return band;
153  }
154 
155  /** Calculate the next sample, given an input signal.
156  @param input the signal input.
157  @return the signal output.
158  @note Timing:
159  */
160  inline int next(int input, Int2Type<HIGHPASS>) {
161  // setPin13High();
162  low += ((f * band) >> 16);
163  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
164  band += ((f * high) >> 16);
165  // int notch = high + low;
166  // setPin13Low();
167  return high;
168  }
169 
170  /** Calculate the next sample, given an input signal.
171  @param input the signal input.
172  @return the signal output.
173  @note Timing: 16 - 20 us
174  */
175  inline int next(int input, Int2Type<NOTCH>) {
176  // setPin13High();
177  low += ((f * band) >> 16);
178  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
179  band += ((f * high) >> 16);
180  int notch = high + low;
181  // setPin13Low();
182  return notch;
183  }
184 };
185 
186 /**
187 @example 11.Audio_Filters/StateVariableFilter/StateVariableFilter.ino
188 This example demonstrates the StateVariable class.
189 */
190 
191 #endif /* STATEVARIABLE_H_ */
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:38
-
void setResonance(Q0n8 resonance)
Set how resonant the filter will be.
Definition: StateVariable.h:80
-
Enables you to instantiate a template based on an integer value.
Definition: meta.h:22
-
StateVariable()
Constructor.
Definition: StateVariable.h:71
-
int next(int input)
Calculate the next sample, given an input signal.
-
State Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www...
Definition: StateVariable.h:66
-
#define Q16n16_2PI
2*PI in Q16n16 format
Definition: mozzi_fixmath.h:67
-
uint8_t Q0n8
unsigned fractional number using 8 fractional bits, represents 0.0 to 0.996
Definition: mozzi_fixmath.h:25
-
void setCentreFreq(unsigned int centre_freq)
Set the centre or corner frequency of the filter.
Definition: StateVariable.h:95
+
1 /*
+
2  * StateVariable.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 /**
+
13 State Variable Filter (approximation of Chamberlin version)
+
14 Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and
+
15 http://www.musicdsp.org/showone.php?id=142. Here's the original:
+
16 ---------------------
+
17 cutoff = cutoff freq in Hz
+
18 fs = sampling frequency //(e.g. 44100Hz)
+
19 f = 2 sin (pi * cutoff / fs) //[approximately]
+
20 q = resonance/bandwidth [0 < q <= 1] most res: q=1, less: q=0
+
21 low = lowpass output
+
22 high = highpass output
+
23 band = bandpass output
+
24 notch = notch output
+
25 
+
26 scale = q
+
27 
+
28 low=high=band=0;
+
29 
+
30 //--beginloop
+
31 low = low + f * band;
+
32 high = scale * input - low - q*band;
+
33 band = f * high + band;
+
34 notch = high + low;
+
35 //--endloop
+
36 ----------------------
+
37 References :
+
38 Hal Chamberlin, Musical Applications of Microprocessors, 2nd Ed, Hayden Book
+
39 Company 1985. pp 490-492. Jon Dattorro, Effect Design Part 1, J. Audio Eng.
+
40 Soc., Vol 45, No. 9, 1997 September
+
41 */
+
42 
+
43 #ifndef STATEVARIABLE_H_
+
44 #define STATEVARIABLE_H_
+
45 
+
46 #include "Arduino.h"
+
47 #include "math.h"
+
48 #include "meta.h"
+
49 #include "mozzi_fixmath.h"
+
50 #include "mozzi_utils.h"
+
51 #include "ResonantFilter.h"
+
52 
+
53 //enum filter_types { LOWPASS, BANDPASS, HIGHPASS, NOTCH };
+
54 
+
55 /** A State Variable filter which offers 12db resonant low, high, bandpass and
+
56 notch modes.
+
57 @tparam FILTER_TYPE choose between LOWPASS, BANDPASS, HIGHPASS and NOTCH.
+
58 @note To save processing time, this version of the filter does not saturate
+
59 internally, so any resonant peaks are unceremoniously truncated. It may be
+
60 worth adding code to constrain the internal variables to enable resonant
+
61 saturating effects.
+
62 @todo Try adding code to constrain the internal variables to enable resonant
+
63 saturating effects.
+
64 */
+
65 template <int8_t FILTER_TYPE> class StateVariable {
+
66 
+
67 public:
+
68  /** Constructor.
+
69  */
+ +
71 
+
72  /** Set how resonant the filter will be.
+
73  @param resonance a byte value between 1 and 255.
+
74  The lower this value is, the more resonant the filter.
+
75  At very low values, the filter can output loud peaks which can exceed
+
76  Mozzi's output range, so you may need to attenuate the output in your sketch.
+
77  @note Timing < 500 ns
+
78  */
+
79  void setResonance(Q0n8 resonance) {
+
80  // qvalue goes from 255 to 0, representing .999 to 0 in fixed point
+
81  // lower q, more resonance
+
82  q = resonance;
+
83  scale = (Q0n8)sqrt((unsigned int)resonance << 8);
+
84  }
+
85 
+
86  /** Set the centre or corner frequency of the filter.
+
87  @param centre_freq 20 - 4096 Hz (MOZZI_AUDIO_RATE/4).
+
88  This will be the cut-off frequency for LOWPASS and HIGHPASS, and the
+
89  centre frequency to pass or reduce for BANDPASS and NOTCH.
+
90  @note Timing 25-30us
+
91  @note The frequency calculation is VERY "approximate". This really needs to
+
92  be fixed.
+
93  */
+
94  void setCentreFreq(unsigned int centre_freq) {
+
95  // simple frequency tuning with error towards nyquist (reference? where did
+
96  // this come from?)
+
97  // f = (Q1n15)(((Q16n16_2PI*centre_freq)>>AUDIO_RATE_AS_LSHIFT)>>1);
+
98  f = (Q15n16)((Q16n16_2PI * centre_freq) >>
+
99  (AUDIO_RATE_AS_LSHIFT)); // this works best for now
+
100  // f = (Q15n16)(((Q16n16_2PI*centre_freq)<<(16-AUDIO_RATE_AS_LSHIFT))>>16);
+
101  // // a small shift left and a round 16 right is faster than big
+
102  // non-byte-aligned right in one go float ff =
+
103  // Q16n16_to_float(((Q16n16_PI*centre_freq))>>AUDIO_RATE_AS_LSHIFT); f =
+
104  // float_to_Q15n16(2.0f *sin(ff));
+
105  }
+
106 
+
107  /** Calculate the next sample, given an input signal.
+
108  @param input the signal input.
+
109  @return the signal output.
+
110  @note Timing: 16 - 20 us
+
111  */
+
112  inline int next(int input) {
+
113  // chooses a different next() function depending on whether the
+
114  // filter is declared as LOWPASS, BANDPASS, HIGHPASS or NOTCH.
+
115  // See meta.h.
+
116  return next(input, Int2Type<FILTER_TYPE>());
+
117  }
+
118 
+
119 private:
+
120  int low, band;
+
121  Q0n8 q, scale;
+
122  volatile Q15n16 f;
+
123 
+
124  /** Calculate the next sample, given an input signal.
+
125  @param in the signal input.
+
126  @return the signal output.
+
127  @note Timing: 16 - 20 us
+
128  */
+
129  inline int next(int input, Int2Type<LOWPASS>) {
+
130  // setPin13High();
+
131  low += ((f * band) >> 16);
+
132  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
+
133  band += ((f * high) >> 16);
+
134  // int notch = high + low;
+
135  // setPin13Low();
+
136  return low;
+
137  }
+
138 
+
139  /** Calculate the next sample, given an input signal.
+
140  @param input the signal input.
+
141  @return the signal output.
+
142  @note Timing:
+
143  */
+
144  inline int next(int input, Int2Type<BANDPASS>) {
+
145  // setPin13High();
+
146  low += ((f * band) >> 16);
+
147  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
+
148  band += ((f * high) >> 16);
+
149  // int notch = high + low;
+
150  // setPin13Low();
+
151  return band;
+
152  }
+
153 
+
154  /** Calculate the next sample, given an input signal.
+
155  @param input the signal input.
+
156  @return the signal output.
+
157  @note Timing:
+
158  */
+
159  inline int next(int input, Int2Type<HIGHPASS>) {
+
160  // setPin13High();
+
161  low += ((f * band) >> 16);
+
162  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
+
163  band += ((f * high) >> 16);
+
164  // int notch = high + low;
+
165  // setPin13Low();
+
166  return high;
+
167  }
+
168 
+
169  /** Calculate the next sample, given an input signal.
+
170  @param input the signal input.
+
171  @return the signal output.
+
172  @note Timing: 16 - 20 us
+
173  */
+
174  inline int next(int input, Int2Type<NOTCH>) {
+
175  // setPin13High();
+
176  low += ((f * band) >> 16);
+
177  int high = (((long)input - low - (((long)band * q) >> 8)) * scale) >> 8;
+
178  band += ((f * high) >> 16);
+
179  int notch = high + low;
+
180  // setPin13Low();
+
181  return notch;
+
182  }
+
183 };
+
184 
+
185 /**
+
186 @example 11.Audio_Filters/StateVariableFilter/StateVariableFilter.ino
+
187 This example demonstrates the StateVariable class.
+
188 */
+
189 
+
190 #endif /* STATEVARIABLE_H_ */
diff --git a/extras/doc/html/_wave_folder_8h_source.html b/extras/doc/html/_wave_folder_8h_source.html index f51afcee5..0ad773c52 100644 --- a/extras/doc/html/_wave_folder_8h_source.html +++ b/extras/doc/html/_wave_folder_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: WaveFolder.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,23 +99,143 @@
WaveFolder.h
-
1 /*
2  * Wavefolder.h
3  *
4  * Copyright 2022 Thomas Combriat
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons
9  * Attribution-NonCommercial-ShareAlike 4.0 International License.
10  *
11  */
12 
13 #ifndef WAVEFOLDER_H
14 #define WAVEFOLDER_H
15 
16 
17 #include "IntegerType.h"
18 #include "AudioOutput.h"
19 
20 
21 /*
22  A simple wavefolder which folds the waves once it reachs the up or
23  low limits. The wave can be folded several times. It constrains the wave
24  to be constrain between the LowLimit and the HighLimit.
25  By default, this class is working on data which not overflow the
26  AudioOutputStorage_t type, which is int by default.
27  Feeding samples which, before folding, are overflowing this container
28  will lead to unpredicted behavior.
29  It is possible to use a bigger type with the template formulation
30  if needed.
31 */
32 
33 
34 /** A simple wavefolder
35  */
36 
37 template<typename T=AudioOutputStorage_t>
39 {
40 public:
41  /** Constructor
42  */
44 
45 
46  /** Set the high limit where the wave will start to be folded back the other way.
47  @param highLimit the high limit used by the wavefolder.
48  */
49  void setHighLimit(T highLimit)
50  {
51  hl = highLimit;
52  R = hl-ll;
53  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
54  }
55 
56 
57  /** Set the low limit where the wave will start to be folded back the other way.
58  @param lowLimit the low limit used by the wavefolder.
59  */
60  void setLowLimit(T lowLimit)
61  {
62  ll = lowLimit;
63  R = hl-ll;
64  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
65  }
66 
67 
68  /** Set the low and the high limits at the same time.
69  @param lowLimit the low limit used by the wavefolder
70  @param highLimit the high limit used by the wavefolder
71  @note highLimit MUST be higher than lowLimit
72  */
73  void setLimits(T lowLimit, T highLimit)
74  {
75  hl = highLimit;
76  ll = lowLimit;
77  R = hl-ll;
78  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
79  }
80 
81 
82  /** Return the next folded sample
83  @param in is the signal input.
84  @return the folded output.
85  */
86  T next(T in)
87  {
88  if (in > hl)
89  {
90  typename IntegerType<sizeof(T)>::unsigned_type sub = in-hl;
91  /* Instead of using a division, we multiply by the inverse.
92  As the inverse is necessary smaller than 1, in order to fit in an integer
93  we multiply it by NUMERATOR before computing the inverse.
94  The shift is equivalent to divide by the NUMERATOR:
95  q = sub / R = (sub * (NUMERATOR/R))/NUMERATOR with NUMERATOR/R = Ri
96  */
97  typename IntegerType<sizeof(T)>::unsigned_type q = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) sub*Ri) >> SHIFT;
98  typename IntegerType<sizeof(T)>::unsigned_type r = sub - q*R; // remainer
99  if (q&0b1) return ll+r; //odd
100  else return hl-r; // even
101 
102  }
103  else if (in < ll)
104  {
105  typename IntegerType<sizeof(T)>::unsigned_type sub = ll-in;
106  typename IntegerType<sizeof(T)>::unsigned_type q = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) sub*Ri) >> SHIFT;
107  typename IntegerType<sizeof(T)>::unsigned_type r = sub - q*R; // remainer
108  if (q&0b1) return hl-r;
109  else return ll+r;
110  }
111  else return in;
112  }
113 
114 private:
115  T hl;
116  T ll;
117  typename IntegerType<sizeof(T)>::unsigned_type R;
118  typename IntegerType<sizeof(T)>::unsigned_type Ri;
119  static const uint8_t SHIFT = (sizeof(T) << 3);
120  static const typename IntegerType<sizeof(T)>::unsigned_type NUMERATOR = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) 1<<(SHIFT))-1;
121 
122  // Slower (way slower, around 2.5 times) but more precise, kept in case we want to switch one day.
123  /* typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type Ri;
124  static const uint8_t SHIFT = 1+(sizeof(T) << 3);
125  static const typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type NUMERATOR = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) 1<<(SHIFT))-1;*/
126 
127 
128 };
129 
130 
131 #endif
Provides appropriate integer types that can bit the given number of bytes on this platform (at most 6...
Definition: IntegerType.h:9
-
void setHighLimit(T highLimit)
Set the high limit where the wave will start to be folded back the other way.
Definition: WaveFolder.h:49
-
void setLimits(T lowLimit, T highLimit)
Set the low and the high limits at the same time.
Definition: WaveFolder.h:73
-
void setLowLimit(T lowLimit)
Set the low limit where the wave will start to be folded back the other way.
Definition: WaveFolder.h:60
-
WaveFolder()
Constructor.
Definition: WaveFolder.h:43
-
A simple wavefolder.
Definition: WaveFolder.h:38
-
T next(T in)
Return the next folded sample.
Definition: WaveFolder.h:86
-
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:53
+
1 /*
+
2  * WaveFolder.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2022-2024 Thomas Combriat 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 WAVEFOLDER_H
+
13 #define WAVEFOLDER_H
+
14 
+
15 
+
16 #include "IntegerType.h"
+
17 #include "AudioOutput.h"
+
18 
+
19 
+
20 /*
+
21  A simple wavefolder which folds the waves once it reachs the up or
+
22  low limits. The wave can be folded several times. It constrains the wave
+
23  to be constrain between the LowLimit and the HighLimit.
+
24  By default, this class is working on data which not overflow the
+
25  AudioOutputStorage_t type, which is int by default.
+
26  Feeding samples which, before folding, are overflowing this container
+
27  will lead to unpredicted behavior.
+
28  It is possible to use a bigger type with the template formulation
+
29  if needed.
+
30 */
+
31 
+
32 
+
33 /** A simple wavefolder
+
34  */
+
35 
+
36 template<typename T=AudioOutputStorage_t>
+ +
38 {
+
39 public:
+
40  /** Constructor
+
41  */
+ +
43 
+
44 
+
45  /** Set the high limit where the wave will start to be folded back the other way.
+
46  @param highLimit the high limit used by the wavefolder.
+
47  */
+
48  void setHighLimit(T highLimit)
+
49  {
+
50  hl = highLimit;
+
51  R = hl-ll;
+
52  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
+
53  }
+
54 
+
55 
+
56  /** Set the low limit where the wave will start to be folded back the other way.
+
57  @param lowLimit the low limit used by the wavefolder.
+
58  */
+
59  void setLowLimit(T lowLimit)
+
60  {
+
61  ll = lowLimit;
+
62  R = hl-ll;
+
63  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
+
64  }
+
65 
+
66 
+
67  /** Set the low and the high limits at the same time.
+
68  @param lowLimit the low limit used by the wavefolder
+
69  @param highLimit the high limit used by the wavefolder
+
70  @note highLimit MUST be higher than lowLimit
+
71  */
+
72  void setLimits(T lowLimit, T highLimit)
+
73  {
+
74  hl = highLimit;
+
75  ll = lowLimit;
+
76  R = hl-ll;
+
77  Ri = NUMERATOR / (hl-ll); // calculated here to speed up next()
+
78  }
+
79 
+
80 
+
81  /** Return the next folded sample
+
82  @param in is the signal input.
+
83  @return the folded output.
+
84  */
+
85  T next(T in)
+
86  {
+
87  if (in > hl)
+
88  {
+
89  typename IntegerType<sizeof(T)>::unsigned_type sub = in-hl;
+
90  /* Instead of using a division, we multiply by the inverse.
+
91  As the inverse is necessary smaller than 1, in order to fit in an integer
+
92  we multiply it by NUMERATOR before computing the inverse.
+
93  The shift is equivalent to divide by the NUMERATOR:
+
94  q = sub / R = (sub * (NUMERATOR/R))/NUMERATOR with NUMERATOR/R = Ri
+
95  */
+
96  typename IntegerType<sizeof(T)>::unsigned_type q = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) sub*Ri) >> SHIFT;
+
97  typename IntegerType<sizeof(T)>::unsigned_type r = sub - q*R; // remainer
+
98  if (q&0b1) return ll+r; //odd
+
99  else return hl-r; // even
+
100 
+
101  }
+
102  else if (in < ll)
+
103  {
+
104  typename IntegerType<sizeof(T)>::unsigned_type sub = ll-in;
+
105  typename IntegerType<sizeof(T)>::unsigned_type q = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) sub*Ri) >> SHIFT;
+
106  typename IntegerType<sizeof(T)>::unsigned_type r = sub - q*R; // remainer
+
107  if (q&0b1) return hl-r;
+
108  else return ll+r;
+
109  }
+
110  else return in;
+
111  }
+
112 
+
113 private:
+
114  T hl;
+
115  T ll;
+
116  typename IntegerType<sizeof(T)>::unsigned_type R;
+
117  typename IntegerType<sizeof(T)>::unsigned_type Ri;
+
118  static const uint8_t SHIFT = (sizeof(T) << 3);
+
119  static const typename IntegerType<sizeof(T)>::unsigned_type NUMERATOR = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) 1<<(SHIFT))-1;
+
120 
+
121  // Slower (way slower, around 2.5 times) but more precise, kept in case we want to switch one day.
+
122  /* typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type Ri;
+
123  static const uint8_t SHIFT = 1+(sizeof(T) << 3);
+
124  static const typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type NUMERATOR = ((typename IntegerType<sizeof(T)+sizeof(T)>::unsigned_type) 1<<(SHIFT))-1;*/
+
125 
+
126 
+
127 };
+
128 
+
129 
+
130 #endif
diff --git a/extras/doc/html/_wave_packet_8h_source.html b/extras/doc/html/_wave_packet_8h_source.html index 328bc8ffd..021c2d735 100644 --- a/extras/doc/html/_wave_packet_8h_source.html +++ b/extras/doc/html/_wave_packet_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: WavePacket.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,30 +99,207 @@
WavePacket.h
-
1 /*
2  * WavePacket.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 
13 #ifndef WAVEPACKET_H
14 #define WAVEPACKET_H
15 
16 #include "MozziHeadersOnly.h"
17 #include "Oscil.h"
18 #include "tables/cos8192_int8.h"
19 #include "mozzi_fixmath.h"
20 #include "Phasor.h"
21 #include "Line.h"
22 #include "meta.h"
23 
24 
25 enum algorithms {SINGLE,DOUBLE};
26 
27 /**
28 Wavepacket synthesis, with two overlapping streams of wave packets. Draws on
29 Miller Puckette's Pure Data example, F14.wave.packet.pd. Each packet is an
30 enveloped grain of a sin (or cos) wave. The frequency of the wave, the width of
31 the envelopes and the rate of release of envelopes are the parameters which can
32 be changed.
33 @tparam ALGORITHM options are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
34 */
35 template <int8_t ALGORITHM>
37 {
38 public:
39 
40  /** Constructor.
41  */
43  {
44  aCos.setTable(COS8192_DATA);
45  }
46 
47 
48  /** Set all the parameters for the synthesis.
49  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
50  @param fundamental the rate at which packets are produced.
51  @param bandwidth the width of each packet. A lower value allows more
52  of the centre frequency to be audible, a rounder sound.
53  A higher value produces narrower packets, a more buzzing sound.
54  @param centrefreq the oscillation frequency within each packet.
55  */
56  inline
57  void set(int fundamental, int bandwidth, int centrefreq)
58  {
59  setFundamental(fundamental);
60  setBandwidth(bandwidth);
61  setCentreFreq(centrefreq);
62  }
63 
64 
65  /** Set the fundamental frequency.
66  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
67  @param fundamental the rate at which packets are produced.
68  */
69  inline
70  void setFundamental(int fundamental)
71  {
72  aPhasor.setFreq(fundamental);
73  invFreq = Q8n24_FIX1 / fundamental;
74  }
75 
76 
77 
78  /** Set the bandwidth.
79  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
80  @param bandwidth the width of each packet. A lower value allows more of the
81  centre frequency to be audible, a rounder sound.
82  A higher value produces narrower packets, a more buzzing sound.
83  */
84  inline
85  void setBandwidth(int bandwidth)
86  {
87  Q15n16 bw = invFreq*bandwidth;
88  bw >>= 9;
89  bw = max(bw, Q15n16_FIX1>>3);
90  aBandwidth.set(bw, AUDIO_STEPS_PER_CONTROL);
91  }
92 
93 
94 
95  /** Set the centre frequency.
96  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
97  @param centrefreq the oscillation frequency within each packet.
98  */
99  inline
100  void setCentreFreq(int centrefreq)
101  {
102  Q15n16 cf = invFreq * centrefreq;
103  cf >>= 3;
104  aCentrefreq.set(cf, AUDIO_STEPS_PER_CONTROL);
105  }
106 
107 
108 /** Calculate the next synthesised sample.
109 @return a full-scale 16 bit value, which needs to be scaled to suit your sketch. If you're using it straight as the sketch output,
110 then that will be yourThing.next()>>2 for HIFI 14 bit output, or >>8 for STANDARD 8+ bit output.
111 */
112  inline
113  int next()
114  {
115  gcentrefreq = aCentrefreq.next();
116  gbandwidth = aBandwidth.next();
117  int phase1 = aPhasor.next()>>16; // -0.5 to 0.5, 0n15
118  if (ALGORITHM == DOUBLE) {
119  return (signalPath(params1, phase1)+signalPath(params2, phase1+32768))>>1;
120  } else {
121  return signalPath(params1, phase1);
122  }
123  }
124 
125 
126 
127 private:
128  //Q15n16 fundamental; // range 4 to 6271 in pd patch, 13 integer bits
129  Q8n24 invFreq;
130  Q15n16 gcentrefreq; // range 0 to 3068, 12 integer bits
131  Q15n16 gbandwidth; // range 1 to 3068, 12 integer bits
132 
133  // Lines to interpolate controls at audio rate
134  Line <Q15n16> aCentrefreq;
135  Line <Q16n16> aBandwidth;
136  Line <Q16n16> aFreq;
137 
138  // different sets of params for each audio phase stream
139  struct parameters
140  {
141  int previous_phase;
142  Q15n16 centrefreq;
143  Q23n8 bandwidth;
144  }
145  params1,params2;
146 
147  // the number of audio steps the line has to take to reach the next control value
148  const unsigned int AUDIO_STEPS_PER_CONTROL;
149 
150  Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aCos;
151  Phasor <MOZZI_AUDIO_RATE> aPhasor;
152 
153 
154  inline
155  int signalPath(struct parameters &param, int phase) // 25us? * 2
156  {
157  //setPin13High();
158  int index;
159 
160  if(phase<param.previous_phase)
161  {
162  param.centrefreq = gcentrefreq>>8;
163  param.bandwidth = Q15n16_to_Q23n8(gbandwidth);
164  }
165  param.previous_phase = phase;
166 
167  // oscillation
168  index = (param.centrefreq * phase)>>16;
169  // hack to make peak in middle of packet, otherwise it centres around a zero-crossing..
170  index += COS8192_NUM_CELLS>>1;
171  index &= COS8192_NUM_CELLS-1;
172  int8_t sig1 = aCos.atIndex(index);
173 
174  // packet envelope
175  Q23n8 bwphase = (param.bandwidth * phase)>>8;
176  bwphase += COS8192_NUM_CELLS>>1;
177  index = constrain(bwphase, 0, (COS8192_NUM_CELLS-1));
178  uint8_t packet_width = 128 + aCos.atIndex(index);
179  // if (AUDIO_MODE == HIFI){
180  // return ((int) sig1 * packet_width)>>3; // scaled to fit HIFI updateAudio output
181  // }else{
182  // return ((int) sig1 * packet_width)>>8; // scaled to fit STANDARD updateAudio output
183  // }
184 
185  return ((int) sig1 * packet_width);
186  }
187 
188 };
189 
190 /** @example 06.Synthesis/WavePacket/WavePacket.ino
191 This is an example of how to use the WavePacket class.
192 */
193 
194 #endif // #ifndef WAVEPACKET_H
void setCentreFreq(int centrefreq)
Set the centre frequency.
Definition: WavePacket.h:100
-
#define MOZZI_CONTROL_RATE
Control rate setting.
-
int next()
Calculate the next synthesised sample.
Definition: WavePacket.h:113
-
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:38
-
WavePacket()
Constructor.
Definition: WavePacket.h:42
-
void set(int fundamental, int bandwidth, int centrefreq)
Set all the parameters for the synthesis.
Definition: WavePacket.h:57
-
void setFundamental(int fundamental)
Set the fundamental frequency.
Definition: WavePacket.h:70
-
For linear changes with a minimum of calculation at each step.
Definition: Line.h:33
-
#define Q15n16_FIX1
1 in Q15n16 format
Definition: mozzi_fixmath.h:61
-
void setBandwidth(int bandwidth)
Set the bandwidth.
Definition: WavePacket.h:85
-
Wavepacket synthesis, with two overlapping streams of wave packets.
Definition: WavePacket.h:36
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:44
-
uint32_t Q8n24
signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:42
-
#define Q8n24_FIX1
1 in Q8n24 format
Definition: mozzi_fixmath.h:62
-
int32_t Q23n8
signed fractional number using 23 integer bits and 8 fractional bits, represents -8388607.996 to 8388607.996
Definition: mozzi_fixmath.h:37
+
1 /*
+
2  * WavePacket.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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 
+
13 #ifndef WAVEPACKET_H
+
14 #define WAVEPACKET_H
+
15 
+
16 #include "MozziHeadersOnly.h"
+
17 #include "Oscil.h"
+
18 #include "tables/cos8192_int8.h"
+
19 #include "mozzi_fixmath.h"
+
20 #include "Phasor.h"
+
21 #include "Line.h"
+
22 #include "meta.h"
+
23 
+
24 
+
25 enum algorithms {SINGLE,DOUBLE};
+
26 
+
27 /**
+
28 Wavepacket synthesis, with two overlapping streams of wave packets. Draws on
+
29 Miller Puckette's Pure Data example, F14.wave.packet.pd. Each packet is an
+
30 enveloped grain of a sin (or cos) wave. The frequency of the wave, the width of
+
31 the envelopes and the rate of release of envelopes are the parameters which can
+
32 be changed.
+
33 @tparam ALGORITHM options are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
+
34 */
+
35 template <int8_t ALGORITHM>
+ +
37 {
+
38 public:
+
39 
+
40  /** Constructor.
+
41  */
+ +
43  {
+
44  aCos.setTable(COS8192_DATA);
+
45  }
+
46 
+
47 
+
48  /** Set all the parameters for the synthesis.
+
49  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
+
50  @param fundamental the rate at which packets are produced.
+
51  @param bandwidth the width of each packet. A lower value allows more
+
52  of the centre frequency to be audible, a rounder sound.
+
53  A higher value produces narrower packets, a more buzzing sound.
+
54  @param centrefreq the oscillation frequency within each packet.
+
55  */
+
56  inline
+
57  void set(int fundamental, int bandwidth, int centrefreq)
+
58  {
+
59  setFundamental(fundamental);
+
60  setBandwidth(bandwidth);
+
61  setCentreFreq(centrefreq);
+
62  }
+
63 
+
64 
+
65  /** Set the fundamental frequency.
+
66  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
+
67  @param fundamental the rate at which packets are produced.
+
68  */
+
69  inline
+
70  void setFundamental(int fundamental)
+
71  {
+
72  aPhasor.setFreq(fundamental);
+
73  invFreq = Q8n24_FIX1 / fundamental;
+
74  }
+
75 
+
76 
+
77 
+
78  /** Set the bandwidth.
+
79  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
+
80  @param bandwidth the width of each packet. A lower value allows more of the
+
81  centre frequency to be audible, a rounder sound.
+
82  A higher value produces narrower packets, a more buzzing sound.
+
83  */
+
84  inline
+
85  void setBandwidth(int bandwidth)
+
86  {
+
87  Q15n16 bw = invFreq*bandwidth;
+
88  bw >>= 9;
+
89  bw = max(bw, Q15n16_FIX1>>3);
+
90  aBandwidth.set(bw, AUDIO_STEPS_PER_CONTROL);
+
91  }
+
92 
+
93 
+
94 
+
95  /** Set the centre frequency.
+
96  The function is designed so that usable ranges for parameters can come from analog inputs, ie. 0-1023.
+
97  @param centrefreq the oscillation frequency within each packet.
+
98  */
+
99  inline
+
100  void setCentreFreq(int centrefreq)
+
101  {
+
102  Q15n16 cf = invFreq * centrefreq;
+
103  cf >>= 3;
+
104  aCentrefreq.set(cf, AUDIO_STEPS_PER_CONTROL);
+
105  }
+
106 
+
107 
+
108 /** Calculate the next synthesised sample.
+
109 @return a full-scale 16 bit value, which needs to be scaled to suit your sketch. If you're using it straight as the sketch output,
+
110 then that will be yourThing.next()>>2 for HIFI 14 bit output, or >>8 for STANDARD 8+ bit output.
+
111 */
+
112  inline
+
113  int next()
+
114  {
+
115  gcentrefreq = aCentrefreq.next();
+
116  gbandwidth = aBandwidth.next();
+
117  int phase1 = aPhasor.next()>>16; // -0.5 to 0.5, 0n15
+
118  if (ALGORITHM == DOUBLE) {
+
119  return (signalPath(params1, phase1)+signalPath(params2, phase1+32768))>>1;
+
120  } else {
+
121  return signalPath(params1, phase1);
+
122  }
+
123  }
+
124 
+
125 
+
126 
+
127 private:
+
128  //Q15n16 fundamental; // range 4 to 6271 in pd patch, 13 integer bits
+
129  Q8n24 invFreq;
+
130  Q15n16 gcentrefreq; // range 0 to 3068, 12 integer bits
+
131  Q15n16 gbandwidth; // range 1 to 3068, 12 integer bits
+
132 
+
133  // Lines to interpolate controls at audio rate
+
134  Line <Q15n16> aCentrefreq;
+
135  Line <Q16n16> aBandwidth;
+
136  Line <Q16n16> aFreq;
+
137 
+
138  // different sets of params for each audio phase stream
+
139  struct parameters
+
140  {
+
141  int previous_phase;
+
142  Q15n16 centrefreq;
+
143  Q23n8 bandwidth;
+
144  }
+
145  params1,params2;
+
146 
+
147  // the number of audio steps the line has to take to reach the next control value
+
148  const unsigned int AUDIO_STEPS_PER_CONTROL;
+
149 
+
150  Oscil <COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aCos;
+
151  Phasor <MOZZI_AUDIO_RATE> aPhasor;
+
152 
+
153 
+
154  inline
+
155  int signalPath(struct parameters &param, int phase) // 25us? * 2
+
156  {
+
157  //setPin13High();
+
158  int index;
+
159 
+
160  if(phase<param.previous_phase)
+
161  {
+
162  param.centrefreq = gcentrefreq>>8;
+
163  param.bandwidth = Q15n16_to_Q23n8(gbandwidth);
+
164  }
+
165  param.previous_phase = phase;
+
166 
+
167  // oscillation
+
168  index = (param.centrefreq * phase)>>16;
+
169  // hack to make peak in middle of packet, otherwise it centres around a zero-crossing..
+
170  index += COS8192_NUM_CELLS>>1;
+
171  index &= COS8192_NUM_CELLS-1;
+
172  int8_t sig1 = aCos.atIndex(index);
+
173 
+
174  // packet envelope
+
175  Q23n8 bwphase = (param.bandwidth * phase)>>8;
+
176  bwphase += COS8192_NUM_CELLS>>1;
+
177  index = constrain(bwphase, 0, (COS8192_NUM_CELLS-1));
+
178  uint8_t packet_width = 128 + aCos.atIndex(index);
+
179  // if (AUDIO_MODE == HIFI){
+
180  // return ((int) sig1 * packet_width)>>3; // scaled to fit HIFI updateAudio output
+
181  // }else{
+
182  // return ((int) sig1 * packet_width)>>8; // scaled to fit STANDARD updateAudio output
+
183  // }
+
184 
+
185  return ((int) sig1 * packet_width);
+
186  }
+
187 
+
188 };
+
189 
+
190 /** @example 06.Synthesis/WavePacket/WavePacket.ino
+
191 This is an example of how to use the WavePacket class.
+
192 */
+
193 
+
194 #endif // #ifndef WAVEPACKET_H
diff --git a/extras/doc/html/_wave_packet_sample_8h_source.html b/extras/doc/html/_wave_packet_sample_8h_source.html index 0420ac722..2bd1cacd0 100644 --- a/extras/doc/html/_wave_packet_sample_8h_source.html +++ b/extras/doc/html/_wave_packet_sample_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: WavePacketSample.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,18 +99,55 @@
WavePacketSample.h
-
1 /*
2  * WavePacketSample.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef WAVEPACKETSAMPLE_H
13 #define WAVEPACKETSAMPLE_H
14 
15 
16 #include "WavePacket.h"
17 /** A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains).
18 @tparam ALGORITHM options are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
19 
20 */
21 template <int8_t ALGORITHM>
22 class WavePacketSample: public WavePacket<ALGORITHM>
23 {
24 public:
25  /** Change the sound table which will be played. Needs to be 8192 cells long for now.
26  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
27  */
28  inline
29  void setTable(const int8_t * TABLE_NAME)
30  {
31  aWav.setTable(TABLE_NAME);
32  }
33 
34 private:
35  Oscil <8192, MOZZI_AUDIO_RATE> aWav;
36 };
37 
38 /** @example 06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino
39 This is an example of how to use the WavePacketSample class.
40 */
41 #endif // #ifndef WAVEPACKETSAMPLE_H
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played.
-
A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains...
-
Wavepacket synthesis, with two overlapping streams of wave packets.
Definition: WavePacket.h:36
+
1 /*
+
2  * WavePacketSample.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2013-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 
+
13 #ifndef WAVEPACKETSAMPLE_H
+
14 #define WAVEPACKETSAMPLE_H
+
15 
+
16 
+
17 #include "WavePacket.h"
+
18 /** A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains).
+
19 @tparam ALGORITHM options are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
+
20 
+
21 */
+
22 template <int8_t ALGORITHM>
+
23 class WavePacketSample: public WavePacket<ALGORITHM>
+
24 {
+
25 public:
+
26  /** Change the sound table which will be played. Needs to be 8192 cells long for now.
+
27  @param TABLE_NAME is the name of the array in the table ".h" file you're using.
+
28  */
+
29  inline
+
30  void setTable(const int8_t * TABLE_NAME)
+
31  {
+
32  aWav.setTable(TABLE_NAME);
+
33  }
+
34 
+
35 private:
+
36  Oscil <8192, MOZZI_AUDIO_RATE> aWav;
+
37 };
+
38 
+
39 /** @example 06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino
+
40 This is an example of how to use the WavePacketSample class.
+
41 */
+
42 #endif // #ifndef WAVEPACKETSAMPLE_H
diff --git a/extras/doc/html/_wave_shaper_8h_source.html b/extras/doc/html/_wave_shaper_8h_source.html index d3873b8de..2e7f8bd8b 100644 --- a/extras/doc/html/_wave_shaper_8h_source.html +++ b/extras/doc/html/_wave_shaper_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: WaveShaper.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,20 +99,116 @@
WaveShaper.h
-
1 /*
2  * WaveShaper.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef WAVESHAPER_H_
13 #define WAVESHAPER_H_
14 
15 #include "Arduino.h"
16 
17 /** WaveShaper maps values from its input to values in a table, which are returned as output.
18 @tparam T the type of numbers being input to be shaped, chosen to match the table.
19 */
20 
21 template <class T>
23  {}
24 ;
25 
26 
27 /** int8_t specialisation of WaveShaper template*/
28 template <>
29 class WaveShaper <char>
30 {
31 
32 public:
33  /** Constructor. Use the template parameter to set type of numbers being mapped. For
34  example, WaveShaper <int> myWaveShaper; makes a WaveShaper which uses ints.
35  @tparam T the type of numbers being input to be shaped, chosen to match the table.
36  @param TABLE_NAME the name of the table being used, which can be found in the
37  ".h" file containing the table. */
38  WaveShaper(const int8_t * TABLE_NAME):table(TABLE_NAME)
39  {
40  ;
41  }
42 
43 
44  /** Maps input to output, transforming it according to the table being used.
45  @param in the input signal. For flexibility, it's up to you to give the correct offset
46  to your input signal. So if you're mapping a signed 8-bit signal (such as the output of
47  an Oscil) into a 256 cell table centred around cell 128, add 128 to offset the
48  input value.
49  @return the shaped signal.
50  */
51  inline
53  {
54  return FLASH_OR_RAM_READ<const int8_t>(table + in);
55  }
56 
57 private:
58  const int8_t * table;
59 };
60 
61 
62 
63 /** int specialisation of WaveShaper template*/
64 template <>
65 class WaveShaper <int>
66 {
67 
68 public:
69  /** Constructor. Use the template parameter to set type of numbers being mapped. For
70  example, WaveShaper <int> myWaveShaper; makes a WaveShaper which uses ints.
71  @tparam T the type of numbers being input to be shaped, chosen to match the table.
72  @param TABLE_NAME the name of the table being used, which can be found in the
73  ".h" file containing the table. */
74  WaveShaper(const int16_t * TABLE_NAME):table(TABLE_NAME)
75  {
76  ;
77  }
78 
79 
80  /** Maps input to output, transforming it according to the table being used.
81  @param in the input signal. For flexibility, it's up to you to give the
82  correct offset to your input signal. So if you're mapping a signed 9-bit signal
83  (such as the sum of 2 8-bit Oscils) into a 512 cell table centred around
84  cell 256, add 256 to offset the input value. With a sigmoid table, this
85  may be useful for compressing a bigger signal into the -244 to 243
86  output range of Mozzi, rather than dividing the signal and returning a
87  int8_t from updateAudio().
88  @return the shaped signal.
89  */
90  inline
91  int next(int in)
92  {
93  return FLASH_OR_RAM_READ<const int16_t>(table + in);
94  }
95 
96 private:
97  const int16_t * table;
98 };
99 
100 /** @example 06.Synthesis/WaveShaper/WaveShaper.ino
101 This is an example of how to use the WaveShaper class.
102 */
103 #endif /* WAVESHAPER_H_ */
int8_t next(byte in)
Maps input to output, transforming it according to the table being used.
Definition: WaveShaper.h:52
-
WaveShaper maps values from its input to values in a table, which are returned as output...
Definition: WaveShaper.h:22
-
int next(int in)
Maps input to output, transforming it according to the table being used.
Definition: WaveShaper.h:91
-
WaveShaper(const int16_t *TABLE_NAME)
Constructor.
Definition: WaveShaper.h:74
-
WaveShaper(const int8_t *TABLE_NAME)
Constructor.
Definition: WaveShaper.h:38
+
1 /*
+
2  * WaveShaper.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 WAVESHAPER_H_
+
13 #define WAVESHAPER_H_
+
14 
+
15 #include "Arduino.h"
+
16 
+
17 /** WaveShaper maps values from its input to values in a table, which are returned as output.
+
18 @tparam T the type of numbers being input to be shaped, chosen to match the table.
+
19 */
+
20 
+
21 template <class T>
+ +
23  {}
+
24 ;
+
25 
+
26 
+
27 /** int8_t specialisation of WaveShaper template*/
+
28 template <>
+
29 class WaveShaper <char>
+
30 {
+
31 
+
32 public:
+
33  /** Constructor. Use the template parameter to set type of numbers being mapped. For
+
34  example, WaveShaper <int> myWaveShaper; makes a WaveShaper which uses ints.
+
35  @tparam T the type of numbers being input to be shaped, chosen to match the table.
+
36  @param TABLE_NAME the name of the table being used, which can be found in the
+
37  ".h" file containing the table. */
+
38  WaveShaper(const int8_t * TABLE_NAME):table(TABLE_NAME)
+
39  {
+
40  ;
+
41  }
+
42 
+
43 
+
44  /** Maps input to output, transforming it according to the table being used.
+
45  @param in the input signal. For flexibility, it's up to you to give the correct offset
+
46  to your input signal. So if you're mapping a signed 8-bit signal (such as the output of
+
47  an Oscil) into a 256 cell table centred around cell 128, add 128 to offset the
+
48  input value.
+
49  @return the shaped signal.
+
50  */
+
51  inline
+ +
53  {
+
54  return FLASH_OR_RAM_READ<const int8_t>(table + in);
+
55  }
+
56 
+
57 private:
+
58  const int8_t * table;
+
59 };
+
60 
+
61 
+
62 
+
63 /** int specialisation of WaveShaper template*/
+
64 template <>
+
65 class WaveShaper <int>
+
66 {
+
67 
+
68 public:
+
69  /** Constructor. Use the template parameter to set type of numbers being mapped. For
+
70  example, WaveShaper <int> myWaveShaper; makes a WaveShaper which uses ints.
+
71  @tparam T the type of numbers being input to be shaped, chosen to match the table.
+
72  @param TABLE_NAME the name of the table being used, which can be found in the
+
73  ".h" file containing the table. */
+
74  WaveShaper(const int16_t * TABLE_NAME):table(TABLE_NAME)
+
75  {
+
76  ;
+
77  }
+
78 
+
79 
+
80  /** Maps input to output, transforming it according to the table being used.
+
81  @param in the input signal. For flexibility, it's up to you to give the
+
82  correct offset to your input signal. So if you're mapping a signed 9-bit signal
+
83  (such as the sum of 2 8-bit Oscils) into a 512 cell table centred around
+
84  cell 256, add 256 to offset the input value. With a sigmoid table, this
+
85  may be useful for compressing a bigger signal into the -244 to 243
+
86  output range of Mozzi, rather than dividing the signal and returning a
+
87  int8_t from updateAudio().
+
88  @return the shaped signal.
+
89  */
+
90  inline
+
91  int next(int in)
+
92  {
+
93  return FLASH_OR_RAM_READ<const int16_t>(table + in);
+
94  }
+
95 
+
96 private:
+
97  const int16_t * table;
+
98 };
+
99 
+
100 /** @example 06.Synthesis/WaveShaper/WaveShaper.ino
+
101 This is an example of how to use the WaveShaper class.
+
102 */
+
103 #endif /* WAVESHAPER_H_ */
diff --git a/extras/doc/html/annotated.html b/extras/doc/html/annotated.html index c9eb93de9..69f24868c 100644 --- a/extras/doc/html/annotated.html +++ b/extras/doc/html/annotated.html @@ -1,9 +1,9 @@ - + - + Mozzi: Class List @@ -13,10 +13,6 @@ - @@ -37,13 +33,13 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -104,64 +100,62 @@
Here are the classes, structs, unions and interfaces with brief descriptions:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
[detail level 12]
 CADSRA simple ADSR envelope generator
 CAudioDelayAudio delay line for comb filter, flange, chorus and short echo effects
 CAudioDelayFeedbackAudio delay line with feedback for comb filter, flange, chorus and short echo effects
 CAutoMapAutomatically map an input value to an output range without knowing the precise range of inputs beforehand
 CAutoRangeKeeps a running calculation of the range of the input values it receives
 CCapPoll
-A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime
 CCircularBufferCircular buffer object
 CControlDelay
-Control-rate delay line for delaying control signals
 CDCfilter
-A DC-blocking filter useful for highlighting changes in control signals
 CEadExponential attack decay envelope
 CEventDelayA non-blocking replacement for Arduino's delay() function
 CInt2TypeEnables you to instantiate a template based on an integer value
 CIntegerType
 CIntegerType< 1 >
 CIntegerType< 2 >
 CIntegerType< 4 >
 CIntegerType< 8 >
 CIntMapA faster version of Arduino's map() function
 CLineFor linear changes with a minimum of calculation at each step
 CLine< unsigned char >
 CLine< unsigned int >
 CLine< unsigned long >
 CMetaOscilMetaOscil is a wrapper for several Oscil
 CMetronomeA metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat
 CMonoOutputThis struct encapsulates one frame of mono audio output
 CMultiResonantFilterA generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime
 COscil
-Oscil plays a wavetable, cycling through the table to generate an audio or control signal
 COverSampleEnables the resolution of analog inputs to be increased by oversampling and decimation
 CPDResonantPDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on https://en.wikipedia.org/wiki/Phase_distortion_synthesis
 CPhasorPhasor repeatedly generates a high resolution ramp at a variable frequency
 CPortamentoA simple portamento (pitch slide from one note to the next) effect, useful for note-based applications
 CRCpoll
-A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime
 CResonantFilterA generic resonant filter for audio signals
 CReverbTank
-A reverb which sounds like the inside of a tin can
 CRollingAverageCalculates a running average over a specified number of the most recent readings
 CRollingStatWARNING: this class is work in progress, don't use it yet
 CSampleSample is like Oscil, it plays a wavetable
 CSampleHuffmanA sample player for samples encoded with Huffman compression
 CSmoothA simple infinite impulse response low pass filter for smoothing control or audio signals
 CStackA simple stack, used internally for keeping track of analog input channels as they are read
 CStateVariable
-
-State Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and http://www.musicdsp.org/showone.php?id=142
 CStereoOutputThis struct encapsulates one frame of mono audio output
 CWaveFolderA simple wavefolder
 CWavePacket
-Wavepacket synthesis, with two overlapping streams of wave packets
 CWavePacketSampleA WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains)
 CWaveShaperWaveShaper maps values from its input to values in a table, which are returned as output
 CWaveShaper< char >Int8_t specialisation of WaveShaper template
 CWaveShaper< int >Int specialisation of WaveShaper template
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 NMozziPrivateREADME! This file is meant to be used as a template when adding support for a new platform
 CMozziRandPrivate
 CADSRA simple ADSR envelope generator
 CAudioDelayAudio delay line for comb filter, flange, chorus and short echo effects
 CAudioDelayFeedbackAudio delay line with feedback for comb filter, flange, chorus and short echo effects
 CAutoMapAutomatically map an input value to an output range without knowing the precise range of inputs beforehand
 CAutoRangeKeeps a running calculation of the range of the input values it receives
 CCapPollA class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime
 CCircularBufferCircular buffer object
 CControlDelayControl-rate delay line for delaying control signals
 CDCfilterA DC-blocking filter useful for highlighting changes in control signals
 CEadExponential attack decay envelope
 CEventDelayA non-blocking replacement for Arduino's delay() function
 CInt2TypeEnables you to instantiate a template based on an integer value
 CIntegerTypeProvides appropriate integer types that can bit the given number of bytes on this platform (at most 64)
 CIntegerType< 1 >
 CIntegerType< 2 >
 CIntegerType< 4 >
 CIntegerType< 8 >
 CIntMapA faster version of Arduino's map() function
 CLineFor linear changes with a minimum of calculation at each step
 CLine< SFix< NI, NF > >
 CLine< UFix< NI, NF > >
 CLine< unsigned char >
 CLine< unsigned int >
 CLine< unsigned long >
 CMetaOscilMetaOscil is a wrapper for several Oscil
 CMetronomeA metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat
 CMidiToFreqPrivate
 CMonoOutputThis struct encapsulates one frame of mono audio output
 CMultiResonantFilterA generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime
 COscilOscil plays a wavetable, cycling through the table to generate an audio or control signal
 COverSampleEnables the resolution of analog inputs to be increased by oversampling and decimation
 CPDResonantPDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on https://en.wikipedia.org/wiki/Phase_distortion_synthesis
 CPhasorPhasor repeatedly generates a high resolution ramp at a variable frequency
 CPortamentoA simple portamento (pitch slide from one note to the next) effect, useful for note-based applications
 CRCpollA class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime
 CResonantFilterA generic resonant filter for audio signals
 CReverbTankA reverb which sounds like the inside of a tin can
 CRollingAverageCalculates a running average over a specified number of the most recent readings
 CRollingStatWARNING: this class is work in progress, don't use it yet
 CSampleSample is like Oscil, it plays a wavetable
 CSampleHuffmanA sample player for samples encoded with Huffman compression
 CSmoothA simple infinite impulse response low pass filter for smoothing control or audio signals
 CSmooth< SFix< NI, NF > >
 CSmooth< UFix< NI, NF > >
 CStackA simple stack, used internally for keeping track of analog input channels as they are read
 CStateVariableState Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and
 CStereoOutputThis struct encapsulates one frame of mono audio output
 CWaveFolderA simple wavefolder
 CWavePacketWavepacket synthesis, with two overlapping streams of wave packets
 CWavePacketSampleA WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains)
 CWaveShaperWaveShaper maps values from its input to values in a table, which are returned as output
 CWaveShaper< char >Int8_t specialisation of WaveShaper template
 CWaveShaper< int >Int specialisation of WaveShaper template
@@ -169,9 +163,7 @@ diff --git a/extras/doc/html/annotated_dup.js b/extras/doc/html/annotated_dup.js index 27e8615fc..3f3e033bd 100644 --- a/extras/doc/html/annotated_dup.js +++ b/extras/doc/html/annotated_dup.js @@ -1,44 +1,52 @@ var annotated_dup = [ + [ "MozziPrivate", "namespace_mozzi_private.html", [ + [ "MozziRandPrivate", "class_mozzi_private_1_1_mozzi_rand_private.html", "class_mozzi_private_1_1_mozzi_rand_private" ] + ] ], [ "ADSR", "class_a_d_s_r.html", "class_a_d_s_r" ], [ "AudioDelay", "class_audio_delay.html", "class_audio_delay" ], [ "AudioDelayFeedback", "class_audio_delay_feedback.html", "class_audio_delay_feedback" ], - [ "AutoMap", "class_auto_map.html", "class_auto_map" ], - [ "AutoRange", "class_auto_range.html", "class_auto_range" ], + [ "AutoMap", "group__sensortools.html#class_auto_map", "group__sensortools_class_auto_map" ], + [ "AutoRange", "group__sensortools.html#class_auto_range", "group__sensortools_class_auto_range" ], [ "CapPoll", "class_cap_poll.html", "class_cap_poll" ], [ "CircularBuffer", "class_circular_buffer.html", "class_circular_buffer" ], [ "ControlDelay", "class_control_delay.html", "class_control_delay" ], [ "DCfilter", "class_d_cfilter.html", "class_d_cfilter" ], [ "Ead", "class_ead.html", "class_ead" ], [ "EventDelay", "class_event_delay.html", "class_event_delay" ], - [ "Int2Type", "group__util.html#struct_int2_type", "group__util_struct_int2_type" ], - [ "IntegerType", "struct_integer_type.html", "struct_integer_type" ], + [ "Int2Type", "group__util.html#struct_int2_type", null ], + [ "IntegerType", "group__util.html#struct_integer_type", "group__util_struct_integer_type" ], [ "IntegerType< 1 >", "struct_integer_type_3_011_01_4.html", "struct_integer_type_3_011_01_4" ], [ "IntegerType< 2 >", "struct_integer_type_3_012_01_4.html", "struct_integer_type_3_012_01_4" ], [ "IntegerType< 4 >", "struct_integer_type_3_014_01_4.html", "struct_integer_type_3_014_01_4" ], [ "IntegerType< 8 >", "struct_integer_type_3_018_01_4.html", "struct_integer_type_3_018_01_4" ], [ "IntMap", "class_int_map.html", "class_int_map" ], [ "Line", "class_line.html", "class_line" ], + [ "Line< SFix< NI, NF > >", "class_line_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html", "class_line_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4" ], + [ "Line< UFix< NI, NF > >", "class_line_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html", "class_line_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4" ], [ "Line< unsigned char >", "class_line_3_01unsigned_01char_01_4.html", "class_line_3_01unsigned_01char_01_4" ], [ "Line< unsigned int >", "class_line_3_01unsigned_01int_01_4.html", "class_line_3_01unsigned_01int_01_4" ], [ "Line< unsigned long >", "class_line_3_01unsigned_01long_01_4.html", "class_line_3_01unsigned_01long_01_4" ], [ "MetaOscil", "class_meta_oscil.html", "class_meta_oscil" ], [ "Metronome", "class_metronome.html", "class_metronome" ], + [ "MidiToFreqPrivate", "class_midi_to_freq_private.html", "class_midi_to_freq_private" ], [ "MonoOutput", "struct_mono_output.html", "struct_mono_output" ], [ "MultiResonantFilter", "class_multi_resonant_filter.html", "class_multi_resonant_filter" ], [ "Oscil", "class_oscil.html", "class_oscil" ], - [ "OverSample", "class_over_sample.html", "class_over_sample" ], + [ "OverSample", "group__sensortools.html#class_over_sample", "group__sensortools_class_over_sample" ], [ "PDResonant", "class_p_d_resonant.html", "class_p_d_resonant" ], [ "Phasor", "class_phasor.html", "class_phasor" ], [ "Portamento", "class_portamento.html", "class_portamento" ], [ "RCpoll", "class_r_cpoll.html", "class_r_cpoll" ], [ "ResonantFilter", "class_resonant_filter.html", "class_resonant_filter" ], [ "ReverbTank", "class_reverb_tank.html", "class_reverb_tank" ], - [ "RollingAverage", "class_rolling_average.html", "class_rolling_average" ], - [ "RollingStat", "class_rolling_stat.html", "class_rolling_stat" ], + [ "RollingAverage", "group__sensortools.html#class_rolling_average", "group__sensortools_class_rolling_average" ], + [ "RollingStat", "group__sensortools.html#class_rolling_stat", "group__sensortools_class_rolling_stat" ], [ "Sample", "class_sample.html", "class_sample" ], [ "SampleHuffman", "class_sample_huffman.html", "class_sample_huffman" ], [ "Smooth", "class_smooth.html", "class_smooth" ], + [ "Smooth< SFix< NI, NF > >", "class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html", "class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4" ], + [ "Smooth< UFix< NI, NF > >", "class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html", "class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4" ], [ "Stack", "class_stack.html", "class_stack" ], [ "StateVariable", "class_state_variable.html", "class_state_variable" ], [ "StereoOutput", "struct_stereo_output.html", "struct_stereo_output" ], diff --git a/extras/doc/html/audio2huff_8py_source.html b/extras/doc/html/audio2huff_8py_source.html index 20cbaf58c..883a4e542 100644 --- a/extras/doc/html/audio2huff_8py_source.html +++ b/extras/doc/html/audio2huff_8py_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: audio2huff.py Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,150 @@
audio2huff.py
-
1 #! /usr/bin/python
2 #
3 # Generator for compressed Arduino audio data
4 # Thomas Grill, 2011
5 # http://grrrr.org
6 #
7 # Modified by TIm Barrass 2013
8 # - changed PROGMEM to CONSTTABLE_STORAGE, to stop compiler warning
9 # - moved huffman table to progmem
10 # - added --name argument to give all constants specific names
11 # - changed all constant names to upper case
12 # - added include guards, Arduino and avr includes
13 #
14 # Dependencies:
15 # Numerical Python (numpy): http://numpy.scipy.org/
16 # scikits.audiolab: http://pypi.python.org/pypi/scikits.audiolab/
17 # purehuff: https://grrrr.org/data/dev/purehuff/
18 # pylab / matplotlib (only for plotting): http://matplotlib.sourceforge.net/
19 #
20 # NOTE: the scikits.audiolab dependency requires Python 2!
21 # see https://github.com/Roger-random/mozzi_wilhelm/issues/1#issuecomment-770141226
22 #
23 #For help on options invoke with:
24 # audio2huff --help
25 
26 import sys,os.path
27 from itertools import imap,chain,izip
28 
29 try:
30  import numpy as N
31 except ImportError:
32  print >>sys.stderr, "Error: Numerical Python not found"
33  exit(-1)
34 
35 try:
36  from scikits.audiolab import Sndfile
37 except ImportError:
38  print >>sys.stderr, "Error: scikits.audiolab not found"
39  exit(-1)
40 
41 try:
42  import purehuff
43 except ImportError:
44  print >>sys.stderr, "Error: purehuff module not found"
45  exit(-1)
46 
47 def grouper(n,seq):
48  """group list elements"""
49  it = iter(seq)
50  while True:
51  l = [v for _,v in izip(xrange(n),it)]
52  if l:
53  yield l
54  if len(l) < n:
55  break
56 
57 def arrayformatter(seq,perline=40):
58  """format list output linewise"""
59  return ",\n".join(",".join(imap(str,s)) for s in grouper(perline,seq))
60 
61 if __name__ == "__main__":
62  from optparse import OptionParser
63  parser = OptionParser()
64  parser.add_option("--bits", type="int", default=8, dest="bits",help="bit resolution")
65  parser.add_option("--sndfile", dest="sndfile",help="input sound file")
66  parser.add_option("--hdrfile", dest="hdrfile",help="output C header file")
67  parser.add_option("--name", dest="name",help="prefix for tables and constants in file")
68  parser.add_option("--plothist", type="int", default=0, dest="plothist",help="plot histogram")
69  (options, args) = parser.parse_args()
70 
71  if not options.sndfile:
72  print >>sys.stderr,"Error: --sndfile argument required"
73  exit(-1)
74 
75  sndf = Sndfile(options.sndfile,'r')
76  sound = sndf.read_frames(sndf.nframes)
77  fs = sndf.samplerate
78  del sndf
79 
80  # mix down multi-channel audio
81  if len(sound.shape) > 1:
82  sound = N.mean(sound,axis=1)
83 
84  # convert to n bits (no dithering, except it has already been done with the same bit resolution for the soundfile)
85  sound8 = N.clip((sound*(2**(options.bits-1))).astype(int),-2**(options.bits-1),2**(options.bits-1)-1)
86  # the following mapping with int is necessary as numpy.int32 types are not digested well by the HuffmanTree class
87  dsound8 = map(int,chain((sound8[0],),imap(lambda x: x[1]-x[0],izip(sound8[:-1],sound8[1:]))))
88 
89  print >>sys.stderr,"min/max: %i/%i"%(N.min(sound8),N.max(sound8))
90  print >>sys.stderr,"data bits: %i"%(len(sound8)*options.bits)
91 
92  hist = purehuff.histogram(dsound8)
93 
94  if options.plothist:
95  try:
96  import pylab as P
97  except ImportError:
98  print >>sys.stderr, "Plotting needs pylab"
99 
100  from collections import defaultdict
101  d = defaultdict(float)
102  for n,v in hist:
103  d[v] += n
104  x = range(min(d.iterkeys()),max(d.iterkeys())+1)
105  y = [d[xi] for xi in x]
106 
107  P.title("Histogram of sample differentials, file %s"%os.path.split(options.sndfile)[-1])
108  P.plot(x,y,marker='x')
109  P.show()
110 
111  hufftree = purehuff.HuffTree(hist)
112 
113  # get decoder instance
114  decoder = hufftree.decoder()
115  # get encoder instance
116  encoder = hufftree.encoder()
117  # encode data
118  enc = encoder(dsound8)
119 
120  print >>sys.stderr,"encoded bits: %i"%len(enc)
121  print >>sys.stderr,"ratio: %.0f%%"%((len(enc)*100.)/(len(sound8)*8))
122  print >>sys.stderr,"decoder length: %.0f words"%(len(decoder.huff))
123 
124  if options.hdrfile:
125  hdrf = file(options.hdrfile,'wt')
126  print >>hdrf,"// generated by Mozzi/extras/python/audio2huff.py \n"
127  print >>hdrf,"#ifndef " + options.name + "_H_"
128  print >>hdrf,"#define " + options.name + "_H_\n"
129  print >>hdrf,'#if ARDUINO >= 100'
130  print >>hdrf,'#include <Arduino.h>\n'
131  print >>hdrf,'#include "mozzi_pgmspace.h"\n \n'
132  print >>hdrf,"#define " + options.name + "_SAMPLERATE %i"%fs
133  print >>hdrf,"#define " + options.name + "_SAMPLE_BITS %i"%options.bits
134  print >>hdrf,'CONSTTABLE_STORAGE(int) ' + options.name + '_HUFFMAN[%i] = {\n%s\n};'%(len(decoder.huff),arrayformatter(decoder.huff))
135  print >>hdrf,'unsigned long const ' + options.name + '_SOUNDDATA_BITS = %iL;'%len(enc)
136  print >>hdrf,'CONSTTABLE_STORAGE(unsigned char) ' + options.name + '_SOUNDDATA[] = {\n%s\n};'%arrayformatter(enc.data)
137  print >>hdrf,"#endif /* " + options.name + "_H_ */"
+
1 #! /usr/bin/python
+
2 #
+
3 # Generator for compressed Arduino audio data
+
4 # Thomas Grill, 2011
+
5 # http://grrrr.org
+
6 #
+
7 # Modified by TIm Barrass 2013
+
8 # - changed PROGMEM to CONSTTABLE_STORAGE, to stop compiler warning
+
9 # - moved huffman table to progmem
+
10 # - added --name argument to give all constants specific names
+
11 # - changed all constant names to upper case
+
12 # - added include guards, Arduino and avr includes
+
13 #
+
14 # Dependencies:
+
15 # Numerical Python (numpy): http://numpy.scipy.org/
+
16 # scikits.audiolab: http://pypi.python.org/pypi/scikits.audiolab/
+
17 # purehuff: https://grrrr.org/data/dev/purehuff/
+
18 # pylab / matplotlib (only for plotting): http://matplotlib.sourceforge.net/
+
19 #
+
20 # NOTE: the scikits.audiolab dependency requires Python 2!
+
21 # see https://github.com/Roger-random/mozzi_wilhelm/issues/1#issuecomment-770141226
+
22 #
+
23 #For help on options invoke with:
+
24 # audio2huff --help
+
25 
+
26 import sys,os.path
+
27 from itertools import imap,chain,izip
+
28 
+
29 try:
+
30  import numpy as N
+
31 except ImportError:
+
32  print >>sys.stderr, "Error: Numerical Python not found"
+
33  exit(-1)
+
34 
+
35 try:
+
36  from scikits.audiolab import Sndfile
+
37 except ImportError:
+
38  print >>sys.stderr, "Error: scikits.audiolab not found"
+
39  exit(-1)
+
40 
+
41 try:
+
42  import purehuff
+
43 except ImportError:
+
44  print >>sys.stderr, "Error: purehuff module not found"
+
45  exit(-1)
+
46 
+
47 def grouper(n,seq):
+
48  """group list elements"""
+
49  it = iter(seq)
+
50  while True:
+
51  l = [v for _,v in izip(xrange(n),it)]
+
52  if l:
+
53  yield l
+
54  if len(l) < n:
+
55  break
+
56 
+
57 def arrayformatter(seq,perline=40):
+
58  """format list output linewise"""
+
59  return ",\n".join(",".join(imap(str,s)) for s in grouper(perline,seq))
+
60 
+
61 if __name__ == "__main__":
+
62  from optparse import OptionParser
+
63  parser = OptionParser()
+
64  parser.add_option("--bits", type="int", default=8, dest="bits",help="bit resolution")
+
65  parser.add_option("--sndfile", dest="sndfile",help="input sound file")
+
66  parser.add_option("--hdrfile", dest="hdrfile",help="output C header file")
+
67  parser.add_option("--name", dest="name",help="prefix for tables and constants in file")
+
68  parser.add_option("--plothist", type="int", default=0, dest="plothist",help="plot histogram")
+
69  (options, args) = parser.parse_args()
+
70 
+
71  if not options.sndfile:
+
72  print >>sys.stderr,"Error: --sndfile argument required"
+
73  exit(-1)
+
74 
+
75  sndf = Sndfile(options.sndfile,'r')
+
76  sound = sndf.read_frames(sndf.nframes)
+
77  fs = sndf.samplerate
+
78  del sndf
+
79 
+
80  # mix down multi-channel audio
+
81  if len(sound.shape) > 1:
+
82  sound = N.mean(sound,axis=1)
+
83 
+
84  # convert to n bits (no dithering, except it has already been done with the same bit resolution for the soundfile)
+
85  sound8 = N.clip((sound*(2**(options.bits-1))).astype(int),-2**(options.bits-1),2**(options.bits-1)-1)
+
86  # the following mapping with int is necessary as numpy.int32 types are not digested well by the HuffmanTree class
+
87  dsound8 = map(int,chain((sound8[0],),imap(lambda x: x[1]-x[0],izip(sound8[:-1],sound8[1:]))))
+
88 
+
89  print >>sys.stderr,"min/max: %i/%i"%(N.min(sound8),N.max(sound8))
+
90  print >>sys.stderr,"data bits: %i"%(len(sound8)*options.bits)
+
91 
+
92  hist = purehuff.histogram(dsound8)
+
93 
+
94  if options.plothist:
+
95  try:
+
96  import pylab as P
+
97  except ImportError:
+
98  print >>sys.stderr, "Plotting needs pylab"
+
99 
+
100  from collections import defaultdict
+
101  d = defaultdict(float)
+
102  for n,v in hist:
+
103  d[v] += n
+
104  x = range(min(d.iterkeys()),max(d.iterkeys())+1)
+
105  y = [d[xi] for xi in x]
+
106 
+
107  P.title("Histogram of sample differentials, file %s"%os.path.split(options.sndfile)[-1])
+
108  P.plot(x,y,marker='x')
+
109  P.show()
+
110 
+
111  hufftree = purehuff.HuffTree(hist)
+
112 
+
113  # get decoder instance
+
114  decoder = hufftree.decoder()
+
115  # get encoder instance
+
116  encoder = hufftree.encoder()
+
117  # encode data
+
118  enc = encoder(dsound8)
+
119 
+
120  print >>sys.stderr,"encoded bits: %i"%len(enc)
+
121  print >>sys.stderr,"ratio: %.0f%%"%((len(enc)*100.)/(len(sound8)*8))
+
122  print >>sys.stderr,"decoder length: %.0f words"%(len(decoder.huff))
+
123 
+
124  if options.hdrfile:
+
125  hdrf = file(options.hdrfile,'wt')
+
126  print >>hdrf,"// generated by Mozzi/extras/python/audio2huff.py \n"
+
127  print >>hdrf,"#ifndef " + options.name + "_H_"
+
128  print >>hdrf,"#define " + options.name + "_H_\n"
+
129  print >>hdrf,'#if ARDUINO >= 100'
+
130  print >>hdrf,'#include <Arduino.h>\n'
+
131  print >>hdrf,'#include "mozzi_pgmspace.h"\n \n'
+
132  print >>hdrf,"#define " + options.name + "_SAMPLERATE %i"%fs
+
133  print >>hdrf,"#define " + options.name + "_SAMPLE_BITS %i"%options.bits
+
134  print >>hdrf,'CONSTTABLE_STORAGE(int) ' + options.name + '_HUFFMAN[%i] = {\n%s\n};'%(len(decoder.huff),arrayformatter(decoder.huff))
+
135  print >>hdrf,'unsigned long const ' + options.name + '_SOUNDDATA_BITS = %iL;'%len(enc)
+
136  print >>hdrf,'CONSTTABLE_STORAGE(unsigned char) ' + options.name + '_SOUNDDATA[] = {\n%s\n};'%arrayformatter(enc.data)
+
137  print >>hdrf,"#endif /* " + options.name + "_H_ */"
+
diff --git a/extras/doc/html/blahblah4b__int8_8h_source.html b/extras/doc/html/blahblah4b__int8_8h_source.html index 7e969d435..27e697d70 100644 --- a/extras/doc/html/blahblah4b__int8_8h_source.html +++ b/extras/doc/html/blahblah4b__int8_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: blahblah4b_int8.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,1223 @@
blahblah4b_int8.h
-
1 #ifndef BLAHBLAH4B_H_
2 #define BLAHBLAH4B_H_
3 
4 #include <Arduino.h>
5 #include "mozzi_pgmspace.h"
6 
7 #define BLAHBLAH4B_NUM_CELLS 22569
8 #define BLAHBLAH4B_SAMPLERATE 16384
9 
10 CONSTTABLE_STORAGE(int8_t) BLAHBLAH4B_DATA [] = { -1, 2, 6, 9, 12, 15, 17, 20, 22, 25, 28, 30,
11 32, 34, 37, 38, 40, 42, 44, 46, 47, 49, 50, 52, 53, 53, 54, 55, 55, 55, 54, 54,
12 53, 51, 48, 46, 42, 38, 34, 29, 25, 20, 15, 10, 5, -1, -6, -11, -16, -21, -25,
13 -29, -33, -37, -40, -43, -47, -50, -52, -55, -57, -58, -59, -59, -59, -59, -58,
14 -57, -56, -55, -54, -53, -51, -50, -48, -45, -42, -39, -35, -32, -27, -23, -18,
15 -14, -9, -5, -1, 3, 7, 10, 13, 16, 19, 22, 25, 28, 30, 33, 36, 38, 40, 43, 45,
16 47, 49, 51, 53, 54, 56, 57, 57, 58, 58, 58, 58, 58, 57, 56, 55, 52, 49, 46, 41,
17 37, 33, 28, 23, 17, 12, 7, 1, -5, -10, -15, -20, -25, -30, -34, -38, -42, -46,
18 -49, -52, -55, -57, -59, -61, -62, -63, -62, -62, -61, -60, -59, -58, -57, -56,
19 -54, -52, -51, -48, -45, -42, -38, -34, -31, -26, -22, -18, -13, -9, -5, -1, 3,
20 6, 9, 12, 15, 18, 21, 24, 27, 29, 32, 34, 37, 39, 41, 43, 45, 47, 49, 51, 53,
21 55, 56, 57, 59, 59, 59, 59, 58, 58, 57, 55, 53, 50, 47, 43, 38, 34, 29, 24, 19,
22 15, 9, 4, -2, -8, -13, -18, -24, -28, -32, -37, -40, -44, -47, -50, -54, -56,
23 -59, -61, -62, -64, -64, -64, -63, -62, -61, -60, -58, -58, -57, -55, -53, -50,
24 -48, -45, -42, -39, -35, -31, -27, -22, -22, -17, -8, -2, 4, 8, 12, 14, 17, 21,
25 23, 25, 28, 30, 32, 36, 39, 42, 44, 45, 46, 48, 50, 51, 53, 54, 56, 58, 58, 60,
26 60, 59, 59, 57, 55, 53, 51, 49, 46, 42, 39, 35, 29, 24, 19, 13, 8, 2, -4, -10,
27 -15, -20, -27, -31, -33, -39, -41, -45, -49, -50, -55, -56, -59, -61, -62, -64,
28 -64, -63, -62, -61, -59, -58, -54, -52, -50, -47, -44, -42, -42, -41, -39, -37,
29 -35, -34, -33, -30, -23, -15, -8, -2, 4, 6, 8, 11, 13, 16, 22, 26, 27, 27, 27,
30 28, 29, 29, 30, 33, 36, 40, 44, 47, 49, 49, 48, 48, 47, 46, 47, 48, 51, 53, 55,
31 56, 57, 56, 53, 49, 43, 39, 34, 30, 26, 22, 19, 17, 14, 9, 3, -2, -8, -14, -22,
32 -28, -32, -36, -38, -39, -41, -41, -43, -46, -49, -52, -55, -58, -60, -61, -59,
33 -58, -57, -55, -52, -50, -51, -51, -50, -49, -48, -47, -46, -42, -37, -34, -29,
34 -24, -20, -16, -12, -10, -7, -3, 0, 3, 6, 10, 14, 17, 20, 23, 26, 28, 29, 31,
35 33, 35, 36, 39, 42, 44, 47, 48, 50, 52, 53, 53, 54, 54, 55, 56, 56, 56, 56, 56,
36 54, 51, 47, 42, 37, 33, 29, 24, 19, 15, 10, 6, 0, -5, -10, -15, -21, -27, -33,
37 -37, -40, -42, -45, -48, -48, -50, -53, -55, -56, -57, -59, -60, -60, -58, -57,
38 -56, -55, -53, -52, -54, -53, -49, -48, -46, -48, -48, -48, -52, -43, -28, -21,
39 -14, -17, -20, -9, 0, 7, 14, 14, 13, 15, 21, 29, 34, 33, 32, 32, 32, 37, 44, 46,
40 46, 46, 45, 46, 49, 55, 56, 55, 55, 51, 49, 52, 54, 57, 58, 56, 55, 54, 52, 50,
41 48, 44, 35, 28, 23, 17, 13, 10, 5, -2, -11, -20, -26, -27, -33, -41, -44, -51,
42 -59, -62, -64, -65, -65, -66, -68, -70, -68, -67, -66, -63, -65, -59, -54, -57,
43 -52, -41, -38, -41, -43, -38, -32, -32, -31, -27, -23, -20, -23, -24, -12, -3,
44 0, 7, 11, 11, 14, 13, 17, 22, 16, 15, 20, 23, 28, 34, 38, 43, 40, 37, 37, 38,
45 44, 47, 47, 48, 47, 48, 51, 53, 57, 56, 54, 55, 56, 55, 55, 54, 54, 50, 43, 40,
46 39, 36, 32, 26, 16, 7, 0, -7, -14, -19, -23, -29, -38, -47, -52, -60, -65, -72,
47 -80, -84, -86, -87, -85, -86, -83, -84, -86, -82, -79, -73, -64, -57, -41, -30,
48 -32, -27, -15, -5, -6, -10, 0, 12, 16, 15, 19, 30, 33, 28, 29, 31, 31, 31, 21,
49 17, 17, 15, 18, 19, 22, 20, 17, 19, 19, 17, 14, 8, 8, 11, 11, 10, 8, 15, 21, 16,
50 10, 15, 24, 23, 18, 24, 30, 29, 30, 35, 37, 36, 37, 38, 40, 40, 37, 40, 43, 40,
51 34, 30, 27, 26, 19, 13, 9, 4, -1, -9, -15, -18, -28, -34, -37, -48, -54, -58,
52 -61, -60, -67, -71, -72, -72, -70, -77, -76, -70, -69, -68, -66, -60, -52, -42,
53 -33, -35, -32, -20, -14, -14, -15, -6, 6, 8, 7, 13, 22, 28, 26, 29, 36, 32, 32,
54 37, 40, 41, 39, 42, 48, 46, 42, 36, 33, 34, 30, 26, 23, 22, 26, 25, 19, 14, 16,
55 21, 13, 9, 16, 19, 16, 13, 18, 21, 14, 17, 21, 20, 20, 21, 27, 31, 26, 26, 26,
56 25, 24, 20, 18, 16, 14, 11, 5, 3, 0, -7, -10, -16, -20, -28, -33, -33, -39, -43,
57 -50, -53, -51, -58, -61, -60, -61, -61, -62, -63, -60, -60, -58, -53, -53, -52,
58 -48, -37, -25, -25, -24, -11, -1, -1, -3, 2, 13, 17, 18, 19, 24, 33, 36, 37, 38,
59 38, 37, 38, 39, 39, 39, 41, 41, 39, 38, 33, 29, 28, 25, 23, 18, 16, 18, 18, 14,
60 8, 4, 9, 14, 6, 1, 10, 18, 14, 8, 11, 16, 15, 15, 18, 19, 21, 25, 28, 31, 28,
61 23, 25, 28, 23, 15, 12, 19, 20, 10, 3, 1, -2, -7, -16, -22, -27, -30, -31, -37,
62 -46, -51, -52, -53, -57, -63, -66, -64, -62, -63, -65, -65, -61, -57, -56, -57,
63 -54, -51, -46, -40, -35, -24, -17, -15, -5, 4, 7, 2, 5, 20, 27, 24, 25, 31, 43,
64 46, 39, 39, 44, 44, 41, 38, 40, 42, 42, 43, 39, 35, 31, 26, 24, 23, 18, 14, 12,
65 13, 13, 8, 2, 4, 11, 8, -2, 1, 10, 10, 6, 6, 11, 11, 10, 12, 14, 17, 18, 20, 26,
66 26, 21, 20, 24, 24, 15, 10, 13, 15, 9, 3, 3, 0, -7, -13, -18, -21, -29, -34,
67 -32, -37, -46, -49, -49, -50, -56, -59, -59, -61, -59, -58, -59, -57, -54, -51,
68 -50, -49, -47, -42, -38, -36, -34, -24, -10, -11, -9, 3, 12, 13, 7, 14, 28, 30,
69 29, 30, 39, 48, 44, 44, 50, 49, 45, 43, 43, 44, 41, 39, 41, 38, 35, 29, 23, 23,
70 20, 14, 8, 4, 4, 6, 1, -2, 0, 5, 1, -5, -2, 2, 2, 1, 4, 8, 8, 8, 13, 16, 18, 17,
71 20, 26, 25, 21, 21, 23, 22, 17, 13, 14, 12, 9, 6, 3, -1, -8, -13, -14, -20, -29,
72 -32, -30, -36, -47, -45, -46, -51, -52, -55, -54, -55, -56, -53, -54, -52, -49,
73 -49, -44, -43, -42, -35, -34, -32, -27, -25, -15, -1, -3, -3, 8, 18, 17, 10, 18,
74 30, 30, 31, 29, 35, 45, 42, 40, 44, 43, 39, 37, 38, 38, 33, 34, 33, 30, 29, 22,
75 17, 17, 15, 11, 4, 0, 1, 4, 3, -4, -4, 5, 4, -4, -3, 4, 6, 5, 5, 11, 13, 13, 16,
76 19, 22, 19, 19, 27, 26, 20, 18, 21, 22, 16, 11, 8, 8, 7, -1, -6, -9, -16, -19,
77 -21, -27, -36, -38, -35, -43, -50, -47, -50, -53, -51, -52, -54, -54, -51, -47,
78 -48, -48, -44, -41, -36, -36, -36, -29, -27, -23, -19, -19, -13, 1, 8, 2, 4, 16,
79 22, 17, 15, 24, 32, 32, 28, 30, 38, 39, 34, 36, 41, 35, 29, 31, 32, 30, 25, 22,
80 23, 22, 18, 12, 10, 11, 8, 3, -1, -4, -2, 3, 0, -2, 3, 6, 3, 2, 6, 8, 7, 8, 13,
81 17, 17, 16, 22, 25, 23, 19, 21, 24, 19, 15, 16, 17, 12, 6, 5, 5, 0, -10, -11,
82 -9, -17, -26, -29, -28, -32, -40, -41, -41, -45, -46, -47, -50, -50, -50, -49,
83 -48, -49, -45, -42, -41, -37, -36, -34, -32, -30, -25, -22, -20, -17, -14, -5,
84 9, 6, 0, 11, 21, 22, 12, 13, 28, 32, 28, 24, 26, 35, 34, 30, 33, 34, 30, 29, 30,
85 29, 25, 21, 23, 22, 20, 16, 10, 13, 14, 9, 3, -3, -2, 3, 2, -4, -4, 7, 9, 0, -1,
86 5, 7, 4, 5, 10, 13, 13, 14, 18, 21, 18, 15, 21, 24, 16, 13, 14, 18, 14, 6, 3, 6,
87 5, -6, -7, -4, -14, -20, -17, -21, -31, -35, -29, -33, -39, -37, -40, -43, -39,
88 -43, -46, -42, -42, -41, -36, -36, -35, -32, -28, -29, -31, -25, -22, -23, -18,
89 -16, -16, -4, 6, -1, -2, 8, 13, 11, 6, 10, 20, 22, 19, 14, 20, 27, 22, 21, 28,
90 26, 22, 25, 24, 22, 21, 16, 16, 17, 15, 11, 9, 12, 11, 7, 2, -2, -1, 4, 3, -2,
91 3, 9, 8, 6, 4, 8, 12, 11, 9, 14, 19, 18, 19, 24, 26, 22, 22, 28, 27, 21, 19, 21,
92 22, 17, 9, 9, 11, 5, -3, -2, -2, -11, -18, -15, -20, -32, -32, -30, -35, -38,
93 -38, -40, -42, -42, -43, -46, -44, -41, -41, -38, -37, -37, -33, -31, -31, -30,
94 -27, -25, -25, -20, -19, -20, -16, -3, 2, -6, -4, 5, 12, 7, 0, 9, 19, 18, 13,
95 11, 19, 22, 19, 20, 23, 22, 22, 23, 22, 23, 18, 16, 18, 16, 15, 12, 11, 14, 13,
96 11, 5, 2, 5, 9, 7, 8, 12, 13, 14, 14, 13, 14, 15, 19, 21, 23, 24, 23, 28, 31,
97 30, 27, 29, 32, 29, 24, 23, 24, 20, 14, 11, 8, 6, 1, 0, -2, -8, -13, -20, -21,
98 -28, -33, -33, -38, -37, -41, -45, -44, -48, -47, -48, -50, -50, -49, -46, -45,
99 -45, -41, -37, -38, -37, -35, -34, -29, -29, -27, -24, -25, -20, -6, -1, -10,
100 -7, 7, 12, 3, -2, 12, 22, 18, 14, 13, 23, 29, 23, 26, 31, 28, 28, 30, 29, 28,
101 26, 27, 27, 23, 24, 22, 21, 23, 21, 17, 13, 8, 11, 15, 12, 12, 20, 19, 16, 17,
102 19, 18, 16, 21, 23, 20, 23, 24, 25, 29, 27, 24, 26, 28, 22, 18, 18, 18, 15, 8,
103 3, 5, 4, -6, -8, -7, -13, -24, -28, -25, -36, -44, -39, -42, -44, -49, -51, -49,
104 -52, -56, -56, -57, -57, -54, -52, -50, -49, -46, -40, -43, -42, -35, -34, -32,
105 -30, -28, -24, -22, -22, -19, -3, 6, -3, -4, 10, 18, 10, 4, 15, 26, 29, 24, 22,
106 31, 39, 36, 32, 37, 36, 35, 39, 37, 36, 37, 37, 36, 32, 31, 29, 25, 25, 24, 18,
107 14, 9, 8, 14, 12, 9, 11, 11, 11, 10, 6, 5, 6, 11, 11, 8, 10, 14, 16, 19, 18, 14,
108 16, 20, 16, 11, 10, 12, 12, 6, 2, 1, -1, -6, -9, -12, -19, -24, -28, -31, -35,
109 -40, -41, -44, -45, -47, -53, -51, -52, -54, -53, -55, -56, -53, -48, -45, -44,
110 -41, -38, -35, -32, -30, -29, -24, -18, -18, -16, -12, -10, -7, -4, 1, 13, 14,
111 9, 14, 24, 29, 21, 20, 33, 39, 37, 33, 32, 41, 47, 40, 38, 40, 41, 43, 39, 36,
112 35, 33, 34, 28, 21, 23, 20, 16, 14, 8, 3, 0, -5, -6, -3, -3, -4, -7, -5, 0, -6,
113 -10, -7, -1, 2, -2, -1, 6, 11, 11, 12, 14, 16, 17, 19, 15, 12, 14, 16, 13, 9, 8,
114 7, 5, 2, -4, -8, -11, -19, -21, -22, -29, -33, -31, -32, -37, -41, -41, -44,
115 -45, -43, -47, -48, -43, -41, -41, -38, -35, -33, -31, -27, -25, -25, -19, -16,
116 -15, -11, -9, -7, -3, 0, 1, 1, 1, 9, 21, 17, 11, 19, 29, 30, 20, 21, 33, 36, 33,
117 28, 27, 33, 34, 29, 31, 31, 27, 27, 24, 20, 17, 13, 14, 10, 4, 4, 1, -3, -4, -8,
118 -11, -14, -17, -12, -7, -10, -12, -8, -4, -5, -8, -4, 3, 7, 9, 10, 13, 19, 24,
119 26, 29, 30, 31, 33, 32, 27, 26, 26, 27, 26, 20, 16, 17, 13, 6, 1, -4, -8, -14,
120 -20, -19, -26, -32, -29, -34, -38, -41, -45, -44, -46, -48, -48, -49, -46, -41,
121 -42, -41, -37, -35, -31, -31, -31, -25, -23, -22, -18, -16, -13, -12, -10, -6,
122 -6, -5, -6, 2, 13, 9, 6, 13, 22, 22, 13, 15, 23, 25, 25, 20, 18, 26, 28, 25, 26,
123 23, 22, 23, 18, 14, 11, 11, 14, 8, 4, 6, 2, 0, -2, -4, -2, -5, -9, -2, 4, 1, -1,
124 3, 10, 10, 7, 10, 14, 20, 23, 22, 25, 32, 37, 37, 37, 40, 40, 39, 36, 32, 31,
125 29, 27, 26, 23, 17, 13, 11, 5, -4, -8, -11, -20, -24, -25, -32, -38, -36, -38,
126 -47, -50, -49, -52, -55, -56, -57, -56, -54, -53, -52, -47, -45, -43, -39, -39,
127 -38, -33, -30, -27, -24, -18, -14, -14, -10, -8, -5, -2, -2, -1, 9, 17, 11, 13,
128 23, 29, 27, 20, 24, 30, 32, 30, 24, 28, 35, 34, 30, 30, 30, 29, 27, 21, 17, 17,
129 18, 16, 10, 10, 10, 7, 7, 3, 3, 5, 3, 3, 5, 7, 7, 7, 11, 13, 13, 14, 16, 19, 24,
130 25, 24, 30, 33, 35, 35, 35, 36, 34, 32, 27, 23, 23, 21, 17, 11, 8, 6, -2, -7,
131 -13, -17, -20, -27, -35, -38, -39, -45, -50, -50, -50, -57, -63, -58, -59, -64,
132 -61, -60, -56, -55, -54, -49, -47, -43, -40, -38, -34, -30, -26, -20, -16, -14,
133 -9, -5, -3, 1, 2, 6, 8, 8, 20, 25, 24, 26, 32, 39, 36, 29, 33, 39, 39, 36, 33,
134 36, 41, 38, 36, 35, 32, 31, 28, 23, 21, 17, 19, 19, 13, 10, 8, 6, 4, -1, -4, -6,
135 -9, -7, -5, -7, -6, -4, -2, 0, -3, -2, 0, 4, 7, 6, 8, 14, 18, 21, 22, 23, 25,
136 24, 22, 22, 20, 18, 17, 18, 17, 10, 8, 9, 4, -3, -8, -9, -14, -20, -24, -27,
137 -30, -33, -35, -37, -41, -44, -44, -46, -51, -50, -47, -46, -45, -44, -40, -39,
138 -37, -34, -32, -29, -27, -22, -17, -15, -12, -7, -3, 0, 0, 2, 5, 7, 7, 7, 9, 13,
139 16, 21, 22, 22, 25, 27, 26, 23, 23, 25, 26, 25, 23, 23, 25, 25, 23, 22, 21, 18,
140 16, 14, 11, 10, 9, 8, 5, 1, -2, -5, -7, -9, -12, -12, -10, -11, -11, -8, -6, -6,
141 -6, -3, -1, -1, 2, 5, 9, 13, 16, 21, 26, 29, 32, 34, 37, 38, 38, 39, 38, 37, 38,
142 36, 33, 31, 26, 24, 19, 13, 8, 3, 0, -9, -14, -16, -23, -28, -32, -35, -39, -44,
143 -46, -49, -51, -52, -53, -54, -54, -51, -51, -49, -46, -44, -38, -38, -36, -28,
144 -27, -24, -18, -15, -13, -10, -5, -1, -1, 2, 5, 5, 6, 7, 7, 8, 8, 7, 12, 13, 12,
145 12, 15, 17, 14, 9, 12, 11, 9, 8, 5, 6, 8, 7, 6, 5, 4, 5, 4, 1, 0, -2, 2, 4, 1,
146 5, 9, 10, 13, 13, 17, 22, 22, 24, 28, 30, 32, 32, 37, 42, 41, 43, 47, 49, 51,
147 51, 50, 52, 51, 49, 44, 40, 37, 32, 25, 20, 13, 8, 2, -6, -9, -17, -27, -29,
148 -32, -40, -50, -52, -54, -61, -65, -67, -71, -71, -67, -71, -73, -69, -66, -62,
149 -63, -58, -54, -51, -43, -42, -34, -27, -26, -18, -11, -8, -5, 0, 6, 8, 9, 9,
150 13, 14, 16, 14, 16, 26, 27, 24, 28, 30, 30, 27, 23, 23, 22, 21, 18, 14, 15, 18,
151 16, 15, 14, 10, 11, 10, 4, 2, 3, 5, 1, -1, 2, 2, 2, 2, 2, 4, 4, 4, 8, 13, 14,
152 17, 21, 25, 27, 28, 32, 34, 37, 39, 39, 41, 46, 47, 47, 48, 49, 48, 45, 42, 38,
153 31, 28, 22, 15, 9, 2, 0, -5, -15, -19, -22, -30, -37, -42, -47, -54, -61, -59,
154 -64, -70, -67, -69, -68, -69, -70, -64, -64, -62, -56, -55, -49, -45, -41, -31,
155 -30, -24, -14, -13, -6, -1, 1, 7, 9, 14, 16, 16, 21, 20, 20, 23, 20, 21, 26, 26,
156 24, 26, 28, 28, 24, 23, 22, 18, 19, 17, 12, 14, 14, 13, 14, 13, 11, 11, 10, 8,
157 5, 4, 4, 1, -1, 1, -3, -3, -3, -3, -2, -1, 3, 4, 5, 11, 13, 14, 16, 19, 23, 25,
158 27, 30, 34, 38, 40, 42, 47, 48, 48, 50, 50, 47, 45, 42, 38, 33, 28, 23, 17, 12,
159 6, -2, -8, -14, -21, -28, -34, -42, -47, -51, -58, -64, -64, -65, -71, -71, -68,
160 -70, -71, -67, -66, -64, -58, -57, -52, -45, -39, -36, -30, -20, -17, -13, -5,
161 -2, 2, 6, 9, 12, 15, 19, 19, 20, 24, 24, 21, 22, 20, 16, 16, 13, 13, 12, 10, 11,
162 10, 11, 8, 4, 4, 3, -2, -5, -5, -6, -6, -5, -5, -4, -2, 0, 0, -1, 4, 5, 6, 9,
163 11, 15, 19, 21, 26, 31, 36, 39, 40, 43, 46, 46, 47, 46, 48, 51, 50, 49, 51, 52,
164 52, 48, 46, 44, 38, 32, 26, 19, 12, 4, -4, -8, -16, -26, -28, -34, -42, -48,
165 -50, -57, -63, -65, -69, -71, -73, -76, -75, -71, -69, -76, -68, -60, -62, -61,
166 -52, -44, -43, -35, -27, -24, -18, -11, -5, 0, 5, 7, 12, 18, 18, 20, 23, 25, 23,
167 22, 22, 19, 17, 15, 12, 14, 16, 12, 9, 13, 15, 9, 3, 3, 2, -1, -5, -9, -9, -5,
168 -4, -5, -3, -1, 1, 2, 2, -2, -3, 1, 2, -1, -1, 3, 8, 14, 18, 21, 31, 38, 38, 39,
169 44, 46, 42, 44, 48, 48, 49, 53, 55, 59, 61, 59, 59, 60, 57, 51, 45, 42, 36, 29,
170 21, 11, 6, 1, -8, -16, -19, -25, -38, -47, -47, -55, -65, -67, -68, -73, -76,
171 -76, -77, -78, -77, -73, -71, -71, -68, -62, -57, -52, -49, -40, -32, -29, -20,
172 -12, -8, -3, 6, 13, 13, 16, 20, 24, 25, 26, 27, 29, 29, 29, 27, 25, 22, 19, 20,
173 20, 14, 13, 16, 16, 12, 9, 9, 9, 7, 5, 2, 0, 2, 3, 4, 4, 4, 6, 9, 9, 8, 8, 10,
174 10, 8, 8, 6, 5, 7, 8, 8, 8, 10, 15, 16, 16, 18, 20, 21, 20, 21, 22, 22, 24, 28,
175 29, 30, 33, 36, 38, 38, 38, 39, 37, 35, 33, 30, 25, 22, 20, 15, 11, 6, 3, -1,
176 -8, -14, -21, -27, -33, -40, -43, -50, -52, -53, -55, -57, -62, -59, -57, -62,
177 -61, -59, -58, -58, -52, -48, -46, -40, -31, -26, -24, -18, -13, -10, -5, -4, 1,
178 3, 5, 9, 11, 14, 15, 17, 18, 17, 14, 12, 9, 4, 2, 0, -1, -1, -3, 0, 3, 5, 3, 0,
179 2, 2, -2, -4, -5, -4, 0, 2, 3, 7, 12, 17, 18, 17, 19, 22, 25, 24, 23, 29, 35,
180 37, 40, 45, 50, 54, 54, 53, 53, 53, 50, 47, 47, 46, 45, 45, 46, 46, 46, 44, 40,
181 37, 32, 25, 17, 10, 2, -5, -12, -19, -22, -28, -34, -36, -43, -49, -52, -58,
182 -62, -68, -71, -70, -74, -75, -72, -69, -67, -67, -60, -56, -55, -51, -46, -39,
183 -36, -34, -25, -19, -15, -9, -2, 5, 10, 14, 17, 19, 19, 23, 23, 20, 21, 19, 18,
184 13, 8, 9, 4, 5, 8, 5, 5, 6, 6, 6, 2, -1, -1, -3, -5, -8, -10, -4, -2, -1, 5, 8,
185 10, 12, 13, 13, 10, 11, 12, 10, 11, 12, 13, 18, 24, 27, 29, 35, 42, 41, 39, 42,
186 43, 41, 40, 39, 42, 43, 44, 46, 48, 50, 50, 49, 48, 46, 41, 39, 33, 28, 23, 15,
187 7, 0, -3, -10, -22, -25, -28, -37, -45, -51, -53, -58, -64, -67, -70, -71, -74,
188 -74, -73, -73, -72, -69, -64, -62, -59, -52, -47, -42, -35, -28, -24, -19, -8,
189 -4, -3, 5, 11, 14, 17, 20, 25, 25, 27, 29, 26, 26, 25, 20, 18, 16, 11, 8, 10,
190 10, 8, 8, 10, 8, 5, 5, 3, -1, 0, -2, -4, -3, -2, 1, 4, 7, 9, 10, 13, 12, 10, 10,
191 8, 6, 6, 5, 4, 5, 8, 9, 9, 12, 14, 15, 17, 17, 16, 19, 19, 19, 21, 24, 27, 29,
192 33, 36, 37, 40, 42, 42, 43, 43, 43, 42, 40, 38, 34, 31, 26, 21, 16, 11, 3, -3,
193 -8, -16, -22, -29, -36, -40, -47, -51, -56, -59, -63, -68, -67, -69, -70, -68,
194 -67, -65, -63, -58, -55, -52, -45, -41, -35, -29, -25, -19, -12, -7, -3, 1, 7,
195 9, 10, 13, 15, 14, 16, 18, 15, 14, 13, 9, 6, 1, -2, -2, -1, -2, -4, 0, 2, 0, 0,
196 1, 0, -2, -3, -4, -5, -3, 0, 2, 6, 10, 13, 16, 19, 19, 21, 27, 26, 24, 28, 33,
197 35, 36, 42, 46, 49, 51, 50, 49, 51, 49, 46, 45, 45, 43, 42, 43, 43, 43, 44, 42,
198 38, 36, 32, 25, 21, 17, 9, 2, -4, -10, -17, -22, -26, -33, -35, -39, -48, -51,
199 -53, -57, -61, -63, -64, -67, -66, -65, -68, -62, -59, -56, -56, -53, -45, -44,
200 -40, -34, -28, -22, -20, -14, -6, -3, -1, 4, 11, 12, 13, 13, 16, 18, 18, 17, 13,
201 15, 14, 6, 2, 1, -2, -6, -7, -6, -7, -6, -4, -4, -3, -2, -4, -4, -3, -4, -5, -3,
202 1, 3, 7, 12, 14, 19, 23, 24, 25, 25, 25, 23, 23, 21, 19, 19, 22, 22, 20, 25, 31,
203 32, 33, 35, 38, 35, 32, 32, 30, 30, 29, 28, 30, 34, 36, 38, 40, 42, 42, 41, 39,
204 35, 31, 27, 20, 13, 9, 3, -4, -8, -13, -19, -24, -29, -37, -42, -48, -55, -60,
205 -65, -68, -70, -72, -74, -71, -69, -68, -67, -63, -59, -59, -55, -48, -46, -42,
206 -32, -28, -23, -14, -8, -3, 4, 8, 9, 13, 16, 15, 16, 20, 20, 16, 18, 19, 12, 10,
207 7, 2, -1, -1, -2, -2, 0, 1, 2, 5, 6, 4, 5, 8, 6, 4, 7, 10, 12, 18, 22, 24, 30,
208 36, 37, 38, 40, 39, 37, 37, 35, 31, 30, 31, 29, 27, 27, 24, 21, 20, 16, 12, 9,
209 6, 3, 1, 1, -1, -1, 3, 5, 4, 6, 8, 9, 10, 10, 12, 12, 13, 14, 12, 12, 10, 8, 8,
210 6, 1, 0, -2, -7, -10, -13, -17, -22, -25, -29, -34, -37, -41, -46, -44, -49,
211 -51, -48, -49, -48, -48, -45, -41, -40, -35, -33, -30, -24, -23, -20, -14, -10,
212 -7, -4, 2, 6, 6, 11, 10, 9, 13, 8, 4, 4, 1, -5, -7, -11, -14, -17, -19, -16,
213 -17, -15, -11, -10, -5, -5, -7, -2, 0, -1, 0, 4, 8, 11, 17, 23, 28, 35, 40, 43,
214 46, 47, 47, 47, 46, 44, 42, 42, 42, 40, 42, 42, 40, 39, 36, 33, 28, 21, 19, 13,
215 9, 7, 4, 4, 6, 6, 8, 9, 10, 11, 10, 9, 7, 4, 2, -1, -6, -9, -12, -13, -12, -17,
216 -20, -20, -19, -24, -30, -30, -31, -38, -40, -43, -47, -46, -45, -46, -48, -43,
217 -41, -45, -41, -40, -38, -37, -36, -30, -28, -23, -21, -17, -7, -6, -3, 1, 2, 2,
218 5, 4, 1, 2, 2, 0, -2, 0, -2, -7, -6, -5, -12, -15, -16, -17, -16, -14, -14, -14,
219 -7, -3, -3, -2, 1, 3, 4, 6, 5, 5, 10, 14, 17, 19, 22, 26, 30, 32, 30, 29, 29,
220 28, 24, 21, 24, 24, 27, 36, 37, 40, 46, 48, 48, 46, 46, 42, 37, 37, 34, 32, 35,
221 37, 40, 45, 47, 46, 46, 45, 38, 30, 23, 12, 1, -7, -15, -24, -28, -31, -35, -40,
222 -43, -47, -53, -57, -64, -71, -73, -77, -81, -78, -74, -74, -70, -61, -55, -54,
223 -47, -40, -39, -34, -29, -26, -21, -14, -8, -2, 5, 11, 15, 21, 24, 21, 23, 20,
224 14, 12, 11, 6, -1, -2, -2, -7, -10, -12, -12, -10, -8, -9, -11, -7, -4, -4, -2,
225 -1, 3, 9, 14, 15, 19, 28, 34, 38, 40, 44, 47, 49, 50, 48, 47, 47, 45, 43, 38,
226 35, 32, 29, 25, 20, 15, 11, 5, 1, -2, -6, -10, -11, -11, -11, -12, -11, -8, -4,
227 -2, 1, 2, 7, 11, 13, 17, 20, 22, 26, 27, 26, 24, 23, 22, 19, 15, 11, 5, 2, -2,
228 -7, -11, -17, -20, -25, -32, -38, -43, -45, -51, -55, -55, -57, -59, -56, -53,
229 -53, -50, -43, -42, -39, -33, -30, -27, -22, -17, -12, -7, -3, 1, 7, 11, 12, 12,
230 15, 15, 11, 8, 4, 2, -2, -8, -12, -14, -17, -21, -21, -17, -18, -18, -13, -8,
231 -9, -8, -4, -3, 0, 1, 2, 6, 13, 17, 22, 30, 37, 42, 48, 52, 52, 52, 53, 52, 49,
232 46, 44, 43, 42, 40, 38, 37, 35, 31, 27, 24, 18, 12, 7, 3, -2, -5, -5, -5, -4, 0,
233 1, 3, 7, 9, 9, 9, 9, 7, 6, 4, 1, -3, -5, -6, -8, -9, -10, -11, -14, -16, -16,
234 -21, -24, -28, -32, -34, -39, -45, -45, -44, -47, -48, -46, -46, -42, -37, -36,
235 -36, -30, -22, -23, -25, -16, -9, -11, -11, -2, 1, 0, 3, 7, 8, 8, 9, 6, 4, 4,
236 -3, -7, -7, -11, -16, -17, -18, -22, -21, -16, -12, -11, -9, -4, -3, -1, -1, -2,
237 2, 4, 4, 4, 6, 12, 18, 21, 25, 28, 31, 33, 31, 29, 28, 25, 22, 21, 16, 15, 20,
238 25, 27, 30, 38, 42, 40, 39, 41, 38, 34, 31, 28, 28, 28, 28, 33, 39, 43, 46, 48,
239 48, 45, 40, 35, 25, 14, 5, -7, -18, -23, -29, -34, -37, -40, -44, -47, -51, -55,
240 -60, -65, -70, -74, -76, -76, -77, -72, -65, -61, -53, -46, -38, -31, -26, -21,
241 -16, -10, -9, -5, 2, 3, 9, 15, 19, 22, 25, 27, 25, 23, 19, 13, 9, 3, -5, -13,
242 -17, -18, -23, -26, -25, -26, -23, -19, -18, -16, -11, -7, -6, -3, -1, 3, 9, 14,
243 18, 22, 31, 37, 41, 45, 48, 48, 47, 46, 42, 37, 32, 27, 23, 18, 13, 8, 6, 5, 0,
244 -4, -6, -8, -10, -12, -13, -13, -12, -8, -4, -1, 4, 11, 18, 25, 30, 34, 41, 45,
245 48, 50, 51, 52, 53, 50, 46, 40, 35, 28, 20, 11, 1, -7, -17, -26, -34, -43, -52,
246 -57, -60, -69, -74, -73, -77, -82, -79, -76, -78, -74, -66, -62, -58, -49, -39,
247 -33, -23, -12, -8, -1, 11, 16, 18, 24, 27, 28, 30, 30, 26, 25, 26, 19, 14, 11,
248 6, -1, -9, -14, -23, -30, -35, -39, -38, -37, -35, -30, -23, -18, -13, -6, 0, 3,
249 8, 12, 16, 20, 27, 35, 42, 51, 57, 63, 70, 72, 72, 70, 67, 61, 53, 45, 36, 30,
250 24, 17, 12, 6, 1, -4, -8, -14, -21, -26, -30, -33, -36, -36, -34, -30, -23, -16,
251 -8, 1, 9, 16, 23, 28, 32, 35, 37, 37, 35, 33, 31, 26, 21, 19, 17, 11, 4, 0, -6,
252 -18, -24, -29, -40, -48, -52, -62, -69, -68, -72, -73, -68, -69, -67, -59, -53,
253 -51, -46, -33, -28, -29, -15, -6, -6, 5, 15, 17, 23, 32, 31, 30, 35, 33, 27, 24,
254 21, 12, 7, 4, -8, -13, -11, -20, -26, -19, -16, -22, -20, -12, -12, -14, -12,
255 -11, -10, -5, -4, -5, 3, 12, 16, 23, 31, 36, 41, 47, 46, 42, 43, 42, 34, 28, 25,
256 20, 16, 16, 14, 11, 15, 16, 14, 13, 12, 11, 8, 6, 4, 1, 3, 4, 5, 12, 17, 20, 27,
257 33, 34, 36, 36, 32, 26, 20, 11, 2, -5, -10, -17, -23, -24, -28, -34, -35, -36,
258 -42, -48, -54, -57, -64, -71, -70, -68, -70, -64, -53, -48, -41, -30, -21, -13,
259 -10, -5, 0, 4, 6, 4, 10, 17, 18, 20, 25, 27, 27, 28, 23, 17, 11, 3, -5, -19,
260 -27, -32, -43, -44, -46, -48, -39, -33, -29, -19, -12, -6, 0, 3, 7, 12, 15, 20,
261 23, 29, 40, 45, 52, 61, 65, 68, 69, 65, 60, 52, 42, 32, 21, 11, 1, -8, -13, -17,
262 -21, -22, -23, -25, -24, -25, -26, -25, -24, -21, -18, -13, -5, 5, 15, 26, 37,
263 47, 56, 62, 67, 70, 70, 66, 61, 56, 45, 34, 25, 14, 3, -5, -16, -29, -35, -43,
264 -57, -64, -71, -81, -86, -86, -94, -100, -90, -83, -83, -75, -62, -52, -42, -27,
265 -19, -9, 5, 14, 19, 26, 35, 38, 44, 49, 49, 52, 53, 50, 46, 42, 33, 21, 12, 3,
266 -13, -26, -35, -45, -54, -62, -68, -66, -61, -58, -51, -41, -32, -23, -13, -4,
267 4, 12, 22, 29, 35, 43, 53, 62, 70, 76, 81, 84, 84, 82, 75, 67, 57, 45, 31, 17,
268 3, -9, -19, -29, -37, -42, -48, -51, -52, -53, -53, -51, -45, -40, -35, -24,
269 -13, -2, 11, 25, 38, 50, 60, 70, 79, 83, 84, 84, 81, 76, 67, 56, 43, 30, 17, 2,
270 -11, -26, -38, -51, -64, -71, -79, -93, -99, -96, -101, -108, -105, -95, -86,
271 -81, -70, -55, -39, -24, -15, -2, 16, 27, 32, 45, 52, 53, 59, 63, 63, 62, 60,
272 54, 47, 41, 31, 16, 5, -4, -21, -36, -47, -60, -68, -76, -87, -88, -79, -76,
273 -73, -58, -42, -31, -19, -4, 7, 19, 31, 38, 44, 55, 64, 70, 77, 83, 87, 92, 92,
274 86, 81, 75, 62, 46, 32, 16, -1, -14, -26, -39, -46, -49, -52, -53, -50, -48,
275 -43, -38, -35, -32, -24, -12, -1, 10, 18, 26, 41, 59, 72, 80, 82, 79, 79, 79,
276 73, 60, 42, 21, 5, -6, -22, -39, -45, -55, -70, -74, -73, -81, -91, -91, -92,
277 -97, -97, -92, -89, -81, -69, -55, -36, -18, -6, 13, 32, 43, 55, 64, 68, 68, 71,
278 69, 61, 57, 55, 47, 38, 32, 21, 10, 1, -13, -27, -41, -57, -72, -85, -95, -96,
279 -88, -83, -79, -63, -41, -25, -13, 4, 21, 33, 40, 43, 47, 56, 62, 64, 68, 74,
280 78, 83, 84, 81, 77, 71, 58, 41, 25, 9, -9, -23, -35, -45, -48, -46, -42, -36,
281 -28, -19, -10, -3, 3, 8, 11, 14, 19, 24, 30, 33, 40, 49, 52, 53, 53, 50, 42, 29,
282 15, 1, -14, -34, -48, -57, -68, -78, -83, -81, -80, -82, -83, -79, -71, -71,
283 -70, -61, -51, -44, -34, -20, -7, 10, 25, 37, 50, 62, 68, 69, 73, 72, 64, 57,
284 49, 40, 28, 17, 5, -5, -13, -26, -39, -47, -56, -64, -68, -69, -70, -68, -59,
285 -51, -44, -32, -17, -4, 7, 17, 28, 39, 48, 54, 58, 65, 67, 67, 68, 66, 61, 57,
286 52, 43, 33, 23, 12, 1, -8, -20, -29, -34, -37, -40, -38, -32, -26, -17, -6, 1,
287 10, 21, 28, 35, 40, 42, 44, 47, 47, 43, 38, 35, 30, 20, 9, 1, -5, -20, -32, -37,
288 -50, -62, -65, -72, -82, -84, -84, -86, -83, -79, -70, -61, -51, -40, -27, -13,
289 -3, 9, 24, 31, 36, 46, 51, 51, 55, 53, 51, 48, 42, 34, 24, 16, 4, -9, -21, -35,
290 -47, -55, -64, -68, -62, -61, -58, -45, -33, -24, -13, 0, 11, 19, 25, 32, 38,
291 44, 49, 52, 58, 60, 62, 66, 65, 61, 56, 51, 42, 29, 16, 4, -8, -18, -29, -37,
292 -41, -41, -41, -38, -32, -25, -16, -6, 3, 9, 18, 28, 34, 39, 43, 47, 50, 49, 43,
293 39, 35, 27, 16, 4, -7, -18, -29, -41, -53, -59, -67, -76, -77, -79, -83, -80,
294 -74, -71, -64, -55, -45, -32, -19, -8, 4, 19, 31, 40, 50, 56, 59, 63, 64, 58,
295 53, 48, 39, 28, 16, 3, -9, -20, -32, -45, -56, -64, -68, -69, -71, -70, -61,
296 -52, -45, -33, -18, -6, 8, 21, 31, 41, 52, 61, 67, 70, 72, 75, 76, 72, 65, 61,
297 56, 46, 35, 24, 13, 1, -10, -22, -32, -39, -43, -46, -47, -44, -39, -32, -22,
298 -12, -2, 9, 18, 28, 37, 41, 42, 45, 45, 42, 38, 30, 23, 18, 9, -5, -14, -20,
299 -29, -39, -47, -56, -60, -64, -71, -73, -69, -68, -66, -58, -49, -42, -30, -15,
300 -6, 3, 17, 27, 34, 42, 46, 47, 49, 48, 43, 37, 32, 24, 15, 6, -4, -13, -20, -27,
301 -34, -38, -41, -43, -42, -41, -42, -38, -31, -27, -23, -15, -6, 3, 12, 21, 30,
302 39, 47, 52, 55, 58, 58, 57, 53, 48, 42, 37, 31, 24, 18, 12, 7, 4, 1, -3, -6, -6,
303 -7, -8, -8, -8, -6, -6, -7, -8, -10, -11, -13, -18, -21, -25, -29, -33, -35,
304 -37, -37, -37, -37, -33, -30, -30, -26, -20, -18, -17, -12, -8, -4, 0, 3, 8, 13,
305 17, 21, 24, 26, 27, 25, 22, 17, 11, 4, -3, -11, -20, -23, -25, -28, -29, -27,
306 -25, -20, -15, -12, -9, -6, -4, -2, 1, 3, 6, 9, 11, 17, 24, 28, 30, 34, 35, 34,
307 33, 29, 23, 17, 10, 4, -1, -5, -9, -10, -11, -10, -7, -5, -2, 1, 2, 4, 5, 5, 5,
308 4, 1, 1, -1, -3, -6, -8, -11, -14, -17, -19, -24, -26, -27, -30, -34, -32, -30,
309 -30, -30, -27, -22, -18, -15, -9, -5, -1, 3, 7, 11, 15, 15, 16, 17, 16, 15, 12,
310 9, 7, 8, 6, 5, 6, 8, 8, 8, 9, 10, 8, 5, 3, 0, -3, -5, -7, -8, -8, -6, -3, -1, 1,
311 4, 6, 6, 6, 6, 4, 1, 0, -2, -4, -3, -3, -2, 1, 5, 8, 10, 13, 14, 16, 16, 15, 12,
312 8, 5, 2, -1, -5, -9, -14, -18, -22, -27, -31, -34, -39, -42, -43, -44, -44, -42,
313 -38, -32, -26, -21, -13, -6, 2, 8, 13, 18, 22, 23, 25, 25, 24, 22, 19, 15, 11,
314 6, 1, -4, -9, -14, -16, -17, -18, -19, -17, -15, -11, -8, -6, -2, 2, 4, 6, 10,
315 13, 15, 16, 19, 21, 21, 21, 20, 18, 16, 12, 8, 4, -1, -6, -10, -13, -14, -15,
316 -16, -15, -14, -11, -8, -5, -1, 2, 4, 7, 9, 10, 11, 10, 10, 8, 5, 2, -1, -8,
317 -13, -20, -28, -33, -39, -47, -50, -51, -54, -51, -45, -42, -36, -28, -18, -11,
318 -4, 4, 9, 14, 18, 20, 22, 23, 21, 20, 18, 15, 11, 6, -1, -7, -12, -17, -21, -25,
319 -28, -30, -29, -28, -26, -23, -19, -15, -10, -5, 1, 7, 12, 15, 21, 26, 29, 30,
320 31, 30, 29, 27, 23, 18, 14, 8, 2, -2, -6, -10, -14, -17, -19, -19, -19, -19,
321 -18, -16, -14, -11, -8, -4, -2, 0, 2, 5, 6, 5, 4, 5, 2, -4, -7, -9, -16, -23,
322 -27, -29, -33, -36, -35, -34, -32, -27, -24, -20, -14, -10, -7, -4, -1, 1, 1, 0,
323 0, 0, -1, -4, -6, -7, -10, -12, -13, -13, -13, -13, -12, -9, -7, -6, -4, -3, -1,
324 0, 0, 2, 3, 4, 4, 5, 7, 7, 7, 7, 7, 5, 3, 1, -1, -4, -8, -10, -12, -12, -12,
325 -12, -11, -8, -5, -1, 2, 6, 9, 12, 15, 17, 18, 19, 19, 17, 15, 14, 10, 5, -1,
326 -7, -13, -20, -28, -34, -39, -47, -52, -53, -52, -53, -51, -42, -34, -28, -18,
327 -5, 4, 12, 20, 27, 30, 32, 32, 30, 25, 21, 15, 7, 0, -6, -13, -18, -20, -22,
328 -25, -25, -24, -24, -22, -22, -21, -20, -20, -18, -16, -13, -11, -6, -2, 2, 6,
329 10, 13, 14, 14, 14, 12, 9, 5, 1, -3, -6, -9, -10, -11, -10, -9, -7, -5, -3, -1,
330 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 4, 1, -1, -4, -8, -13, -19, -23, -28, -35, -38,
331 -39, -42, -45, -41, -37, -35, -29, -19, -14, -7, 3, 9, 14, 21, 24, 24, 24, 23,
332 20, 14, 8, 2, -6, -13, -18, -22, -26, -29, -28, -25, -24, -21, -15, -13, -10,
333 -5, -2, 0, 3, 5, 5, 8, 10, 11, 12, 13, 13, 13, 12, 9, 7, 2, -3, -7, -11, -16,
334 -20, -23, -25, -25, -24, -22, -19, -15, -10, -6, -1, 3, 6, 9, 10, 12, 12, 12,
335 11, 10, 9, 6, 4, 1, -2, -6, -9, -13, -18, -22, -26, -32, -36, -37, -42, -46,
336 -44, -42, -41, -35, -28, -22, -14, -4, 4, 10, 16, 20, 19, 19, 17, 11, 4, -2, -9,
337 -15, -18, -21, -23, -19, -16, -14, -7, -1, 1, 3, 7, 7, 6, 7, 5, 3, 3, 4, 4, 4,
338 7, 9, 9, 10, 11, 9, 5, 2, -2, -7, -11, -16, -19, -20, -20, -19, -16, -12, -7,
339 -1, 4, 9, 13, 16, 17, 18, 17, 14, 11, 8, 4, 1, -2, -5, -8, -10, -11, -15, -16,
340 -18, -23, -24, -27, -31, -34, -36, -36, -37, -37, -33, -30, -25, -17, -10, -3,
341 4, 11, 15, 19, 21, 19, 17, 13, 6, -1, -7, -15, -20, -22, -26, -27, -24, -21,
342 -17, -12, -6, -3, 0, 4, 5, 5, 6, 4, 3, 4, 4, 4, 5, 7, 9, 10, 12, 12, 11, 9, 7,
343 3, 0, -5, -9, -12, -14, -14, -13, -11, -7, -3, 2, 7, 10, 14, 17, 17, 17, 16, 14,
344 11, 7, 5, 2, 0, -2, -4, -4, -5, -6, -7, -8, -11, -14, -16, -21, -26, -29, -34,
345 -35, -36, -38, -35, -30, -24, -17, -9, -2, 6, 14, 19, 20, 22, 21, 15, 11, 5, -3,
346 -9, -14, -19, -22, -21, -19, -17, -13, -8, -5, 0, 3, 4, 6, 5, 4, 4, 2, 1, 0, 0,
347 2, 3, 4, 6, 7, 8, 9, 8, 5, 3, 0, -4, -7, -10, -12, -13, -13, -11, -9, -5, -1, 4,
348 8, 12, 15, 17, 18, 18, 16, 14, 11, 7, 5, 2, 0, 0, 0, 0, 2, 4, 5, 6, 6, 5, 3, 2,
349 -2, -6, -11, -16, -21, -26, -27, -32, -35, -32, -33, -29, -23, -21, -14, -7, -1,
350 6, 10, 14, 17, 18, 18, 17, 14, 11, 7, 4, 2, 0, -2, -3, -3, -3, -2, -1, -2, -2,
351 -1, -3, -3, -4, -6, -7, -6, -6, -5, -3, -1, 2, 5, 9, 11, 12, 14, 13, 12, 11, 8,
352 5, 2, -1, -3, -4, -4, -4, -2, 0, 3, 6, 9, 11, 13, 14, 15, 14, 12, 10, 8, 5, 2,
353 1, 0, -1, 1, 1, 3, 5, 5, 6, 6, 5, 2, 0, -3, -6, -9, -13, -15, -18, -20, -21,
354 -24, -22, -22, -21, -18, -14, -11, -7, -2, 1, 5, 8, 10, 12, 12, 11, 10, 8, 6, 4,
355 2, -1, -1, -3, -4, -3, -4, -3, -2, -2, -1, 0, 0, 1, 3, 4, 6, 8, 10, 12, 13, 14,
356 14, 13, 12, 9, 7, 4, 0, -3, -7, -9, -11, -13, -13, -13, -11, -8, -5, -2, 2, 6,
357 10, 13, 15, 17, 18, 18, 17, 16, 14, 12, 10, 7, 5, 3, 2, 1, 1, 1, 2, 2, 3, 4, 4,
358 4, 4, 4, 3, 1, 0, -1, -3, -5, -6, -10, -12, -16, -21, -24, -29, -33, -36, -38,
359 -36, -34, -28, -20, -11, 1, 12, 24, 33, 41, 45, 45, 44, 36, 29, 19, 6, -4, -15,
360 -24, -30, -34, -35, -33, -28, -22, -15, -7, 1, 7, 13, 17, 20, 21, 21, 20, 18,
361 16, 15, 12, 11, 9, 7, 6, 4, 2, -1, -4, -7, -10, -13, -15, -16, -16, -14, -11,
362 -7, -2, 4, 9, 15, 19, 22, 24, 23, 21, 17, 12, 6, -1, -7, -13, -17, -20, -21,
363 -20, -18, -14, -9, -3, 2, 7, 12, 15, 17, 18, 17, 15, 13, 11, 9, 8, 8, 9, 11, 14,
364 17, 20, 23, 24, 23, 21, 18, 11, 4, -3, -12, -20, -27, -33, -37, -38, -38, -35,
365 -32, -28, -23, -18, -10, -3, 2, 11, 16, 22, 28, 31, 34, 34, 32, 28, 24, 17, 9,
366 1, -7, -14, -20, -25, -27, -28, -26, -22, -17, -10, -2, 5, 12, 19, 24, 28, 30,
367 30, 30, 27, 24, 19, 14, 9, 4, 0, -5, -8, -10, -12, -13, -13, -12, -10, -8, -5,
368 -3, 1, 4, 7, 10, 13, 15, 16, 17, 17, 17, 16, 14, 11, 8, 4, 1, -3, -5, -8, -10,
369 -11, -11, -11, -9, -7, -4, -1, 3, 6, 9, 12, 14, 16, 17, 17, 17, 15, 13, 12, 9,
370 7, 4, 2, 1, -1, 0, 1, 4, 8, 12, 18, 23, 27, 31, 32, 31, 27, 21, 13, 4, -6, -16,
371 -24, -31, -35, -37, -36, -32, -27, -19, -11, -4, 4, 10, 15, 18, 19, 19, 18, 15,
372 12, 9, 5, 2, -1, -3, -6, -7, -8, -11, -12, -13, -14, -15, -14, -13, -10, -6, -2,
373 4, 9, 16, 21, 26, 30, 31, 32, 30, 26, 20, 14, 7, -1, -7, -14, -19, -22, -24,
374 -23, -22, -18, -14, -9, -3, 2, 7, 12, 16, 19, 21, 22, 22, 21, 20, 19, 16, 14,
375 11, 8, 5, 2, -2, -5, -8, -11, -13, -15, -15, -15, -14, -11, -8, -3, 1, 7, 13,
376 21, 30, 34, 41, 43, 42, 42, 35, 26, 15, 3, -10, -22, -32, -40, -46, -48, -47,
377 -43, -37, -29, -20, -11, 0, 9, 17, 24, 28, 32, 33, 33, 31, 26, 23, 17, 12, 7, 1,
378 -3, -7, -9, -11, -11, -11, -9, -7, -4, -1, 3, 6, 8, 11, 11, 12, 12, 10, 9, 5, 2,
379 -2, -6, -8, -10, -12, -12, -12, -10, -7, -5, -2, 1, 3, 6, 7, 8, 8, 8, 7, 7, 6,
380 6, 6, 5, 6, 6, 6, 7, 6, 6, 6, 4, 3, 1, 0, -2, -4, -5, -6, -6, -6, -4, -3, 2, 5,
381 9, 16, 18, 23, 27, 28, 29, 27, 25, 20, 15, 8, 1, -6, -12, -16, -20, -20, -20,
382 -18, -14, -11, -6, -2, 1, 3, 4, 3, 3, 0, -3, -5, -7, -9, -8, -7, -5, -1, 2, 8,
383 12, 16, 18, 19, 19, 17, 13, 8, 2, -4, -10, -14, -17, -18, -18, -16, -11, -6, 1,
384 8, 14, 20, 24, 26, 27, 26, 22, 18, 13, 8, 3, -2, -5, -7, -9, -8, -7, -6, -4, -2,
385 0, 3, 3, 4, 4, 3, 2, 1, 1, 0, 1, 1, 2, 4, 6, 9, 11, 13, 14, 14, 14, 13, 11, 8,
386 5, 2, -2, -5, -8, -4, -4, 1, 7, 9, 18, 22, 26, 29, 28, 25, 20, 14, 6, -2, -11,
387 -19, -25, -30, -31, -31, -29, -23, -17, -10, -2, 5, 12, 17, 22, 24, 24, 23, 21,
388 18, 14, 11, 8, 5, 4, 3, 3, 4, 5, 6, 7, 8, 8, 7, 6, 4, 2, 0, -1, -3, -3, -4, -3,
389 -3, -2, -1, -1, -1, 0, 0, -1, -1, -3, -2, -2, -2, -2, -2, -1, 0, 1, 3, 4, 5, 7,
390 9, 9, 11, 11, 11, 12, 11, 11, 10, 9, 8, 7, 7, 7, 6, 6, 7, 8, 9, 10, 11, 12, 13,
391 13, 13, 13, 12, 11, 9, 8, 7, 5, 4, 3, 2, 1, 1, 1, 1, 0, 0, 0, 0, -1, -1, -3, -3,
392 -5, -6, -7, -9, -9, -10, -10, -10, -10, -10, -9, -8, -6, -5, -4, -2, 1, 4, 5, 8,
393 9, 11, 13, 13, 13, 12, 11, 9, 7, 6, 4, 2, 1, 1, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3,
394 3, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 9, 8, 6, 5, 3, 2, 0,
395 -1, -1, -2, -2, -1, 0, 1, 3, 4, 6, 7, 8, 9, 9, 9, 9, 8, 7, 6, 4, 3, 2, 1, 0, 1,
396 2, 5, 9, 12, 17, 19, 21, 22, 20, 17, 12, 6, 0, -7, -13, -18, -22, -23, -23, -21,
397 -18, -13, -8, -2, 4, 9, 12, 14, 16, 16, 14, 12, 9, 6, 3, 1, 0, -1, 0, 1, 3, 6,
398 8, 11, 13, 13, 14, 13, 11, 8, 4, -1, -6, -11, -16, -22, -24, -26, -26, -24, -22,
399 -17, -12, -5, 2, 7, 12, 17, 20, 22, 23, 21, 20, 17, 14, 12, 8, 5, 3, 1, 1, 0, 0,
400 2, 2, 3, 4, 4, 4, 5, 4, 3, 3, 2, 2, 2, 2, 3, 4, 6, 8, 10, 12, 14, 15, 16, 15,
401 14, 13, 11, 8, 5, 2, -1, -4, -6, -8, -9, -10, -10, -10, -9, -8, -8, -7, -7, -7,
402 -6, -7, -6, -7, -8, -8, -8, -7, -6, -5, -4, -2, 0, 1, 4, 5, 6, 9, 9, 10, 10, 9,
403 10, 9, 8, 7, 5, 4, 3, 2, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4,
404 5, 6, 7, 8, 9, 9, 9, 10, 9, 8, 7, 6, 4, 2, 1, -1, -2, -3, -3, -3, -3, -2, -1, 1,
405 2, 4, 5, 6, 7, 7, 7, 7, 7, 6, 5, 5, 3, 7, 9, 10, 17, 15, 19, 22, 19, 20, 16, 10,
406 5, -3, -9, -15, -22, -25, -27, -28, -24, -21, -16, -9, -3, 4, 10, 15, 19, 21,
407 22, 22, 21, 18, 15, 12, 9, 7, 5, 4, 3, 4, 5, 6, 7, 9, 9, 9, 8, 6, 5, 0, -3, -8,
408 -13, -18, -24, -26, -28, -27, -24, -22, -16, -9, 0, 8, 16, 22, 28, 31, 33, 33,
409 30, 25, 19, 12, 5, -2, -9, -13, -17, -19, -19, -18, -15, -11, -7, -2, 3, 7, 11,
410 14, 16, 17, 18, 17, 17, 16, 14, 14, 12, 11, 10, 9, 9, 8, 7, 7, 5, 4, 2, 0, -2,
411 -4, -7, -9, -12, -14, -15, -17, -17, -17, -16, -14, -13, -9, -7, -5, 0, 2, 5, 8,
412 9, 10, 11, 10, 8, 6, 3, 0, -1, -5, -5, -6, -6, -3, -2, 0, 3, 5, 7, 8, 9, 8, 8,
413 5, 3, 2, -2, -3, -4, -5, -5, -4, -3, -1, 1, 3, 5, 6, 7, 8, 7, 7, 5, 3, 2, 0, -2,
414 -3, -4, -4, -3, -2, -1, 1, 2, 4, 6, 6, 7, 7, 6, 6, 4, 3, 1, -1, -1, -2, -2, -2,
415 1, 5, 6, 15, 17, 21, 29, 28, 31, 32, 25, 22, 16, 5, -1, -12, -22, -27, -35, -37,
416 -37, -38, -32, -27, -20, -11, -3, 5, 13, 18, 23, 25, 26, 26, 23, 20, 16, 12, 9,
417 5, 2, 1, -1, -1, 0, 0, 2, 3, 3, 4, 3, 1, -1, -5, -9, -15, -23, -29, -32, -34,
418 -35, -33, -30, -23, -12, -3, 9, 19, 27, 35, 41, 45, 44, 41, 34, 27, 18, 7, -2,
419 -12, -19, -24, -27, -27, -25, -21, -16, -9, -2, 4, 10, 14, 17, 19, 18, 17, 15,
420 13, 11, 9, 8, 7, 7, 8, 9, 10, 12, 12, 13, 12, 11, 8, 4, 0, -5, -10, -16, -20,
421 -24, -27, -28, -28, -26, -23, -17, -12, -6, 1, 6, 12, 16, 19, 21, 21, 20, 18,
422 15, 11, 7, 3, -1, -5, -10, -13, -16, -18, -17, -18, -18, -15, -13, -10, -5, -2,
423 1, 4, 6, 8, 10, 11, 11, 11, 10, 10, 9, 8, 7, 5, 5, 3, 2, 2, 0, -1, -1, -2, -3,
424 -3, -4, -4, -4, -4, -4, -4, -3, -2, -1, 0, 1, 3, 4, 5, 6, 6, 6, 6, 6, 5, 4, 2,
425 2, 1, 0, 1, 2, 3, 6, 8, 10, 13, 14, 16, 17, 16, 15, 12, 8, 4, -2, -7, -13, -18,
426 -22, -26, -28, -29, -29, -27, -23, -19, -14, -8, -2, 4, 9, 13, 17, 20, 21, 22,
427 21, 21, 19, 17, 15, 12, 10, 8, 6, 4, 3, 2, 1, -1, -2, -3, -4, -6, -8, -10, -13,
428 -16, -20, -26, -29, -28, -29, -28, -26, -23, -14, -5, 3, 13, 20, 27, 32, 37, 40,
429 38, 35, 30, 24, 17, 10, 2, -5, -11, -16, -19, -20, -20, -19, -17, -14, -10, -6,
430 -4, -1, 0, 1, 2, 2, 1, 0, 0, 1, 2, 4, 8, 10, 15, 21, 25, 29, 31, 32, 31, 28, 24,
431 18, 10, 1, -7, -16, -23, -30, -35, -38, -39, -37, -33, -29, -22, -16, -9, -1, 5,
432 10, 15, 17, 19, 20, 19, 19, 17, 16, 14, 13, 11, 10, 10, 9, 9, 8, 8, 7, 6, 4, 1,
433 -1, -5, -10, -14, -21, -28, -32, -34, -36, -37, -36, -31, -24, -15, -5, 5, 14,
434 23, 31, 38, 42, 42, 40, 36, 31, 24, 16, 7, -1, -9, -15, -20, -22, -24, -25, -23,
435 -20, -17, -13, -9, -6, -4, -1, 0, 2, 2, 1, 1, 1, 1, 2, 3, 4, 5, 8, 12, 14, 17,
436 20, 21, 24, 25, 25, 24, 20, 17, 12, 7, 1, -5, -11, -17, -21, -24, -27, -28, -27,
437 -26, -23, -19, -15, -10, -7, -3, 0, 3, 6, 8, 8, 9, 10, 11, 11, 11, 12, 12, 12,
438 13, 14, 14, 13, 12, 11, 9, 7, 5, 2, -1, -4, -7, -9, -11, -13, -15, -15, -16,
439 -18, -21, -23, -22, -21, -22, -20, -18, -13, -8, -3, 4, 8, 14, 19, 23, 27, 27,
440 26, 26, 22, 20, 15, 10, 6, -1, -5, -8, -12, -14, -16, -16, -16, -15, -12, -10,
441 -9, -7, -4, -2, 0, 1, 2, 4, 7, 8, 12, 14, 16, 20, 23, 26, 28, 27, 28, 25, 22,
442 19, 13, 7, 0, -7, -13, -20, -25, -29, -32, -33, -33, -30, -27, -23, -17, -11,
443 -5, 2, 7, 12, 15, 18, 20, 20, 20, 19, 17, 15, 13, 11, 9, 7, 6, 5, 4, 3, 2, 1,
444 -1, -3, -5, -10, -14, -18, -21, -24, -27, -28, -28, -25, -22, -16, -10, -4, 3,
445 11, 17, 23, 27, 30, 31, 31, 29, 26, 21, 16, 10, 5, 1, -4, -8, -11, -12, -13,
446 -12, -11, -9, -9, -7, -5, -4, -3, -3, -3, -3, -4, -4, -4, -4, -3, -1, 1, 4, 7,
447 9, 13, 17, 19, 22, 24, 25, 25, 25, 24, 21, 17, 13, 8, 2, -3, -8, -13, -17, -21,
448 -23, -24, -25, -24, -23, -21, -18, -15, -11, -9, -6, -2, 0, 2, 4, 5, 6, 7, 8, 9,
449 9, 10, 11, 12, 13, 13, 13, 13, 12, 12, 10, 9, 7, 4, 2, -1, -3, -5, -8, -9, -11,
450 -12, -12, -13, -14, -16, -18, -19, -19, -18, -19, -19, -18, -14, -11, -7, -3, 1,
451 6, 10, 15, 19, 21, 22, 23, 23, 22, 19, 16, 12, 7, 3, 0, -3, -7, -11, -13, -13,
452 -13, -13, -13, -11, -10, -9, -7, -4, -4, -4, -3, -2, 2, 4, 4, 8, 11, 14, 17, 20,
453 22, 19, 20, 20, 17, 15, 10, 5, 2, -5, -9, -12, -17, -20, -23, -22, -21, -21,
454 -19, -17, -14, -10, -7, -3, 0, 2, 4, 6, 8, 8, 7, 7, 7, 6, 7, 5, 5, 5, 4, 4, 4,
455 3, 2, -1, -3, -4, -6, -8, -12, -13, -14, -15, -14, -13, -12, -11, -8, -4, -1, 2,
456 5, 8, 11, 13, 14, 16, 15, 14, 12, 11, 10, 7, 4, 2, 0, -1, -3, -4, -4, -5, -5,
457 -4, -3, -3, -3, -2, -2, -2, -2, -2, -3, -3, -4, -3, -3, -3, -2, -1, 0, 2, 3, 5,
458 7, 8, 11, 14, 15, 17, 18, 20, 20, 20, 20, 17, 13, 12, 8, 4, 1, -5, -8, -11, -15,
459 -16, -18, -19, -20, -20, -18, -17, -16, -14, -13, -11, -8, -6, -4, -2, -1, 1, 3,
460 5, 7, 8, 10, 11, 13, 14, 15, 15, 16, 16, 16, 15, 14, 13, 11, 10, 8, 6, 3, 0, -3,
461 -6, -9, -12, -15, -17, -20, -23, -25, -27, -27, -26, -26, -25, -22, -18, -14,
462 -9, -3, 2, 6, 11, 16, 20, 22, 22, 23, 23, 23, 20, 17, 15, 12, 8, 5, 2, 0, -4,
463 -6, -8, -8, -10, -12, -12, -12, -13, -13, -12, -10, -8, -7, -4, 1, 5, 8, 11, 16,
464 18, 19, 20, 21, 20, 18, 15, 12, 9, 4, 0, -4, -7, -11, -13, -15, -17, -17, -17,
465 -17, -16, -15, -13, -12, -10, -9, -7, -5, -4, -4, -2, -2, -1, 0, 0, 1, 1, 1, 0,
466 -1, -2, -1, -2, -4, -5, -4, -4, -4, -3, -3, -3, -2, -1, 0, 1, 0, 0, 1, 1, 1, 0,
467 0, -1, -2, -2, -1, -1, -2, -2, -1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, -1, -2,
468 -2, -3, -3, -4, -4, -3, -3, -3, -2, -1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 3,
469 3, 5, 7, 9, 11, 13, 15, 16, 16, 15, 14, 13, 10, 6, 2, -2, -7, -11, -14, -19,
470 -22, -24, -25, -26, -26, -25, -24, -21, -18, -15, -12, -9, -5, -2, 1, 4, 6, 8,
471 9, 11, 12, 13, 14, 14, 14, 15, 15, 15, 14, 14, 13, 12, 11, 9, 7, 5, 2, -1, -5,
472 -9, -13, -17, -22, -26, -30, -31, -32, -34, -34, -31, -28, -24, -19, -13, -6,
473 -1, 5, 12, 18, 21, 24, 27, 29, 29, 27, 25, 23, 19, 15, 11, 8, 4, 0, -4, -5, -7,
474 -9, -11, -11, -11, -11, -11, -11, -11, -11, -11, -9, -7, -6, -5, -2, 2, 4, 7,
475 11, 13, 15, 17, 19, 20, 19, 19, 17, 15, 12, 9, 5, 1, -4, -8, -11, -15, -19, -21,
476 -23, -24, -24, -23, -22, -21, -19, -16, -13, -10, -7, -5, -2, 0, 2, 3, 3, 3, 3,
477 2, 1, 1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 6, 4, 4, 2, -1, -3, -4, -6,
478 -8, -9, -9, -9, -9, -9, -7, -5, -4, -2, 0, 3, 4, 6, 7, 8, 9, 8, 8, 8, 6, 5, 3,
479 2, 0, -1, -2, -2, -3, -3, -2, -2, -1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2,
480 4, 6, 8, 10, 11, 13, 14, 15, 15, 14, 12, 10, 8, 4, 0, -4, -8, -12, -16, -20,
481 -22, -24, -26, -26, -25, -24, -22, -20, -16, -13, -9, -5, -1, 3, 6, 9, 11, 14,
482 16, 16, 17, 17, 17, 17, 16, 15, 14, 13, 12, 10, 9, 7, 4, 2, -1, -5, -9, -13,
483 -17, -20, -24, -28, -30, -31, -32, -32, -30, -27, -23, -19, -14, -7, -1, 5, 10,
484 15, 21, 24, 26, 28, 29, 28, 26, 24, 21, 18, 13, 9, 5, 2, -1, -4, -7, -8, -9,
485 -10, -11, -11, -11, -11, -11, -11, -11, -11, -11, -9, -7, -8, -5, 0, 1, 4, 10,
486 13, 14, 18, 22, 23, 23, 24, 22, 20, 19, 14, 9, 5, -2, -7, -11, -16, -21, -24,
487 -26, -29, -29, -28, -27, -26, -23, -21, -18, -14, -12, -9, -7, -6, -4, -2, -2,
488 -3, -2, 0, 0, 0, 2, 3, 5, 7, 8, 11, 13, 13, 13, 14, 15, 13, 11, 9, 7, 4, 1, -3,
489 -6, -9, -12, -15, -16, -17, -18, -18, -17, -16, -14, -12, -10, -7, -4, -2, 1, 3,
490 5, 7, 8, 8, 9, 9, 8, 7, 7, 6, 5, 3, 2, 1, 0, -1, -2, -2, -3, -4, -4, -4, -5, -5,
491 -5, -4, -4, -4, -2, -1, 0, 2, 4, 5, 6, 8, 9, 10, 10, 10, 9, 8, 7, 5, 2, -1, -4,
492 -7, -10, -14, -17, -19, -22, -24, -24, -24, -24, -23, -21, -19, -16, -13, -10,
493 -7, -3, 0, 3, 6, 8, 10, 12, 13, 14, 14, 14, 13, 13, 11, 9, 7, 4, 0, -3, -6, -9,
494 -12, -15, -17, -18, -19, -19, -20, -19, -17, -16, -13, -11, -8, -5, -3, 0, 3, 6,
495 7, 9, 11, 12, 12, 12, 12, 12, 11, 10, 9, 9, 7, 6, 4, 4, 2, 1, 0, -1, -2, -3, -4,
496 -5, -6, -7, -8, -9, -9, -10, -10, -10, -10, -9, -8, -7, -4, -1, 2, 4, 9, 13, 15,
497 19, 22, 24, 24, 25, 25, 23, 21, 17, 13, 10, 5, -1, -5, -10, -15, -19, -22, -25,
498 -27, -28, -29, -28, -26, -24, -22, -19, -15, -13, -9, -6, -4, -1, 1, 1, 3, 4, 3,
499 3, 3, 2, 3, 3, 2, 3, 4, 5, 6, 8, 10, 11, 11, 12, 13, 13, 12, 10, 9, 7, 4, 1, -2,
500 -5, -9, -11, -14, -15, -16, -17, -16, -15, -13, -11, -8, -5, -2, 1, 4, 7, 9, 11,
501 12, 12, 12, 12, 11, 9, 7, 5, 3, 1, -1, -2, -3, -5, -5, -6, -6, -6, -5, -5, -3,
502 -1, 0, 2, 4, 7, 7, 9, 11, 11, 11, 12, 12, 11, 10, 8, 6, 4, 2, -1, -4, -7, -10,
503 -12, -14, -16, -18, -19, -20, -20, -19, -19, -18, -17, -15, -13, -11, -9, -7,
504 -4, -2, 0, 3, 6, 7, 9, 11, 12, 13, 14, 14, 13, 13, 12, 10, 8, 5, 1, -2, -5, -8,
505 -12, -14, -17, -19, -19, -20, -21, -20, -19, -17, -15, -12, -10, -7, -4, -1, 2,
506 4, 6, 7, 9, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -3,
507 -4, -5, -6, -8, -8, -9, -10, -10, -9, -8, -7, -5, -3, 0, 2, 6, 9, 11, 14, 16,
508 18, 19, 19, 19, 18, 16, 14, 11, 8, 4, -1, -5, -9, -14, -18, -22, -25, -27, -29,
509 -30, -30, -30, -28, -26, -23, -20, -16, -12, -9, -5, -1, 1, 4, 6, 7, 8, 8, 9, 9,
510 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 8, 8, 7, 5, 4, 2, -1, -3, -6, -8, -10,
511 -12, -14, -14, -15, -14, -14, -12, -10, -8, -6, -3, 0, 3, 5, 8, 10, 11, 13, 13,
512 13, 13, 13, 12, 10, 9, 7, 6, 4, 2, 0, -1, -2, -2, -2, -3, -1, 1, 2, 4, 7, 9, 10,
513 12, 14, 14, 15, 14, 13, 12, 10, 6, 3, 0, -6, -10, -14, -18, -22, -25, -27, -29,
514 -29, -29, -28, -26, -23, -20, -16, -11, -7, -2, 3, 6, 10, 14, 16, 18, 20, 20,
515 19, 19, 16, 14, 11, 7, 4, 1, -2, -6, -9, -11, -12, -13, -14, -14, -13, -11, -11,
516 -9, -7, -5, -4, -3, -1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 5, 6, 7,
517 7, 8, 9, 9, 9, 8, 8, 6, 5, 3, 1, -1, -3, -5, -7, -9, -10, -11, -13, -13, -10,
518 -9, -9, -4, 0, 2, 6, 11, 14, 18, 20, 23, 25, 25, 25, 23, 21, 19, 13, 8, 5, -2,
519 -8, -13, -19, -25, -28, -32, -35, -36, -36, -36, -35, -31, -28, -24, -20, -15,
520 -10, -5, -2, 3, 7, 10, 11, 13, 14, 14, 13, 13, 12, 10, 10, 9, 7, 7, 7, 6, 6, 7,
521 7, 8, 8, 8, 8, 8, 7, 6, 5, 3, 0, -2, -4, -7, -10, -12, -15, -16, -17, -18, -19,
522 -18, -17, -15, -13, -9, -6, -3, 1, 5, 9, 12, 15, 17, 19, 20, 20, 20, 19, 18, 16,
523 13, 10, 8, 5, 2, 1, -2, -3, -2, -2, -2, 0, 2, 3, 5, 7, 9, 10, 11, 11, 10, 9, 8,
524 4, 1, -2, -7, -11, -14, -19, -22, -24, -28, -29, -29, -29, -28, -25, -23, -19,
525 -15, -10, -5, 0, 5, 9, 13, 16, 19, 20, 21, 21, 19, 18, 15, 12, 9, 6, 2, 0, -2,
526 -4, -6, -7, -7, -6, -6, -4, -3, -1, 0, 2, 3, 5, 5, 5, 5, 4, 3, 2, 0, -2, -3, -5,
527 -7, -8, -8, -9, -9, -8, -7, -5, -2, 0, 2, 5, 8, 10, 12, 14, 15, 15, 16, 15, 14,
528 13, 10, 8, 6, 3, 0, -2, -3, -3, -6, -6, -3, -3, -1, 3, 5, 8, 10, 13, 16, 17, 17,
529 18, 15, 15, 13, 8, 5, 1, -6, -9, -14, -21, -24, -27, -31, -33, -33, -33, -32,
530 -31, -28, -25, -21, -17, -12, -8, -3, 1, 4, 8, 10, 12, 14, 16, 15, 15, 15, 14,
531 13, 13, 11, 11, 10, 9, 9, 9, 9, 8, 7, 8, 7, 7, 6, 5, 4, 3, 1, -2, -3, -5, -8,
532 -11, -13, -14, -16, -17, -18, -18, -17, -16, -15, -12, -9, -7, -4, 0, 4, 7, 10,
533 13, 16, 18, 19, 20, 21, 21, 20, 19, 17, 15, 14, 12, 10, 8, 8, 7, 5, 6, 6, 6, 6,
534 6, 7, 7, 6, 5, 3, 1, 0, -4, -7, -9, -14, -17, -20, -24, -25, -27, -29, -30, -28,
535 -28, -26, -24, -21, -16, -13, -10, -5, -1, 3, 6, 9, 12, 15, 16, 17, 18, 18, 18,
536 18, 17, 16, 15, 13, 11, 10, 9, 8, 6, 5, 4, 3, 3, 3, 2, 1, 1, 0, -1, -1, -2, -3,
537 -4, -6, -6, -7, -8, -9, -10, -10, -10, -10, -10, -8, -7, -6, -4, -2, 1, 4, 6, 9,
538 11, 13, 15, 16, 17, 18, 18, 17, 17, 16, 14, 13, 14, 12, 9, 11, 11, 9, 11, 11,
539 10, 11, 10, 10, 11, 9, 8, 6, 2, 2, -2, -7, -9, -14, -18, -20, -26, -27, -28,
540 -32, -33, -32, -32, -30, -29, -27, -23, -19, -16, -11, -6, -1, 3, 7, 11, 16, 18,
541 20, 22, 24, 25, 25, 24, 24, 23, 20, 18, 16, 15, 12, 9, 7, 6, 4, 2, 0, -1, -2,
542 -3, -5, -5, -5, -7, -8, -9, -9, -10, -11, -12, -12, -12, -12, -12, -11, -10, -9,
543 -8, -6, -3, -1, 1, 3, 6, 8, 10, 12, 13, 15, 16, 16, 16, 16, 16, 15, 16, 16, 13,
544 14, 15, 13, 14, 14, 13, 13, 13, 12, 12, 10, 9, 6, 2, 1, -1, -7, -10, -13, -18,
545 -21, -26, -29, -30, -34, -36, -37, -37, -36, -36, -35, -31, -28, -26, -20, -15,
546 -10, -5, -1, 5, 10, 15, 18, 23, 26, 28, 29, 31, 32, 31, 30, 29, 27, 25, 22, 18,
547 15, 13, 8, 5, 2, -1, -4, -7, -9, -11, -13, -15, -16, -17, -17, -18, -18, -18,
548 -17, -17, -16, -15, -14, -12, -11, -9, -7, -5, -3, 0, 2, 5, 7, 9, 12, 14, 16,
549 17, 18, 20, 21, 21, 21, 22, 23, 22, 22, 22, 22, 22, 21, 19, 18, 17, 15, 12, 10,
550 6, 3, -1, -5, -9, -14, -18, -23, -27, -31, -34, -38, -40, -41, -42, -42, -42,
551 -40, -37, -35, -31, -26, -21, -16, -10, -4, 2, 7, 12, 18, 23, 27, 30, 33, 36,
552 38, 39, 39, 40, 39, 37, 35, 33, 30, 27, 22, 19, 15, 10, 6, 1, -3, -7, -11, -14,
553 -17, -19, -22, -24, -25, -25, -26, -26, -25, -24, -23, -21, -19, -16, -14, -11,
554 -8, -4, -1, 3, 6, 10, 13, 16, 19, 22, 25, 27, 29, 31, 33, 34, 36, 36, 36, 36,
555 35, 34, 32, 29, 26, 22, 18, 13, 8, 3, -3, -9, -14, -20, -26, -30, -35, -39, -43,
556 -45, -47, -48, -49, -48, -46, -44, -41, -37, -32, -27, -22, -16, -9, -3, 2, 7,
557 14, 18, 22, 26, 30, 34, 36, 37, 39, 40, 40, 39, 38, 37, 35, 33, 30, 27, 24, 20,
558 16, 12, 9, 4, 0, -4, -7, -11, -15, -18, -21, -23, -25, -27, -28, -28, -29, -29,
559 -28, -26, -25, -23, -20, -17, -14, -11, -7, -3, 1, 4, 9, 13, 17, 21, 26, 30, 34,
560 37, 41, 44, 45, 46, 47, 46, 45, 42, 39, 34, 29, 22, 15, 8, 1, -7, -15, -22, -29,
561 -35, -41, -46, -50, -53, -55, -55, -55, -54, -51, -47, -43, -38, -32, -26, -20,
562 -14, -9, -2, 4, 9, 13, 18, 22, 25, 28, 31, 33, 35, 35, 36, 37, 38, 37, 37, 36,
563 35, 33, 31, 29, 27, 24, 20, 17, 13, 9, 5, 0, -4, -8, -12, -16, -19, -22, -25,
564 -28, -29, -30, -30, -30, -29, -28, -26, -23, -20, -17, -13, -9, -6, -2, 4, 8,
565 11, 17, 21, 24, 29, 32, 35, 37, 38, 38, 38, 37, 35, 32, 27, 25, 19, 13, 8, 2,
566 -3, -10, -16, -20, -24, -29, -33, -36, -38, -40, -41, -40, -39, -38, -36, -33,
567 -29, -26, -23, -19, -14, -11, -8, -3, 0, 3, 6, 9, 13, 16, 18, 21, 23, 26, 27,
568 29, 31, 32, 33, 33, 34, 33, 32, 31, 29, 27, 24, 20, 17, 13, 9, 4, 0, -4, -8,
569 -12, -15, -18, -21, -23, -24, -25, -25, -25, -24, -23, -21, -19, -17, -15, -10,
570 -7, -3, 2, 7, 11, 16, 20, 24, 27, 29, 30, 31, 30, 29, 27, 23, 20, 16, 10, 5, 0,
571 -5, -10, -16, -20, -23, -26, -29, -31, -31, -30, -30, -29, -26, -24, -22, -20,
572 -17, -13, -10, -8, -6, -4, -2, 0, 1, 3, 5, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19,
573 20, 21, 22, 22, 21, 21, 21, 20, 18, 15, 13, 11, 9, 6, 4, 1, -1, -4, -6, -7, -8,
574 -9, -11, -11, -11, -11, -11, -10, -10, -9, -7, -6, -3, 0, 2, 5, 8, 11, 14, 15,
575 17, 18, 19, 18, 17, 16, 14, 12, 9, 5, 2, -2, -6, -10, -13, -17, -19, -22, -23,
576 -25, -26, -26, -26, -25, -24, -23, -21, -19, -18, -16, -14, -11, -10, -8, -6,
577 -4, -2, 0, 3, 5, 7, 9, 11, 14, 16, 17, 18, 21, 22, 22, 23, 23, 23, 22, 21, 20,
578 19, 17, 14, 12, 9, 7, 4, 2, 0, -2, -4, -6, -7, -8, -8, -8, -9, -8, -8, -7, -6,
579 -5, -3, 0, 1, 3, 7, 10, 12, 14, 17, 18, 19, 18, 18, 18, 17, 13, 10, 8, 5, 1, -3,
580 -7, -10, -14, -18, -20, -23, -24, -26, -28, -28, -28, -28, -27, -26, -24, -23,
581 -22, -20, -17, -15, -13, -12, -9, -6, -5, -2, 0, 3, 5, 6, 9, 11, 13, 15, 17, 18,
582 19, 20, 21, 21, 21, 21, 20, 18, 17, 16, 14, 11, 9, 7, 5, 3, 1, -1, -2, -3, -4,
583 -5, -5, -5, -5, -5, -4, -3, -2, -1, 2, 4, 5, 8, 10, 11, 13, 13, 13, 13, 12, 10,
584 9, 7, 4, 1, -2, -4, -7, -10, -13, -15, -17, -20, -22, -22, -23, -24, -24, -24,
585 -24, -23, -22, -21, -20, -19, -18, -16, -14, -12, -11, -10, -8, -7, -6, -4, -3,
586 -1, -1, 0, 2, 3, 5, 7, 8, 9, 10, 10, 12, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7,
587 7, 7, 7, 7, 7, 6, 6, 7, 7, 7, 8, 8, 8, 9, 10, 10, 11, 11, 11, 11, 11, 9, 8, 7,
588 5, 2, 0, -2, -5, -7, -10, -13, -15, -18, -20, -21, -22, -24, -25, -24, -25, -25,
589 -24, -24, -23, -21, -21, -19, -17, -15, -13, -12, -9, -7, -6, -4, -2, -1, 0, 0,
590 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 3, 3, 3, 4, 5, 6, 6,
591 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, 18, 16, 16, 15, 12, 10,
592 8, 5, 2, -1, -4, -7, -10, -13, -16, -18, -21, -23, -25, -26, -27, -29, -29, -29,
593 -29, -29, -29, -28, -26, -25, -24, -22, -19, -16, -14, -11, -9, -6, -4, -3, -2,
594 0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 7,
595 6, 7, 7, 7, 7, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 15, 14, 12,
596 11, 9, 6, 4, 1, -1, -3, -6, -8, -11, -13, -15, -17, -19, -20, -22, -23, -24,
597 -25, -26, -27, -27, -27, -26, -26, -25, -22, -20, -18, -16, -14, -12, -10, -10,
598 -10, -9, -8, -7, -6, -4, -3, -2, -1, -1, 0, 0, 1, 1, 1, 2, 3, 4, 4, 5, 7, 8, 9,
599 10, 12, 13, 13, 14, 15, 16, 17, 17, 18, 19, 19, 19, 20, 20, 21, 20, 20, 19, 18,
600 17, 15, 13, 11, 8, 5, 2, -1, -3, -7, -10, -12, -15, -17, -20, -22, -24, -25,
601 -27, -28, -29, -29, -30, -30, -29, -28, -27, -25, -23, -20, -16, -14, -11, -9,
602 -8, -8, -7, -7, -7, -5, -4, -4, -4, -3, -3, -3, -3, -4, -4, -4, -5, -5, -4, -4,
603 -4, -3, -2, -1, 1, 2, 3, 5, 7, 8, 10, 11, 13, 14, 15, 17, 19, 20, 21, 22, 24,
604 24, 25, 25, 24, 24, 22, 21, 19, 17, 15, 13, 10, 8, 5, 2, 0, -2, -5, -8, -11,
605 -14, -16, -18, -20, -23, -25, -27, -29, -30, -30, -31, -30, -29, -28, -26, -23,
606 -21, -18, -16, -17, -16, -18, -16, -11, -11, -12, -13, -10, -6, -5, -5, -7, -6,
607 -4, -2, -2, -2, -2, 0, 2, 3, 4, 5, 7, 8, 10, 10, 11, 12, 13, 14, 15, 16, 16, 17,
608 19, 20, 20, 21, 21, 21, 21, 20, 20, 19, 17, 16, 14, 12, 11, 9, 7, 5, 3, 1, -1,
609 -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -22, -23, -24, -25, -25, -24, -23,
610 -22, -20, -19, -17, -16, -16, -16, -16, -16, -16, -15, -14, -13, -13, -13, -12,
611 -11, -10, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 2, 4, 5, 6, 8, 10, 11, 13, 14,
612 16, 18, 20, 21, 23, 24, 25, 26, 26, 26, 26, 25, 24, 23, 22, 20, 17, 15, 13, 11,
613 8, 6, 4, 1, -1, -4, -6, -9, -11, -13, -16, -18, -20, -22, -24, -25, -26, -27,
614 -26, -26, -24, -23, -21, -20, -19, -19, -19, -19, -18, -18, -18, -17, -16, -15,
615 -14, -13, -12, -11, -10, -9, -7, -6, -5, -3, -1, 0, 2, 4, 5, 7, 8, 10, 11, 12,
616 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 22, 22, 21, 20, 20, 19, 17, 16, 15,
617 13, 12, 10, 8, 6, 4, 2, 0, -2, -4, -5, -8, -10, -12, -14, -16, -18, -19, -21,
618 -22, -23, -23, -22, -21, -21, -20, -19, -18, -18, -19, -20, -21, -21, -21, -20,
619 -19, -18, -18, -17, -16, -14, -12, -11, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10,
620 12, 14, 15, 17, 19, 20, 22, 23, 25, 26, 26, 27, 28, 28, 27, 27, 26, 25, 23, 21,
621 19, 17, 15, 12, 10, 8, 5, 2, 0, -3, -5, -8, -11, -13, -16, -18, -20, -22, -24,
622 -26, -27, -27, -28, -28, -27, -25, -23, -21, -20, -19, -18, -18, -20, -19, -18,
623 -18, -17, -16, -15, -14, -13, -11, -9, -8, -6, -5, -3, -1, 0, 2, 4, 6, 8, 9, 11,
624 13, 14, 15, 16, 18, 19, 20, 21, 21, 22, 22, 23, 23, 22, 22, 22, 21, 19, 18, 17,
625 16, 14, 12, 11, 9, 7, 5, 3, 1, -2, -5, -7, -10, -13, -15, -18, -20, -23, -25,
626 -26, -27, -28, -27, -26, -25, -23, -22, -20, -20, -21, -22, -24, -24, -24, -24,
627 -23, -22, -21, -20, -18, -15, -13, -11, -9, -7, -5, -3, -1, 2, 4, 6, 8, 10, 12,
628 14, 16, 18, 19, 20, 22, 23, 25, 26, 26, 27, 27, 27, 27, 27, 25, 24, 23, 21, 19,
629 17, 14, 12, 10, 7, 4, 2, 0, -3, -5, -8, -10, -13, -16, -18, -20, -23, -25, -27,
630 -28, -30, -31, -31, -30, -29, -27, -25, -23, -21, -21, -21, -22, -22, -22, -22,
631 -21, -20, -18, -17, -15, -13, -10, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13,
632 15, 17, 18, 20, 21, 22, 24, 25, 26, 27, 27, 27, 27, 27, 26, 25, 23, 22, 20, 18,
633 16, 14, 12, 9, 6, 4, 1, -1, -4, -7, -9, -13, -15, -18, -20, -22, -26, -27, -29,
634 -30, -31, -31, -30, -29, -27, -25, -23, -20, -19, -19, -18, -18, -18, -19, -20,
635 -19, -19, -18, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 4, 5, 7, 9, 11, 13,
636 16, 17, 19, 21, 23, 25, 26, 28, 29, 30, 30, 30, 30, 30, 28, 27, 26, 23, 22, 19,
637 16, 15, 12, 8, 5, 3, 0, -3, -6, -9, -12, -15, -19, -22, -24, -27, -30, -32, -33,
638 -34, -35, -35, -34, -33, -31, -29, -26, -23, -21, -20, -20, -19, -19, -19, -18,
639 -17, -17, -16, -15, -12, -10, -7, -5, -3, 0, 2, 4, 7, 9, 10, 12, 14, 15, 17, 19,
640 21, 22, 24, 25, 26, 28, 28, 29, 29, 28, 28, 27, 26, 25, 22, 20, 18, 16, 13, 10,
641 8, 5, 3, -1, -3, -5, -7, -10, -12, -15, -17, -20, -22, -24, -26, -29, -31, -33,
642 -34, -35, -35, -34, -33, -32, -30, -27, -23, -21, -20, -20, -19, -19, -19, -19,
643 -18, -17, -16, -15, -13, -10, -8, -5, -4, -1, 1, 3, 5, 7, 9, 11, 12, 14, 16, 18,
644 20, 21, 23, 24, 26, 28, 29, 30, 30, 30, 30, 29, 29, 27, 26, 23, 21, 18, 15, 12,
645 9, 5, 2, -1, -4, -7, -10, -13, -16, -19, -22, -25, -26, -28, -31, -33, -35, -36,
646 -37, -38, -37, -37, -36, -34, -32, -28, -25, -23, -21, -20, -19, -18, -17, -17,
647 -16, -16, -15, -14, -11, -9, -6, -4, -2, 1, 3, 5, 8, 10, 12, 14, 15, 17, 19, 21,
648 23, 25, 26, 27, 29, 30, 31, 32, 32, 32, 31, 30, 29, 28, 25, 22, 19, 16, 13, 10,
649 7, 4, 0, -3, -6, -8, -11, -14, -16, -19, -21, -23, -26, -27, -29, -31, -34, -35,
650 -35, -36, -36, -36, -36, -34, -32, -29, -26, -23, -22, -20, -19, -18, -17, -17,
651 -16, -16, -15, -14, -13, -11, -8, -6, -3, -1, 1, 4, 6, 9, 11, 12, 14, 15, 17,
652 19, 21, 23, 24, 26, 27, 29, 31, 32, 33, 33, 34, 32, 32, 30, 28, 27, 24, 20, 18,
653 15, 11, 9, 4, 1, -2, -6, -9, -11, -15, -18, -20, -23, -26, -28, -31, -33, -35,
654 -38, -39, -39, -40, -40, -40, -40, -37, -34, -32, -28, -25, -23, -21, -21, -19,
655 -18, -17, -17, -16, -14, -14, -12, -9, -7, -4, -2, 1, 4, 6, 9, 11, 12, 14, 15,
656 17, 19, 20, 22, 23, 24, 26, 27, 29, 30, 31, 32, 32, 32, 31, 30, 29, 27, 24, 21,
657 18, 15, 12, 9, 6, 2, -1, -4, -6, -9, -12, -13, -16, -19, -21, -23, -25, -28,
658 -30, -33, -35, -36, -38, -39, -39, -38, -38, -37, -35, -32, -29, -27, -24, -23,
659 -21, -20, -20, -19, -18, -18, -17, -16, -15, -12, -10, -8, -5, -2, 1, 3, 6, 8,
660 10, 12, 14, 15, 17, 19, 21, 22, 24, 26, 27, 29, 31, 32, 32, 33, 33, 32, 32, 30,
661 28, 27, 23, 20, 17, 13, 10, 7, 3, 0, -4, -6, -8, -11, -13, -15, -17, -19, -22,
662 -24, -27, -29, -32, -34, -36, -37, -38, -39, -39, -39, -38, -37, -34, -32, -29,
663 -26, -25, -22, -21, -20, -19, -19, -18, -17, -16, -14, -12, -9, -7, -4, -1, 2,
664 4, 7, 9, 11, 13, 14, 16, 18, 20, 22, 24, 25, 27, 28, 29, 31, 32, 33, 33, 34, 32,
665 31, 30, 28, 25, 23, 20, 16, 14, 10, 6, 4, 0, -3, -5, -8, -10, -12, -14, -16,
666 -19, -21, -23, -25, -27, -30, -32, -34, -35, -36, -37, -37, -37, -36, -35, -34,
667 -31, -28, -27, -25, -23, -22, -20, -20, -19, -18, -17, -16, -15, -12, -9, -6,
668 -3, 0, 3, 6, 7, 10, 12, 14, 16, 17, 19, 21, 23, 24, 26, 28, 29, 31, 32, 32, 33,
669 33, 32, 32, 30, 29, 26, 23, 22, 17, 14, 12, 8, 6, 3, -1, -2, -6, -9, -10, -13,
670 -15, -17, -20, -22, -24, -26, -28, -30, -32, -33, -34, -35, -36, -36, -36, -35,
671 -34, -32, -30, -28, -27, -25, -24, -23, -22, -22, -22, -20, -19, -17, -15, -12,
672 -9, -7, -4, -1, 2, 5, 7, 9, 12, 14, 16, 18, 21, 23, 25, 27, 29, 31, 32, 34, 35,
673 36, 36, 35, 34, 33, 32, 30, 26, 24, 20, 16, 14, 11, 7, 6, 3, -1, -2, -5, -8, -9,
674 -12, -15, -16, -20, -22, -23, -26, -28, -28, -31, -32, -33, -35, -34, -34, -35,
675 -34, -33, -32, -30, -28, -27, -25, -23, -22, -21, -20, -20, -19, -18, -17, -15,
676 -12, -10, -6, -4, -1, 2, 4, 7, 9, 11, 14, 15, 17, 19, 22, 23, 26, 28, 30, 31,
677 33, 34, 35, 35, 35, 35, 34, 32, 31, 28, 25, 23, 19, 17, 15, 12, 9, 8, 5, 3, 1,
678 -2, -5, -7, -11, -14, -15, -19, -21, -22, -25, -27, -28, -31, -31, -32, -34,
679 -34, -34, -35, -34, -33, -32, -30, -29, -28, -27, -25, -25, -24, -23, -23, -21,
680 -20, -18, -15, -13, -11, -7, -5, -2, 1, 3, 6, 8, 10, 13, 15, 17, 20, 23, 24, 27,
681 30, 32, 34, 35, 36, 38, 38, 37, 37, 35, 35, 32, 29, 27, 24, 20, 19, 16, 13, 13,
682 10, 7, 6, 2, -1, -3, -7, -10, -12, -16, -18, -19, -22, -24, -25, -28, -29, -30,
683 -31, -32, -33, -34, -34, -34, -34, -33, -32, -31, -29, -28, -28, -26, -26, -26,
684 -24, -24, -22, -20, -18, -16, -13, -11, -8, -5, -3, 0, 2, 4, 6, 9, 10, 13, 15,
685 18, 21, 23, 26, 29, 31, 33, 35, 36, 37, 37, 37, 37, 35, 33, 31, 28, 25, 23, 19,
686 18, 17, 14, 13, 12, 8, 7, 4, 0, -3, -6, -9, -11, -14, -17, -19, -21, -24, -25,
687 -27, -29, -30, -31, -33, -34, -35, -36, -36, -36, -36, -35, -34, -34, -33, -32,
688 -31, -30, -29, -29, -27, -25, -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 3, 4,
689 7, 9, 11, 14, 17, 19, 22, 25, 26, 31, 32, 35, 36, 36, 37, 37, 36, 35, 34, 32,
690 29, 26, 23, 22, 20, 18, 17, 16, 14, 12, 10, 7, 4, 1, -3, -5, -8, -11, -14, -16,
691 -18, -20, -22, -23, -25, -26, -27, -28, -30, -31, -32, -33, -34, -34, -34, -34,
692 -34, -33, -32, -31, -30, -29, -28, -27, -25, -23, -21, -18, -16, -13, -10, -8,
693 -6, -3, -1, 1, 3, 5, 8, 10, 12, 15, 17, 20, 23, 26, 29, 31, 33, 35, 37, 37, 38,
694 38, 37, 36, 35, 33, 30, 28, 26, 23, 22, 21, 20, 19, 17, 15, 14, 10, 7, 4, 0, -3,
695 -6, -9, -12, -14, -17, -19, -20, -22, -24, -25, -26, -27, -28, -30, -31, -32,
696 -34, -35, -35, -35, -35, -34, -34, -32, -30, -29, -27, -25, -24, -22, -20, -18,
697 -16, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 10, 12, 14, 17, 20, 23, 25, 28,
698 31, 33, 35, 36, 37, 38, 37, 37, 35, 34, 32, 30, 27, 25, 24, 22, 21, 20, 20, 17,
699 16, 14, 10, 7, 3, -2, -5, -7, -11, -13, -15, -18, -20, -22, -24, -24, -26, -27,
700 -28, -29, -30, -31, -33, -34, -35, -36, -36, -36, -36, -35, -34, -32, -30, -28,
701 -26, -23, -21, -20, -18, -16, -14, -12, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 10,
702 12, 15, 18, 21, 23, 26, 29, 31, 34, 35, 36, 37, 38, 36, 36, 35, 32, 30, 29, 26,
703 23, 22, 20, 20, 19, 18, 16, 14, 11, 8, 4, 0, -5, -8, -12, -16, -17, -20, -22,
704 -23, -25, -26, -27, -27, -28, -29, -29, -31, -31, -33, -34, -35, -37, -37, -38,
705 -38, -37, -35, -34, -31, -28, -25, -22, -19, -17, -15, -14, -13, -12, -10, -9,
706 -7, -6, -4, -1, 0, 3, 5, 7, 10, 12, 15, 18, 22, 25, 27, 31, 33, 34, 36, 37, 38,
707 38, 37, 36, 36, 33, 30, 29, 26, 23, 22, 21, 19, 19, 18, 16, 14, 11, 8, 3, -1,
708 -6, -10, -13, -16, -19, -20, -21, -23, -23, -24, -24, -24, -25, -26, -26, -27,
709 -29, -30, -32, -34, -35, -37, -37, -37, -37, -36, -34, -32, -29, -25, -21, -17,
710 -14, -13, -11, -10, -10, -10, -9, -8, -7, -5, -3, 0, 3, 6, 8, 11, 14, 17, 19,
711 23, 26, 28, 31, 34, 35, 37, 38, 38, 39, 39, 38, 37, 36, 34, 31, 29, 26, 24, 21,
712 19, 17, 16, 14, 12, 10, 7, 3, -1, -5, -9, -12, -16, -18, -19, -20, -20, -21,
713 -21, -21, -22, -22, -23, -24, -25, -26, -28, -29, -30, -33, -34, -35, -36, -36,
714 -36, -35, -34, -32, -30, -27, -24, -20, -17, -15, -12, -10, -10, -9, -8, -8, -7,
715 -6, -5, -2, 1, 4, 8, 12, 15, 18, 20, 23, 26, 28, 30, 32, 34, 36, 37, 38, 39, 40,
716 40, 39, 38, 37, 35, 33, 30, 28, 24, 20, 17, 14, 12, 10, 8, 7, 5, 2, -1, -5, -9,
717 -12, -16, -19, -19, -21, -21, -21, -22, -21, -23, -24, -24, -26, -26, -28, -29,
718 -31, -32, -34, -35, -36, -38, -38, -37, -37, -35, -32, -30, -28, -25, -23, -19,
719 -17, -14, -11, -10, -7, -6, -5, -3, -2, -1, 1, 4, 7, 11, 14, 18, 21, 23, 26, 28,
720 30, 32, 34, 36, 37, 38, 39, 41, 40, 41, 40, 39, 39, 37, 36, 33, 30, 27, 22, 17,
721 14, 9, 6, 4, 3, 2, 1, -2, -5, -7, -11, -16, -19, -22, -23, -25, -25, -25, -25,
722 -26, -27, -27, -28, -29, -31, -32, -32, -34, -35, -35, -37, -38, -39, -40, -39,
723 -37, -35, -33, -29, -27, -24, -21, -18, -16, -13, -11, -8, -5, -3, 0, 2, 4, 6,
724 8, 10, 14, 17, 20, 24, 27, 29, 32, 34, 36, 38, 39, 40, 42, 43, 44, 45, 45, 45,
725 44, 43, 42, 38, 39, 36, 28, 29, 21, 16, 14, 5, 0, -2, -6, -9, -7, -10, -12, -11,
726 -15, -19, -21, -26, -30, -30, -32, -33, -30, -30, -30, -29, -30, -32, -32, -34,
727 -35, -35, -36, -36, -35, -37, -38, -37, -38, -37, -35, -33, -29, -25, -22, -18,
728 -15, -13, -10, -8, -6, -3, -1, 2, 6, 8, 10, 13, 15, 18, 22, 24, 27, 31, 33, 37,
729 40, 41, 43, 45, 45, 46, 48, 49, 49, 50, 50, 49, 48, 46, 43, 40, 36, 32, 27, 22,
730 17, 11, 5, -1, -7, -11, -16, -19, -19, -21, -21, -22, -24, -27, -28, -32, -36,
731 -36, -38, -38, -36, -35, -34, -33, -34, -35, -35, -36, -38, -38, -38, -37, -37,
732 -37, -36, -36, -34, -34, -33, -29, -25, -22, -18, -14, -11, -7, -5, -3, 0, 2, 4,
733 7, 10, 13, 17, 21, 24, 27, 30, 32, 35, 38, 40, 43, 45, 47, 49, 50, 50, 51, 52,
734 52, 52, 52, 51, 50, 48, 44, 40, 37, 31, 26, 21, 14, 8, 2, -5, -11, -15, -23,
735 -25, -26, -28, -29, -29, -30, -31, -32, -38, -39, -41, -46, -45, -44, -43, -40,
736 -38, -39, -37, -37, -40, -38, -40, -40, -37, -38, -36, -34, -33, -33, -30, -29,
737 -27, -22, -20, -15, -10, -5, -1, 2, 4, 7, 9, 11, 14, 17, 20, 24, 27, 30, 34, 36,
738 38, 41, 43, 45, 48, 50, 51, 54, 55, 55, 55, 55, 54, 53, 52, 50, 49, 47, 43, 39,
739 36, 30, 24, 21, 14, 7, 3, -4, -11, -14, -21, -28, -29, -35, -41, -41, -44, -47,
740 -45, -48, -48, -46, -48, -48, -47, -47, -47, -46, -46, -44, -43, -43, -41, -39,
741 -39, -37, -36, -34, -32, -30, -28, -25, -23, -19, -15, -12, -7, -4, 0, 4, 8, 10,
742 14, 17, 19, 22, 25, 27, 31, 34, 35, 38, 41, 42, 45, 47, 48, 50, 51, 52, 52, 53,
743 54, 52, 52, 52, 50, 49, 48, 44, 42, 40, 34, 31, 27, 20, 15, 10, 4, -3, -8, -16,
744 -21, -27, -35, -39, -44, -48, -51, -54, -56, -56, -58, -59, -58, -57, -56, -54,
745 -54, -54, -51, -50, -48, -44, -42, -39, -36, -35, -32, -30, -29, -27, -24, -22,
746 -17, -14, -11, -4, 0, 2, 7, 9, 12, 16, 18, 20, 25, 27, 29, 33, 35, 36, 38, 40,
747 41, 43, 45, 47, 49, 50, 51, 52, 51, 51, 51, 50, 48, 47, 47, 45, 44, 42, 39, 37,
748 33, 27, 23, 19, 12, 7, 3, -5, -11, -15, -24, -28, -33, -43, -46, -49, -56, -58,
749 -59, -64, -62, -62, -66, -63, -61, -62, -59, -55, -55, -51, -47, -47, -41, -39,
750 -38, -33, -30, -29, -25, -21, -19, -14, -11, -8, -3, 1, 5, 8, 13, 17, 19, 23,
751 26, 28, 32, 33, 35, 38, 40, 41, 44, 46, 47, 49, 51, 51, 53, 53, 52, 53, 53, 51,
752 51, 50, 48, 46, 45, 43, 41, 39, 36, 33, 29, 25, 20, 15, 11, 4, -2, -7, -13, -22,
753 -26, -32, -40, -44, -50, -55, -56, -60, -65, -64, -66, -70, -68, -67, -68, -65,
754 -63, -61, -57, -53, -51, -47, -42, -40, -35, -32, -27, -23, -20, -16, -12, -8,
755 -4, 1, 6, 12, 17, 21, 26, 29, 32, 35, 37, 40, 42, 43, 46, 49, 49, 52, 54, 54,
756 55, 56, 55, 56, 56, 54, 54, 54, 51, 50, 49, 45, 43, 42, 38, 35, 34, 30, 26, 25,
757 19, 14, 10, 4, -2, -7, -14, -20, -24, -31, -37, -41, -47, -52, -58, -60, -64,
758 -68, -69, -71, -71, -73, -72, -72, -71, -69, -68, -64, -61, -57, -53, -48, -43,
759 -38, -33, -29, -23, -18, -15, -9, -4, 2, 6, 13, 19, 24, 29, 33, 38, 41, 44, 47,
760 49, 51, 53, 55, 56, 58, 59, 60, 60, 60, 60, 59, 59, 58, 56, 55, 53, 51, 49, 46,
761 43, 40, 37, 33, 30, 26, 22, 18, 14, 9, 4, -2, -8, -12, -19, -25, -30, -36, -43,
762 -46, -53, -57, -59, -66, -70, -70, -74, -78, -76, -77, -77, -75, -74, -73, -68,
763 -66, -65, -59, -54, -51, -46, -40, -36, -30, -25, -20, -13, -8, -2, 4, 10, 17,
764 23, 28, 34, 40, 43, 46, 51, 53, 54, 57, 59, 59, 62, 63, 63, 66, 65, 64, 65, 65,
765 62, 61, 60, 57, 54, 52, 49, 46, 43, 39, 35, 32, 28, 23, 19, 16, 10, 4, 0, -7,
766 -14, -19, -26, -33, -37, -44, -50, -54, -58, -63, -68, -70, -74, -77, -79, -80,
767 -81, -81, -80, -80, -78, -75, -72, -69, -64, -59, -56, -50, -44, -39, -34, -29,
768 -21, -15, -9, -2, 4, 11, 19, 25, 30, 37, 43, 47, 52, 56, 59, 62, 64, 65, 67, 68,
769 69, 70, 71, 71, 70, 71, 70, 68, 66, 64, 61, 58, 55, 51, 48, 45, 40, 36, 33, 28,
770 23, 18, 13, 9, 2, -3, -9, -16, -21, -29, -37, -41, -45, -55, -60, -62, -67, -73,
771 -76, -77, -80, -81, -84, -85, -83, -82, -84, -82, -76, -75, -73, -67, -62, -58,
772 -52, -47, -42, -34, -29, -23, -15, -8, 0, 6, 14, 23, 29, 35, 44, 49, 52, 59, 62,
773 65, 69, 71, 72, 75, 78, 77, 78, 81, 79, 78, 78, 77, 74, 72, 69, 64, 62, 57, 52,
774 49, 44, 38, 34, 30, 24, 19, 14, 9, 3, -4, -10, -17, -24, -30, -37, -46, -50,
775 -55, -66, -66, -72, -78, -80, -84, -88, -89, -89, -91, -91, -90, -88, -88, -86,
776 -78, -78, -73, -66, -64, -55, -50, -44, -38, -29, -23, -17, -9, -2, 7, 15, 22,
777 31, 37, 44, 52, 57, 61, 68, 70, 73, 77, 77, 79, 82, 82, 82, 82, 83, 82, 80, 79,
778 77, 73, 70, 67, 61, 58, 53, 47, 44, 38, 32, 28, 23, 17, 11, 5, -1, -8, -15, -21,
779 -27, -35, -39, -48, -54, -56, -65, -69, -72, -77, -81, -85, -88, -89, -90, -91,
780 -91, -93, -87, -87, -87, -79, -76, -73, -66, -62, -55, -48, -42, -36, -29, -21,
781 -15, -9, 1, 9, 16, 25, 32, 41, 47, 54, 61, 65, 70, 72, 74, 78, 79, 80, 82, 82,
782 82, 83, 82, 82, 80, 78, 76, 72, 69, 65, 59, 56, 51, 45, 41, 36, 32, 26, 22, 18,
783 12, 6, 0, -5, -11, -19, -24, -31, -38, -42, -49, -56, -58, -62, -70, -72, -73,
784 -80, -81, -83, -87, -86, -86, -88, -87, -84, -82, -80, -78, -69, -67, -65, -54,
785 -51, -46, -35, -33, -27, -18, -13, -6, 1, 10, 18, 24, 34, 41, 47, 56, 61, 65,
786 69, 72, 74, 75, 78, 78, 77, 80, 78, 77, 79, 77, 76, 74, 71, 68, 65, 61, 57, 52,
787 48, 42, 37, 34, 29, 24, 21, 17, 13, 7, 2, -2, -9, -15, -21, -28, -34, -39, -47,
788 -52, -54, -61, -66, -68, -72, -75, -79, -80, -82, -85, -83, -86, -87, -83, -82,
789 -82, -76, -72, -68, -63, -57, -51, -46, -38, -32, -29, -20, -15, -10, -1, 4, 12,
790 19, 27, 35, 41, 51, 57, 60, 67, 70, 72, 75, 76, 76, 76, 76, 76, 74, 75, 75, 72,
791 72, 70, 66, 65, 60, 56, 53, 47, 42, 37, 33, 30, 25, 21, 18, 14, 10, 5, 1, -3,
792 -9, -15, -21, -26, -32, -38, -43, -50, -53, -56, -64, -65, -69, -72, -74, -79,
793 -81, -79, -83, -85, -81, -83, -79, -79, -76, -70, -68, -62, -58, -51, -44, -40,
794 -33, -28, -20, -17, -11, -2, 3, 8, 17, 24, 30, 40, 45, 52, 59, 62, 66, 68, 72,
795 73, 71, 73, 73, 72, 71, 71, 70, 69, 67, 65, 62, 61, 58, 53, 51, 46, 41, 38, 33,
796 30, 27, 23, 21, 18, 15, 12, 8, 4, -2, -7, -12, -18, -24, -29, -33, -39, -44,
797 -48, -52, -56, -60, -65, -66, -72, -75, -77, -80, -80, -83, -83, -80, -79, -78,
798 -72, -69, -63, -58, -56, -47, -43, -38, -32, -27, -20, -16, -11, -4, 3, 10, 16,
799 24, 33, 39, 46, 53, 58, 65, 66, 68, 71, 70, 71, 70, 69, 70, 68, 67, 67, 66, 65,
800 64, 61, 58, 55, 51, 46, 42, 38, 32, 30, 26, 24, 21, 20, 19, 17, 16, 13, 10, 7,
801 1, -5, -9, -15, -21, -26, -30, -33, -39, -42, -42, -51, -53, -53, -62, -65, -67,
802 -72, -76, -78, -78, -80, -79, -77, -74, -71, -66, -61, -58, -51, -45, -43, -39,
803 -30, -27, -24, -17, -14, -8, 0, 3, 11, 20, 27, 35, 41, 49, 55, 58, 62, 64, 64,
804 64, 65, 64, 62, 63, 62, 61, 63, 61, 60, 61, 59, 55, 52, 48, 45, 39, 33, 30, 25,
805 22, 20, 18, 18, 19, 18, 16, 15, 13, 9, 5, -1, -8, -11, -18, -24, -27, -31, -35,
806 -38, -41, -43, -45, -51, -54, -56, -64, -68, -72, -77, -77, -82, -81, -79, -77,
807 -73, -70, -64, -58, -53, -49, -44, -38, -34, -30, -26, -21, -18, -12, -9, -2, 5,
808 11, 20, 25, 34, 42, 47, 53, 57, 59, 61, 61, 59, 59, 59, 58, 56, 56, 56, 56, 57,
809 56, 56, 55, 52, 49, 44, 40, 35, 29, 24, 20, 18, 17, 17, 17, 18, 19, 19, 18, 16,
810 14, 9, 3, -4, -8, -15, -21, -24, -28, -31, -33, -36, -38, -40, -41, -47, -53,
811 -55, -63, -70, -71, -77, -81, -79, -79, -79, -75, -67, -64, -59, -50, -48, -43,
812 -37, -35, -32, -28, -24, -22, -18, -13, -7, 0, 8, 15, 24, 33, 40, 47, 52, 57,
813 58, 58, 58, 56, 57, 56, 54, 54, 55, 55, 56, 57, 57, 57, 56, 53, 48, 44, 38, 31,
814 26, 20, 16, 14, 13, 14, 16, 17, 19, 21, 20, 19, 16, 13, 7, 0, -7, -12, -17, -22,
815 -24, -27, -28, -28, -29, -33, -33, -36, -44, -49, -57, -62, -68, -74, -77, -80,
816 -78, -76, -74, -69, -61, -56, -52, -47, -42, -38, -36, -33, -32, -29, -25, -22,
817 -19, -12, -4, 2, 10, 19, 27, 34, 41, 46, 49, 52, 53, 52, 50, 51, 50, 49, 50, 50,
818 51, 53, 55, 55, 55, 55, 52, 49, 44, 39, 33, 28, 24, 19, 17, 19, 20, 21, 24, 26,
819 28, 28, 28, 25, 20, 16, 9, 0, -5, -10, -15, -17, -19, -21, -22, -22, -26, -31,
820 -30, -38, -46, -53, -62, -66, -75, -81, -80, -81, -81, -76, -74, -67, -59, -58,
821 -52, -47, -44, -42, -41, -37, -34, -31, -29, -23, -15, -10, -2, 6, 15, 24, 29,
822 35, 42, 46, 48, 49, 50, 51, 50, 50, 49, 52, 54, 53, 55, 56, 57, 56, 54, 52, 49,
823 44, 39, 33, 28, 24, 20, 19, 18, 19, 21, 22, 25, 26, 26, 27, 24, 21, 16, 11, 6,
824 -1, -6, -9, -12, -15, -16, -16, -18, -20, -25, -28, -31, -40, -47, -54, -62,
825 -68, -74, -79, -78, -79, -78, -74, -70, -65, -61, -56, -53, -49, -46, -45, -41,
826 -38, -35, -31, -27, -20, -13, -8, 0, 9, 16, 22, 28, 34, 38, 42, 44, 45, 48, 48,
827 48, 49, 50, 52, 52, 53, 54, 54, 54, 53, 50, 48, 44, 41, 36, 32, 29, 23, 21, 20,
828 19, 19, 20, 22, 23, 24, 25, 24, 23, 21, 18, 14, 10, 6, 0, -4, -5, -9, -10, -11,
829 -13, -15, -19, -24, -27, -33, -41, -48, -56, -60, -67, -73, -73, -74, -75, -72,
830 -70, -67, -61, -59, -56, -52, -48, -46, -44, -40, -37, -33, -28, -23, -15, -10,
831 -3, 3, 9, 17, 20, 25, 32, 34, 37, 40, 42, 45, 46, 48, 50, 51, 52, 52, 53, 53,
832 52, 51, 49, 47, 44, 40, 38, 34, 31, 29, 25, 24, 22, 21, 21, 21, 23, 23, 23, 25,
833 23, 22, 21, 18, 15, 11, 8, 3, 0, -2, -6, -8, -10, -14, -17, -20, -25, -31, -36,
834 -42, -49, -56, -62, -65, -70, -74, -73, -74, -72, -70, -68, -63, -60, -56, -53,
835 -50, -45, -43, -39, -35, -30, -24, -20, -13, -7, -2, 5, 9, 15, 20, 25, 30, 32,
836 37, 40, 41, 46, 46, 48, 50, 49, 51, 50, 50, 50, 48, 48, 45, 42, 40, 37, 36, 33,
837 30, 28, 25, 24, 22, 20, 21, 20, 22, 22, 23, 23, 23, 23, 23, 21, 19, 16, 13, 8,
838 5, 2, -2, -4, -7, -10, -13, -16, -21, -28, -30, -36, -45, -48, -56, -62, -64,
839 -71, -71, -72, -73, -70, -70, -66, -61, -59, -55, -51, -47, -44, -39, -35, -32,
840 -25, -21, -17, -8, -5, 2, 8, 12, 18, 22, 28, 31, 34, 39, 40, 44, 46, 46, 49, 48,
841 49, 50, 47, 49, 47, 45, 44, 42, 40, 37, 35, 33, 30, 29, 26, 23, 21, 19, 19, 18,
842 18, 19, 19, 21, 22, 23, 24, 23, 23, 21, 19, 17, 13, 10, 6, 4, 0, -3, -4, -8,
843 -12, -15, -21, -25, -30, -38, -44, -50, -56, -60, -65, -68, -69, -70, -70, -67,
844 -65, -62, -59, -57, -53, -49, -46, -42, -38, -33, -28, -22, -17, -12, -6, -1, 4,
845 8, 13, 18, 21, 26, 29, 32, 36, 39, 42, 45, 46, 48, 48, 49, 48, 46, 46, 45, 43,
846 41, 39, 37, 35, 34, 32, 29, 28, 26, 23, 21, 20, 19, 18, 18, 19, 20, 21, 22, 23,
847 24, 25, 25, 24, 23, 20, 17, 14, 10, 7, 3, 0, -3, -8, -10, -14, -21, -24, -29,
848 -36, -42, -47, -55, -60, -63, -69, -71, -72, -72, -72, -69, -66, -63, -60, -54,
849 -52, -48, -43, -39, -35, -30, -24, -20, -15, -9, -4, 1, 6, 11, 15, 19, 25, 28,
850 32, 36, 38, 41, 44, 46, 47, 47, 47, 47, 45, 45, 44, 43, 40, 40, 37, 34, 33, 31,
851 28, 27, 24, 22, 20, 18, 17, 16, 17, 17, 19, 21, 22, 24, 25, 26, 27, 26, 25, 24,
852 21, 18, 14, 11, 9, 5, 2, -1, -5, -8, -14, -18, -24, -30, -35, -45, -50, -55,
853 -64, -68, -72, -75, -75, -76, -74, -72, -69, -65, -63, -57, -54, -49, -45, -42,
854 -36, -33, -27, -21, -17, -8, -3, 2, 10, 13, 19, 24, 28, 33, 35, 39, 42, 43, 48,
855 48, 50, 51, 52, 52, 50, 49, 48, 45, 44, 40, 38, 35, 31, 29, 25, 24, 21, 18, 18,
856 15, 14, 13, 13, 14, 14, 17, 19, 20, 23, 24, 25, 26, 26, 27, 25, 25, 22, 18, 17,
857 13, 11, 7, 4, 1, -5, -9, -14, -21, -28, -34, -43, -50, -55, -61, -68, -71, -73,
858 -76, -76, -74, -74, -71, -68, -65, -63, -59, -54, -52, -46, -40, -34, -28, -20,
859 -13, -7, 0, 7, 11, 17, 23, 26, 29, 34, 36, 38, 41, 45, 48, 50, 53, 53, 54, 53,
860 51, 48, 46, 43, 39, 35, 32, 29, 25, 23, 21, 20, 19, 18, 16, 14, 14, 11, 10, 11,
861 11, 12, 14, 17, 19, 21, 25, 27, 29, 31, 32, 31, 29, 27, 23, 19, 17, 13, 11, 7,
862 3, -1, -6, -11, -19, -25, -30, -41, -48, -56, -64, -70, -77, -78, -80, -82, -79,
863 -79, -77, -73, -69, -66, -62, -55, -51, -47, -40, -36, -28, -21, -14, -5, 1, 9,
864 14, 20, 27, 29, 34, 37, 39, 41, 41, 43, 44, 46, 48, 48, 49, 48, 47, 45, 42, 40,
865 36, 31, 28, 23, 20, 15, 12, 10, 8, 8, 6, 6, 5, 4, 3, 3, 3, 6, 8, 11, 14, 17, 20,
866 24, 28, 31, 34, 37, 38, 38, 36, 34, 32, 28, 26, 23, 19, 15, 9, 5, -3, -10, -16,
867 -25, -33, -41, -51, -59, -66, -74, -79, -81, -83, -84, -82, -81, -79, -75, -73,
868 -68, -64, -58, -53, -50, -42, -35, -30, -22, -13, -4, 4, 11, 17, 22, 27, 29, 32,
869 35, 35, 36, 37, 37, 40, 41, 44, 47, 48, 49, 47, 45, 41, 38, 33, 27, 23, 17, 12,
870 9, 5, 4, 3, 4, 4, 4, 5, 3, 2, 1, 0, 2, 4, 7, 11, 15, 20, 25, 31, 38, 44, 48, 51,
871 53, 52, 49, 47, 43, 39, 36, 32, 29, 24, 20, 14, 6, 2, -5, -16, -22, -34, -46,
872 -55, -66, -74, -80, -85, -88, -89, -88, -89, -86, -82, -79, -74, -70, -65, -61,
873 -58, -52, -47, -41, -32, -25, -15, -6, 2, 10, 15, 22, 28, 31, 36, 37, 37, 36,
874 36, 37, 38, 42, 45, 47, 50, 49, 48, 46, 43, 40, 35, 30, 24, 17, 12, 6, 2, 2, 1,
875 2, 4, 4, 5, 4, 3, 2, 2, 5, 8, 10, 14, 19, 23, 28, 35, 42, 48, 54, 57, 59, 59,
876 57, 54, 51, 50, 47, 42, 38, 33, 28, 21, 15, 7, -1, -9, -20, -32, -43, -54, -65,
877 -75, -82, -87, -91, -95, -97, -97, -97, -96, -93, -89, -85, -81, -76, -72, -66,
878 -60, -53, -44, -35, -25, -15, -6, 3, 11, 19, 24, 30, 36, 38, 41, 42, 41, 42, 41,
879 41, 44, 47, 50, 51, 52, 51, 49, 46, 41, 38, 32, 25, 18, 11, 6, 1, -3, -4, -3,
880 -3, -3, -3, -5, -7, -8, -8, -8, -6, -2, 4, 9, 16, 25, 31, 38, 46, 53, 59, 62,
881 61, 62, 63, 61, 59, 58, 59, 58, 54, 52, 48, 42, 35, 26, 15, 5, -8, -24, -38,
882 -49, -62, -73, -80, -87, -91, -96, -99, -100, -102, -102, -103, -102, -98, -99,
883 -96, -91, -86, -78, -71, -59, -49, -37, -24, -16, -4, 6, 14, 22, 28, 35, 39, 41,
884 44, 46, 48, 49, 51, 52, 52, 57, 56, 56, 58, 54, 52, 48, 43, 37, 30, 24, 16, 11,
885 6, 2, -1, -4, -4, -4, -5, -4, -6, -6, -6, -8, -9, -9, -9, -8, -5, 1, 7, 14, 22,
886 29, 36, 42, 47, 50, 52, 54, 54, 54, 54, 52, 52, 52, 51, 51, 48, 43, 37, 30, 19,
887 10, 1, -14, -23, -33, -47, -52, -60, -69, -72, -77, -81, -84, -88, -92, -94,
888 -95, -97, -97, -93, -89, -83, -78, -70, -60, -53, -43, -33, -24, -14, -7, 0, 7,
889 13, 20, 24, 30, 35, 38, 42, 45, 47, 48, 49, 50, 48, 48, 48, 46, 45, 43, 40, 38,
890 34, 30, 25, 21, 18, 12, 8, 5, 1, -2, -4, -6, -7, -8, -9, -11, -10, -10, -12,
891 -12, -11, -9, -7, -1, 4, 9, 16, 20, 24, 30, 33, 37, 39, 41, 43, 45, 46, 47, 49,
892 52, 53, 54, 53, 51, 46, 38, 31, 22, 14, 6, -4, -12, -20, -30, -37, -42, -50,
893 -56, -57, -65, -72, -75, -83, -89, -90, -92, -92, -88, -87, -84, -75, -70, -64,
894 -55, -49, -40, -34, -28, -21, -18, -12, -8, -2, 4, 11, 17, 20, 26, 30, 32, 35,
895 35, 35, 32, 28, 27, 24, 25, 25, 25, 27, 27, 25, 24, 22, 20, 16, 13, 9, 4, 1, -5,
896 -7, -8, -9, -6, -5, -1, 3, 5, 8, 10, 12, 14, 16, 17, 21, 24, 27, 31, 37, 41, 46,
897 52, 57, 61, 64, 66, 67, 68, 68, 66, 64, 62, 58, 54, 48, 40, 31, 24, 14, 4, -4,
898 -14, -26, -36, -45, -54, -62, -68, -75, -80, -83, -90, -95, -96, -100, -100,
899 -100, -99, -94, -91, -86, -80, -72, -63, -58, -49, -40, -33, -26, -20, -14, -8,
900 -2, 4, 8, 16, 19, 20, 23, 24, 26, 25, 24, 24, 29, 35, 36, 41, 44, 43, 43, 39,
901 38, 35, 30, 26, 21, 17, 12, 7, 5, 5, 7, 6, 6, 6, 1, -1, -5, -10, -14, -18, -22,
902 -24, -23, -20, -16, -5, 6, 17, 29, 39, 45, 48, 51, 53, 54, 57, 57, 60, 66, 69,
903 72, 78, 87, 93, 96, 98, 94, 86, 73, 54, 37, 22, 6, -9, -20, -27, -37, -44, -51,
904 -57, -61, -65, -72, -80, -89, -100, -110, -121, -125, -127, -128, -121, -115,
905 -106, -94, -87, -75, -64, -56, -46, -40, -36, -33, -31, -28, -22, -15, -8, 4,
906 15, 23, 33, 37, 41, 45, 41, 42, 48, 47, 48, 49, 47, 46, 46, 44, 46, 49, 48, 46,
907 43, 38, 32, 24, 17, 14, 9, 4, 0, -7, -11, -14, -20, -22, -23, -24, -27, -28,
908 -30, -33, -33, -32, -28, -21, -11, -2, 6, 16, 24, 31, 40, 47, 53, 61, 67, 70,
909 73, 77, 81, 85, 91, 96, 100, 101, 99, 92, 84, 73, 59, 46, 35, 21, 8, -6, -19,
910 -31, -42, -51, -58, -65, -73, -81, -90, -100, -107, -116, -122, -122, -124,
911 -123, -119, -116, -108, -101, -98, -84, -74, -69, -58, -50, -45, -38, -34, -31,
912 -22, -14, -9, 0, 7, 12, 18, 20, 24, 28, 28, 34, 39, 43, 48, 49, 49, 49, 49, 47,
913 45, 45, 41, 38, 34, 28, 25, 19, 17, 16, 13, 12, 7, 4, 1, -6, -9, -13, -13, -13,
914 -13, -9, -6, -2, 2, 7, 14, 20, 27, 30, 35, 40, 41, 45, 49, 52, 59, 64, 70, 75,
915 79, 82, 83, 84, 82, 79, 75, 67, 58, 47, 36, 24, 12, 2, -7, -14, -23, -32, -40,
916 -49, -57, -65, -74, -81, -88, -96, -103, -107, -112, -114, -112, -110, -103,
917 -97, -91, -83, -77, -69, -61, -53, -43, -37, -30, -23, -18, -12, -7, 0, 8, 15,
918 22, 23, 28, 31, 29, 29, 27, 25, 20, 13, 10, 10, 13, 15, 17, 23, 26, 26, 25, 23,
919 23, 19, 14, 11, 8, 4, 0, -2, 0, 3, 7, 9, 14, 16, 16, 15, 9, 5, 2, -4, -7, -8,
920 -8, -8, -5, 1, 9, 18, 27, 35, 41, 44, 46, 46, 44, 44, 43, 45, 49, 51, 55, 60,
921 65, 70, 73, 76, 76, 72, 64, 54, 42, 28, 14, 3, -5, -12, -20, -25, -30, -35, -41,
922 -47, -53, -60, -68, -75, -84, -92, -100, -105, -106, -104, -102, -96, -86, -80,
923 -73, -67, -61, -53, -50, -44, -37, -35, -31, -29, -27, -20, -15, -10, -1, 7, 11,
924 15, 16, 15, 16, 12, 6, 3, -2, -3, 0, 3, 8, 14, 19, 24, 28, 29, 31, 30, 26, 23,
925 19, 14, 13, 11, 12, 16, 20, 25, 30, 34, 37, 38, 35, 31, 27, 22, 17, 12, 9, 8, 7,
926 8, 12, 17, 23, 28, 30, 33, 34, 33, 31, 28, 27, 27, 27, 28, 32, 36, 41, 46, 50,
927 54, 55, 53, 48, 41, 33, 23, 13, 5, -1, -5, -8, -12, -15, -16, -20, -24, -28,
928 -35, -42, -50, -59, -68, -74, -80, -85, -83, -82, -79, -72, -68, -64, -58, -56,
929 -53, -51, -47, -47, -45, -41, -41, -37, -33, -29, -21, -17, -11, -7, -2, 2, -1,
930 0, -2, -5, -9, -17, -19, -19, -17, -7, 0, 10, 20, 24, 27, 29, 30, 27, 25, 22,
931 17, 16, 11, 8, 11, 15, 22, 29, 35, 41, 43, 41, 38, 31, 23, 16, 11, 7, 6, 7, 8,
932 14, 20, 28, 39, 46, 51, 52, 51, 49, 45, 40, 37, 37, 41, 43, 47, 54, 60, 65, 68,
933 71, 71, 67, 58, 45, 33, 19, 5, -7, -15, -18, -21, -23, -26, -29, -32, -38, -44,
934 -52, -60, -69, -79, -86, -94, -99, -101, -100, -93, -89, -82, -73, -70, -64,
935 -58, -56, -50, -47, -45, -39, -36, -35, -31, -25, -23, -16, -8, -4, 3, 6, 8, 9,
936 6, 5, 1, -3, -6, -14, -17, -15, -14, -6, 3, 11, 19, 23, 25, 24, 24, 20, 16, 12,
937 8, 7, 3, 3, 9, 13, 21, 30, 36, 44, 47, 46, 43, 38, 32, 26, 23, 21, 22, 24, 27,
938 34, 40, 48, 57, 61, 64, 64, 60, 56, 50, 44, 40, 40, 41, 42, 45, 49, 53, 55, 56,
939 54, 50, 43, 31, 18, 5, -9, -21, -30, -35, -37, -38, -39, -40, -42, -45, -49,
940 -55, -63, -69, -77, -85, -90, -96, -98, -96, -93, -88, -79, -70, -63, -55, -50,
941 -48, -42, -39, -37, -33, -31, -28, -23, -20, -13, -6, 1, 7, 14, 17, 19, 21, 16,
942 15, 13, 6, 2, -3, -10, -13, -14, -9, 0, 8, 18, 26, 28, 28, 25, 20, 19, 16, 9, 7,
943 8, 4, 4, 8, 14, 23, 32, 38, 43, 44, 41, 34, 25, 20, 14, 10, 11, 14, 17, 23, 30,
944 37, 47, 56, 60, 62, 60, 54, 47, 41, 36, 33, 36, 41, 46, 53, 59, 64, 67, 68, 66,
945 61, 52, 39, 23, 8, -6, -20, -29, -32, -33, -33, -33, -35, -40, -43, -48, -57,
946 -62, -70, -80, -86, -93, -97, -97, -95, -89, -81, -70, -64, -58, -50, -47, -42,
947 -39, -34, -29, -29, -25, -23, -19, -13, -8, 0, 9, 18, 19, 21, 24, 18, 16, 13, 7,
948 5, -2, -10, -18, -22, -21, -18, -8, 4, 13, 19, 20, 20, 16, 12, 10, 6, 4, 2, -1,
949 -2, 0, 5, 13, 24, 36, 44, 50, 51, 47, 41, 33, 26, 22, 19, 19, 19, 22, 27, 32,
950 41, 51, 60, 65, 65, 61, 53, 46, 38, 32, 31, 32, 36, 40, 46, 51, 56, 61, 63, 63,
951 60, 51, 39, 23, 9, -5, -17, -22, -26, -26, -25, -26, -28, -31, -34, -39, -47,
952 -55, -64, -75, -84, -90, -95, -95, -91, -86, -78, -71, -65, -58, -54, -50, -46,
953 -43, -40, -39, -37, -34, -31, -23, -16, -7, 4, 11, 15, 18, 18, 17, 14, 11, 7, 3,
954 -1, -5, -9, -13, -15, -18, -23, -22, -18, -17, -11, -4, -3, 0, 2, 0, 2, 6, 6, 8,
955 11, 14, 16, 20, 26, 35, 42, 48, 55, 56, 58, 58, 53, 49, 47, 42, 39, 40, 40, 40,
956 43, 44, 46, 50, 51, 51, 47, 42, 35, 28, 24, 20, 18, 20, 24, 27, 30, 35, 39, 41,
957 44, 42, 40, 36, 27, 17, 7, -2, -12, -18, -21, -24, -24, -26, -28, -31, -35, -39,
958 -44, -51, -57, -65, -74, -78, -84, -88, -85, -84, -81, -75, -69, -64, -58, -52,
959 -48, -40, -34, -31, -24, -21, -14, -11, -9, -1, 4, 7, 14, 18, 21, 25, 26, 25,
960 28, 27, 21, 20, 15, 12, 9, 3, -2, -7, -11, -16, -16, -11, -10, -8, -4, -4, -3,
961 -1, 3, 12, 19, 22, 24, 21, 19, 18, 17, 24, 34, 37, 40, 46, 47, 49, 51, 50, 56,
962 60, 57, 54, 49, 45, 40, 36, 37, 41, 41, 40, 36, 32, 28, 24, 20, 21, 23, 22, 19,
963 16, 14, 15, 17, 20, 23, 25, 21, 14, 5, -4, -13, -20, -24, -25, -27, -30, -31,
964 -34, -35, -34, -32, -31, -32, -39, -46, -54, -65, -71, -73, -73, -68, -64, -60,
965 -54, -50, -43, -32, -25, -19, -10, -8, -10, -9, -8, -9, -7, -4, 0, 6, 8, 11, 13,
966 13, 17, 15, 9, 8, 2, -12, -20, -30, -43, -46, -47, -46, -35, -26, -16, -4, 4,
967 12, 17, 18, 20, 19, 13, 13, 13, 11, 17, 28, 37, 51, 63, 70, 76, 78, 75, 69, 62,
968 54, 45, 36, 29, 25, 23, 24, 29, 34, 40, 43, 40, 37, 32, 23, 15, 10, 5, 3, 5, 7,
969 13, 21, 29, 35, 42, 45, 42, 35, 28, 15, 3, -6, -16, -22, -22, -22, -20, -13, -9,
970 -3, 1, 0, -5, -16, -30, -43, -56, -64, -65, -68, -66, -59, -53, -40, -35, -33,
971 -22, -22, -30, -36, -30, -25, -39, -40, -29, -26, -26, -21, -7, 1, 2, -5, -3, 3,
972 -5, -8, -15, -14, -12, -32, -35, -30, -36, -37, -42, -43, -31, -25, -20, -2, 15,
973 21, 28, 32, 41, 51, 44, 45, 52, 50, 51, 52, 56, 63, 66, 69, 72, 74, 69, 58, 49,
974 39, 27, 13, 1, -2, -4, -5, -3, 3, 11, 18, 22, 26, 29, 28, 23, 22, 23, 25, 29,
975 32, 41, 55, 67, 78, 87, 95, 98, 95, 90, 80, 66, 50, 35, 21, 9, -1, -11, -17,
976 -20, -25, -29, -33, -38, -43, -49, -57, -63, -68, -71, -71, -70, -68, -63, -58,
977 -52, -42, -35, -33, -28, -27, -23, -16, -9, -1, 5, 1, 8, 15, 4, 0, 2, -2, -8,
978 -13, -12, -17, -28, -31, -33, -34, -35, -41, -46, -45, -51, -65, -66, -72, -76,
979 -65, -58, -39, -13, 5, 27, 47, 60, 73, 78, 79, 84, 82, 70, 65, 60, 54, 61, 67,
980 70, 76, 72, 61, 55, 43, 25, 6, -14, -35, -52, -67, -75, -73, -67, -55, -38, -24,
981 -7, 3, 9, 18, 22, 23, 26, 29, 35, 43, 53, 65, 82, 98, 112, 120, 121, 115, 102,
982 84, 67, 47, 25, 3, -17, -32, -43, -51, -55, -57, -59, -63, -67, -73, -81, -88,
983 -93, -94, -94, -90, -82, -73, -60, -46, -33, -24, -16, -10, -12, -12, -13, -13,
984 -14, -16, -13, -16, -20, -16, -15, -12, -8, -15, -26, -34, -48, -61, -65, -68,
985 -69, -71, -73, -67, -64, -60, -49, -44, -43, -41, -50, -61, -59, -54, -41, -16,
986 11, 36, 54, 69, 83, 91, 99, 102, 95, 82, 66, 44, 27, 23, 24, 27, 32, 32, 27, 18,
987 9, -1, -14, -28, -47, -68, -85, -95, -96, -84, -62, -38, -12, 13, 31, 42, 54,
988 62, 66, 67, 65, 61, 58, 59, 65, 77, 93, 106, 113, 114, 107, 93, 74, 54, 30, 3,
989 -23, -49, -68, -80, -84, -81, -76, -70, -67, -68, -69, -73, -76, -77, -79, -78,
990 -73, -70, -64, -50, -34, -15, 6, 19, 22, 19, 8, 1, -4, -10, -12, -17, -26, -35,
991 -37, -37, -36, -30, -30, -33, -43, -56, -64, -70, -71, -72, -73, -71, -68, -67,
992 -60, -44, -27, -17, -16, -16, -29, -39, -37, -38, -22, 7, 23, 38, 56, 67, 75,
993 88, 95, 93, 82, 57, 33, 11, 1, 3, 0, 5, 10, 4, 3, 4, -1, -5, -13, -26, -47, -66,
994 -78, -86, -82, -67, -43, -16, 9, 37, 60, 77, 91, 97, 97, 94, 84, 71, 66, 65, 66,
995 78, 90, 99, 103, 100, 95, 85, 71, 52, 26, -1, -28, -52, -67, -71, -71, -68, -61,
996 -55, -50, -45, -43, -43, -45, -48, -52, -56, -54, -47, -35, -21, -8, 3, 9, 11,
997 8, 3, -3, -15, -24, -36, -48, -52, -56, -59, -55, -50, -49, -46, -46, -53, -55,
998 -56, -59, -62, -61, -58, -57, -51, -40, -32, -24, -15, -12, -10, -8, -12, -18,
999 -21, -27, -36, -37, -27, -12, 11, 35, 47, 56, 62, 61, 60, 59, 52, 40, 25, 11, 6,
1000 6, 12, 23, 30, 35, 36, 28, 22, 17, 5, -10, -25, -41, -52, -53, -39, -16, 1, 19,
1001 34, 42, 49, 54, 54, 54, 49, 39, 36, 41, 45, 55, 72, 89, 101, 106, 106, 102, 93,
1002 80, 63, 44, 26, 7, -9, -14, -14, -14, -11, -8, -9, -12, -18, -27, -35, -41, -47,
1003 -52, -52, -49, -41, -29, -15, -1, 5, 7, 6, 1, -8, -16, -25, -38, -44, -44, -42,
1004 -36, -26, -19, -14, -11, -14, -21, -29, -40, -53, -63, -68, -71, -70, -59, -44,
1005 -32, -21, -8, -1, 1, 1, -8, -19, -26, -37, -44, -44, -43, -43, -40, -30, -16, 3,
1006 23, 42, 54, 53, 52, 46, 39, 40, 35, 27, 22, 18, 17, 26, 41, 50, 57, 56, 47, 38,
1007 26, 15, 4, -10, -21, -31, -37, -31, -21, -6, 11, 25, 34, 41, 47, 49, 50, 49, 46,
1008 46, 47, 52, 59, 68, 80, 89, 94, 97, 93, 85, 74, 62, 47, 34, 21, 9, -1, -7, -10,
1009 -9, -9, -10, -15, -20, -27, -34, -38, -40, -42, -41, -38, -31, -22, -11, 1, 9,
1010 14, 16, 10, 4, -4, -16, -26, -36, -46, -48, -46, -43, -35, -28, -26, -27, -32,
1011 -37, -40, -48, -56, -65, -72, -76, -74, -63, -48, -33, -23, -13, -9, -7, -7,
1012 -12, -17, -26, -37, -46, -52, -50, -47, -45, -43, -43, -34, -19, -3, 17, 29, 30,
1013 28, 28, 29, 33, 37, 36, 32, 30, 29, 35, 43, 51, 55, 49, 41, 30, 18, 10, 1, -10,
1014 -23, -36, -44, -46, -40, -30, -11, 4, 14, 27, 36, 41, 47, 49, 51, 53, 50, 48,
1015 54, 61, 69, 79, 86, 91, 89, 81, 76, 68, 56, 43, 25, 7, -9, -22, -29, -31, -33,
1016 -37, -40, -43, -45, -46, -47, -47, -49, -48, -45, -40, -31, -21, -11, -3, 0, 1,
1017 0, -5, -13, -21, -33, -42, -48, -52, -47, -41, -36, -33, -35, -35, -38, -47,
1018 -53, -62, -72, -78, -81, -79, -67, -55, -45, -27, -9, 1, 9, 16, 16, 9, 2, -6,
1019 -16, -17, -16, -22, -16, -7, -11, -12, -13, -7, 2, 6, 11, 8, 1, -2, 1, 4, 12,
1020 21, 14, 13, 18, 17, 25, 32, 34, 34, 30, 23, 15, 17, 19, 16, 12, 3, -2, -5, -1,
1021 9, 11, 16, 19, 17, 23, 33, 38, 39, 42, 43, 43, 47, 51, 54, 59, 62, 64, 64, 67,
1022 68, 65, 65, 63, 56, 49, 43, 34, 27, 22, 13, 5, 0, -6, -11, -15, -18, -20, -22,
1023 -22, -25, -26, -25, -26, -24, -21, -21, -24, -25, -25, -27, -27, -27, -31, -33,
1024 -34, -36, -40, -42, -44, -47, -46, -44, -43, -41, -36, -34, -31, -27, -28, -33,
1025 -35, -34, -35, -36, -35, -37, -33, -30, -27, -21, -16, -14, -17, -18, -18, -22,
1026 -30, -36, -41, -49, -55, -61, -58, -36, -14, 7, 24, 33, 40, 43, 47, 52, 50, 42,
1027 30, 22, 21, 25, 34, 42, 52, 55, 52, 47, 39, 33, 20, 3, -15, -37, -51, -55, -52,
1028 -42, -29, -14, -1, 14, 29, 38, 44, 44, 39, 36, 35, 35, 40, 48, 60, 72, 83, 91,
1029 97, 97, 94, 87, 74, 59, 41, 23, 9, 0, -7, -11, -13, -15, -16, -17, -20, -23,
1030 -29, -37, -46, -52, -53, -51, -45, -35, -24, -16, -9, -2, 2, 3, -1, -9, -17,
1031 -25, -35, -41, -41, -41, -39, -35, -29, -24, -24, -24, -30, -37, -44, -57, -65,
1032 -64, -65, -62, -52, -41, -29, -16, -7, 0, 6, 0, -6, -11, -21, -25, -30, -32,
1033 -28, -26, -22, -17, -15, -13, -18, -21, -13, -7, 0, 4, 7, 12, 20, 31, 41, 49,
1034 51, 48, 46, 44, 46, 46, 42, 41, 37, 33, 29, 24, 23, 19, 11, 1, -12, -19, -24,
1035 -27, -25, -19, -13, -7, 3, 14, 24, 31, 35, 40, 45, 47, 50, 56, 62, 68, 76, 83,
1036 88, 90, 89, 88, 84, 75, 63, 47, 31, 17, 4, -5, -12, -19, -25, -28, -30, -33,
1037 -34, -36, -40, -44, -47, -49, -47, -40, -33, -25, -17, -9, -4, 3, 7, 7, 4, -4,
1038 -10, -18, -25, -29, -32, -36, -40, -40, -36, -34, -32, -30, -33, -40, -48, -52,
1039 -54, -53, -54, -54, -48, -45, -39, -27, -15, -6, -4, -3, -2, -7, -9, -11, -12,
1040 -16, -19, -22, -27, -24, -24, -30, -24, -18, -10, 5, 12, 14, 21, 24, 26, 31, 35,
1041 34, 31, 27, 28, 33, 36, 41, 46, 43, 42, 37, 29, 27, 21, 8, -2, -14, -24, -26,
1042 -25, -22, -13, -4, 3, 11, 20, 26, 29, 31, 33, 35, 36, 39, 45, 53, 63, 71, 77,
1043 82, 85, 81, 78, 72, 61, 50, 36, 23, 12, 3, -2, -7, -9, -13, -16, -19, -22, -25,
1044 -29, -33, -38, -42, -41, -38, -31, -21, -14, -6, 0, 3, 7, 7, 4, -1, -9, -17,
1045 -23, -30, -34, -37, -40, -40, -41, -43, -41, -41, -41, -40, -40, -43, -46, -45,
1046 -46, -42, -37, -35, -31, -25, -22, -18, -9, -2, -1, 2, 1, -3, -7, -9, -10, -13,
1047 -14, -19, -28, -31, -34, -41, -42, -31, -23, -13, 3, 8, 13, 25, 28, 34, 41, 39,
1048 32, 29, 28, 30, 36, 40, 44, 45, 43, 43, 39, 34, 31, 19, 4, -7, -20, -27, -26,
1049 -23, -15, -7, -1, 7, 16, 24, 29, 32, 32, 31, 30, 32, 39, 46, 54, 63, 69, 74, 77,
1050 76, 74, 70, 60, 48, 36, 22, 12, 5, 0, -2, -5, -8, -10, -12, -14, -16, -19, -24,
1051 -29, -32, -34, -31, -27, -22, -15, -10, -6, -2, -1, -1, -2, -9, -15, -19, -25,
1052 -28, -29, -31, -32, -34, -33, -31, -31, -33, -36, -37, -37, -41, -42, -42, -41,
1053 -42, -35, -30, -29, -22, -16, -14, -8, -7, -8, -11, -13, -15, -17, -18, -19,
1054 -19, -20, -20, -23, -26, -27, -32, -39, -42, -38, -32, -20, -1, 9, 17, 26, 32,
1055 40, 48, 49, 44, 37, 30, 26, 28, 32, 36, 36, 35, 35, 32, 28, 26, 17, 4, -9, -23,
1056 -33, -35, -31, -23, -15, -8, -1, 7, 16, 24, 29, 29, 27, 25, 26, 32, 40, 47, 57,
1057 65, 70, 74, 76, 75, 72, 65, 54, 42, 29, 19, 12, 8, 6, 2, -2, -4, -8, -11, -14,
1058 -18, -25, -31, -35, -37, -35, -29, -25, -18, -11, -6, -1, 3, 3, 0, -5, -12, -21,
1059 -26, -29, -28, -28, -26, -26, -30, -28, -26, -26, -27, -29, -36, -45, -50, -52,
1060 -50, -48, -48, -42, -36, -31, -25, -17, -8, -5, -8, -7, -8, -12, -15, -13, -12,
1061 -13, -16, -18, -18, -19, -22, -24, -29, -39, -44, -40, -32, -18, -4, 2, 11, 19,
1062 25, 33, 39, 39, 33, 28, 22, 20, 24, 27, 33, 37, 35, 35, 31, 30, 28, 18, 8, -5,
1063 -19, -25, -23, -16, -10, -3, 3, 8, 16, 22, 28, 31, 30, 27, 26, 30, 35, 43, 53,
1064 64, 70, 73, 77, 78, 76, 72, 62, 50, 37, 24, 15, 9, 6, 2, -3, -7, -10, -14, -17,
1065 -19, -24, -30, -35, -38, -38, -33, -27, -22, -17, -11, -6, -3, 0, 0, -4, -10,
1066 -17, -21, -24, -26, -27, -28, -28, -29, -30, -31, -30, -29, -33, -37, -40, -44,
1067 -46, -46, -43, -41, -38, -33, -29, -22, -16, -12, -7, -4, -3, -5, -7, -10, -11,
1068 -12, -15, -15, -18, -21, -24, -27, -29, -34, -44, -47, -41, -35, -24, -7, 0, 7,
1069 16, 22, 31, 38, 37, 34, 31, 26, 24, 28, 32, 36, 38, 35, 34, 31, 26, 24, 15, 2,
1070 -12, -26, -32, -32, -27, -19, -12, -5, 2, 11, 19, 27, 31, 30, 30, 29, 32, 41,
1071 49, 60, 70, 77, 81, 85, 86, 84, 79, 69, 55, 41, 27, 18, 10, 6, 3, -2, -5, -7,
1072 -9, -11, -13, -18, -25, -30, -34, -35, -31, -27, -20, -13, -8, -3, 2, 5, 5, 3,
1073 -2, -9, -16, -23, -27, -31, -33, -34, -36, -36, -36, -38, -41, -41, -43, -48,
1074 -50, -51, -50, -48, -44, -35, -30, -27, -21, -15, -10, -8, -4, -3, -4, -4, -6,
1075 -7, -7, -8, -8, -10, -13, -17, -24, -29, -34, -40, -51, -61, -56, -46, -35, -16,
1076 0, 7, 16, 26, 34, 42, 42, 34, 30, 25, 21, 26, 33, 41, 47, 48, 49, 49, 45, 40,
1077 32, 17, 1, -16, -29, -32, -27, -23, -16, -7, 0, 8, 16, 23, 27, 26, 23, 21, 22,
1078 27, 35, 45, 57, 68, 73, 79, 84, 82, 79, 72, 59, 45, 32, 21, 15, 12, 10, 8, 6, 4,
1079 1, -3, -6, -12, -22, -30, -37, -41, -40, -36, -30, -23, -17, -12, -7, -3, -2,
1080 -3, -7, -12, -20, -28, -29, -29, -29, -28, -28, -28, -27, -23, -20, -19, -22,
1081 -30, -35, -39, -40, -40, -39, -38, -37, -34, -30, -23, -18, -13, -10, -13, -15,
1082 -15, -16, -16, -16, -17, -19, -22, -22, -22, -21, -20, -25, -29, -33, -42, -50,
1083 -47, -34, -23, -6, 9, 16, 28, 38, 47, 57, 57, 51, 42, 34, 31, 30, 33, 38, 41,
1084 39, 37, 38, 36, 35, 28, 13, -1, -16, -27, -29, -26, -24, -22, -17, -11, -4, 6,
1085 13, 17, 17, 16, 17, 18, 26, 34, 43, 53, 61, 68, 73, 79, 80, 77, 71, 60, 48, 37,
1086 28, 22, 16, 13, 9, 5, 3, 1, -1, -4, -9, -17, -24, -30, -34, -34, -32, -29, -26,
1087 -22, -16, -11, -7, -5, -7, -11, -15, -19, -21, -22, -24, -25, -24, -23, -21,
1088 -19, -22, -25, -28, -32, -33, -38, -41, -40, -42, -41, -38, -32, -27, -22, -18,
1089 -15, -11, -14, -14, -11, -12, -12, -13, -12, -11, -14, -14, -12, -13, -16, -21,
1090 -25, -31, -37, -48, -56, -58, -52, -42, -27, -4, 12, 22, 37, 47, 54, 57, 56, 51,
1091 44, 38, 34, 38, 45, 49, 54, 56, 57, 56, 51, 45, 34, 19, 4, -11, -21, -25, -25,
1092 -23, -17, -11, -7, 0, 5, 8, 9, 9, 9, 9, 13, 20, 31, 44, 56, 67, 74, 80, 82, 79,
1093 76, 68, 56, 45, 33, 24, 17, 13, 9, 5, 1, -4, -8, -12, -18, -25, -32, -38, -43,
1094 -45, -44, -39, -34, -28, -22, -18, -14, -10, -8, -7, -7, -8, -10, -11, -10, -9,
1095 -8, -9, -10, -12, -16, -19, -23, -27, -32, -35, -36, -36, -35, -33, -30, -25,
1096 -20, -16, -17, -19, -21, -20, -20, -20, -18, -17, -15, -12, -7, -3, -1, 1, -1,
1097 -5, -8, -14, -23, -28, -30, -37, -43, -45, -47, -46, -37, -23, -9, 9, 18, 24,
1098 33, 38, 40, 44, 43, 39, 34, 32, 34, 40, 46, 50, 53, 50, 47, 43, 36, 32, 21, 7,
1099 -5, -15, -21, -21, -18, -15, -11, -7, -4, 2, 6, 10, 12, 13, 14, 17, 22, 31, 41,
1100 52, 60, 67, 70, 72, 71, 67, 63, 54, 43, 33, 22, 16, 11, 7, 4, -2, -6, -10, -15,
1101 -19, -23, -29, -36, -40, -42, -43, -38, -34, -29, -23, -19, -15, -12, -9, -9,
1102 -12, -15, -16, -15, -14, -10, -8, -8, -9, -12, -13, -16, -22, -25, -30, -38,
1103 -42, -41, -41, -42, -38, -35, -33, -30, -25, -19, -16, -13, -12, -12, -11, -10,
1104 -9, -7, -8, -8, -8, -7, -5, -3, -2, -5, -8, -11, -18, -23, -27, -32, -41, -48,
1105 -48, -43, -35, -25, -7, 7, 15, 24, 31, 35, 37, 36, 34, 31, 28, 26, 31, 40, 45,
1106 50, 54, 54, 52, 47, 42, 36, 24, 13, 2, -4, -6, -6, -2, 3, 8, 9, 11, 14, 14, 14,
1107 14, 13, 13, 15, 21, 30, 41, 50, 58, 62, 63, 63, 59, 54, 47, 37, 28, 20, 13, 10,
1108 7, 5, 2, -2, -7, -14, -19, -25, -32, -38, -44, -46, -48, -46, -41, -35, -29,
1109 -21, -17, -13, -10, -9, -11, -13, -15, -15, -11, -9, -7, -3, -2, -5, -4, -2, -5,
1110 -10, -14, -19, -21, -22, -24, -25, -25, -27, -29, -24, -19, -19, -18, -17, -19,
1111 -18, -16, -13, -9, -7, -8, -8, -4, -1, 1, -1, -2, -7, -15, -18, -17, -19, -23,
1112 -25, -25, -29, -30, -27, -24, -23, -25, -23, -22, -22, -13, 0, 10, 17, 23, 29,
1113 34, 40, 45, 49, 48, 42, 40, 37, 35, 38, 40, 39, 38, 36, 33, 32, 31, 26, 21, 14,
1114 6, 1, -3, -2, 1, 2, 5, 8, 11, 15, 21, 26, 31, 35, 35, 36, 39, 41, 45, 47, 47,
1115 45, 42, 39, 36, 32, 26, 18, 10, 2, -6, -12, -16, -21, -26, -31, -35, -38, -39,
1116 -40, -41, -41, -41, -42, -37, -32, -29, -24, -17, -14, -11, -6, 0, 1, 0, 1, 0,
1117 -3, -6, -6, -5, -7, -11, -12, -11, -12, -14, -13, -14, -17, -22, -27, -29, -30,
1118 -33, -33, -29, -29, -29, -24, -20, -17, -14, -12, -12, -12, -12, -16, -15, -11,
1119 -15, -17, -17, -17, -20, -22, -23, -26, -27, -31, -34, -31, -30, -27, -25, -20,
1120 -15, -12, -1, 12, 20, 26, 33, 38, 38, 42, 46, 45, 46, 42, 39, 40, 39, 39, 40,
1121 40, 36, 31, 29, 25, 22, 17, 13, 7, 1, -1, -3, -2, 1, 3, 5, 9, 13, 17, 22, 28,
1122 32, 35, 37, 39, 43, 46, 48, 49, 48, 47, 43, 39, 35, 29, 22, 15, 6, -2, -8, -14,
1123 -19, -23, -27, -32, -35, -37, -39, -40, -40, -40, -39, -38, -34, -29, -24, -18,
1124 -13, -9, -6, -4, -3, -3, -4, -2, -3, -4, -5, -5, -3, -2, -3, -4, -6, -11, -17,
1125 -19, -23, -28, -31, -34, -33, -32, -31, -24, -21, -19, -18, -16, -16, -14, -13,
1126 -15, -12, -10, -12, -6, -1, 1, 2, 2, -2, -7, -10, -14, -18, -20, -22, -25, -26,
1127 -25, -22, -21, -20, -21, -27, -30, -32, -30, -25, -17, -9, -4, 6, 14, 21, 31,
1128 34, 33, 31, 28, 24, 21, 27, 31, 30, 37, 41, 44, 47, 50, 52, 47, 40, 30, 21, 18,
1129 13, 13, 17, 19, 21, 26, 33, 35, 38, 38, 34, 29, 25, 24, 22, 25, 28, 28, 32, 34,
1130 35, 35, 33, 28, 18, 9, 0, -10, -15, -20, -23, -24, -24, -22, -21, -19, -18, -19,
1131 -22, -29, -34, -38, -39, -41, -40, -34, -30, -24, -17, -11, -7, -8, -11, -14,
1132 -17, -19, -20, -20, -22, -22, -18, -16, -11, -10, -12, -13, -17, -21, -24, -24,
1133 -26, -29, -27, -26, -22, -17, -13, -9, -9, -11, -11, -13, -14, -15, -14, -14,
1134 -15, -14, -15, -12, -13, -15, -13, -17, -22, -23, -25, -26, -25, -22, -21, -22,
1135 -22, -21, -16, -13, -7, 0, 4, 7, 10, 15, 20, 23, 25, 26, 27, 26, 26, 27, 28, 31,
1136 31, 32, 34, 34, 36, 37, 37, 36, 31, 28, 25, 23, 21, 21, 23, 23, 25, 27, 30, 33,
1137 35, 36, 34, 32, 32, 30, 29, 29, 29, 29, 28, 27, 26, 25, 23, 18, 14, 7, 0, -5,
1138 -10, -14, -17, -20, -21, -21, -21, -22, -21, -22, -24, -27, -29, -31, -32, -32,
1139 -32, -33, -31, -29, -27, -23, -20, -18, -20, -21, -21, -20, -19, -20, -17, -16,
1140 -16, -15, -14, -11, -12, -13, -13, -14, -16, -17, -16, -15, -16, -15, -15, -15,
1141 -16, -17, -15, -13, -15, -16, -16, -15, -15, -13, -12, -13, -14, -16, -16, -17,
1142 -18, -17, -18, -19, -21, -20, -19, -19, -18, -18, -17, -18, -19, -16, -14, -12,
1143 -8, -4, 2, 5, 10, 16, 20, 22, 23, 25, 25, 24, 25, 28, 32, 33, 36, 40, 41, 42,
1144 44, 44, 43, 39, 36, 33, 30, 28, 27, 27, 26, 28, 27, 26, 27, 25, 24, 22, 19, 17,
1145 16, 15, 16, 18, 19, 19, 21, 21, 19, 18, 15, 11, 6, 1, -3, -7, -10, -12, -13,
1146 -14, -15, -16, -17, -18, -23, -27, -28, -31, -35, -37, -38, -37, -38, -37, -35,
1147 -31, -30, -30, -27, -24, -23, -22, -20, -18, -15, -15, -15, -10, -8, -9, -8, -4,
1148 -3, -6, -8, -7, -10, -13, -13, -14, -16, -19, -18, -16, -15, -15, -14, -13, -17,
1149 -18, -18, -21, -21, -21, -22, -22, -24, -22, -22, -24, -22, -22, -22, -23, -23,
1150 -20, -20, -20, -18, -20, -20, -15, -12, -11, -4, 1, 6, 10, 12, 18, 22, 23, 26,
1151 27, 27, 28, 30, 32, 33, 37, 39, 40, 42, 42, 43, 43, 41, 40, 36, 32, 30, 28, 26,
1152 26, 26, 26, 26, 25, 26, 26, 24, 24, 22, 21, 22, 20, 22, 23, 23, 24, 24, 24, 23,
1153 20, 18, 15, 10, 6, 3, -1, -5, -7, -8, -9, -11, -13, -16, -17, -20, -23, -26,
1154 -29, -32, -34, -37, -37, -36, -37, -36, -34, -32, -30, -27, -25, -22, -21, -20,
1155 -18, -17, -15, -15, -15, -12, -12, -13, -10, -9, -10, -8, -5, -5, -5, -5, -5,
1156 -7, -12, -11, -10, -14, -14, -13, -16, -17, -16, -18, -19, -19, -21, -22, -23,
1157 -25, -25, -26, -25, -24, -27, -27, -26, -29, -30, -29, -27, -24, -24, -19, -12,
1158 -8, -3, 7, 14, 15, 19, 26, 27, 26, 29, 35, 37, 39, 43, 46, 48, 49, 50, 52, 51,
1159 48, 45, 42, 38, 34, 32, 30, 28, 25, 23, 22, 21, 19, 18, 17, 15, 11, 9, 9, 9, 10,
1160 12, 15, 16, 18, 20, 22, 24, 25, 25, 24, 22, 20, 17, 15, 13, 10, 7, 4, 1, -3, -5,
1161 -8, -10, -14, -19, -23, -28, -33, -36, -39, -41, -44, -46, -46, -46, -44, -43,
1162 -41, -40, -38, -37, -36, -31, -26, -23, -20, -17, -13, -12, -12, -8, -4, -4, -3,
1163 -1, 0, -2, -2, 0, 3, 0, -2, -2, -3, -7, -11, -12, -13, -19, -24, -24, -28, -33,
1164 -33, -33, -36, -38, -39, -41, -44, -46, -46, -46, -45, -44, -44, -39, -33, -28,
1165 -20, -11, -2, 4, 10, 17, 22, 25, 31, 35, 37, 39, 42, 46, 50, 54, 57, 61, 63, 62,
1166 61, 60, 58, 53, 48, 44, 39, 34, 29, 27, 24, 22, 20, 17, 14, 10, 7, 6, 5, 3, 2,
1167 2, 2, 3, 5, 8, 10, 12, 13, 15, 15, 15, 15, 15, 14, 13, 12, 11, 9, 9, 8, 6, 4, 1,
1168 -3, -6, -10, -13, -16, -19, -22, -26, -28, -29, -31, -32, -32, -32, -33, -34,
1169 -34, -34, -33, -33, -31, -30, -28, -27, -24, -21, -20, -17, -15, -13, -11, -9,
1170 -10, -9, -6, -7, -7, -5, -4, -6, -6, -4, -4, -7, -7, -7, -10, -12, -14, -15,
1171 -18, -20, -22, -23, -25, -27, -28, -29, -31, -34, -33, -31, -33, -34, -30, -27,
1172 -25, -21, -17, -13, -9, -6, -3, 0, 2, 4, 7, 11, 13, 15, 20, 23, 25, 29, 34, 35,
1173 37, 40, 41, 41, 43, 44, 42, 42, 43, 42, 41, 41, 40, 38, 37, 35, 32, 30, 29, 27,
1174 25, 25, 23, 23, 22, 22, 21, 22, 21, 19, 19, 18, 17, 16, 15, 13, 12, 11, 10, 8,
1175 7, 5, 3, 2, 0, -3, -4, -5, -8, -11, -12, -14, -17, -20, -22, -25, -29, -32, -33,
1176 -35, -37, -38, -38, -38, -39, -40, -38, -37, -38, -37, -36, -36, -36, -35, -33,
1177 -31, -31, -28, -25, -23, -22, -20, -16, -14, -13, -11, -8, -9, -10, -8, -7, -7,
1178 -8, -7, -6, -7, -8, -7, -7, -9, -10, -11, -12, -15, -17, -16, -15, -17, -16,
1179 -10, -7, -8, -5, 1, 2, 2, 3, 6, 6, 6, 8, 11, 14, 17, 21, 25, 29, 31, 34, 37, 39,
1180 38, 40, 41, 41, 40, 40, 41, 42, 42, 42, 42, 40, 38, 35, 32, 31, 27, 24, 23, 22,
1181 22, 23, 23, 24, 24, 24, 23, 21, 19, 18, 16, 16, 14, 13, 13, 13, 12, 13, 13, 12,
1182 10, 7, 4, 1, -2, -5, -8, -11, -13, -15, -17, -19, -20, -22, -26, -30, -33, -36,
1183 -40, -43, -44, -44, -45, -43, -40, -38, -37, -34, -30, -29, -28, -27, -26, -25,
1184 -23, -20, -18, -15, -13, -12, -9, -7, -7, -4, -3, -3, -4, -4, -5, -7, -7, -8,
1185 -9, -12, -16, -19, -24, -27, -31, -36, -39, -41, -41, -39, -35, -30, -24, -13,
1186 -4, 1, 8, 14, 19, 25, 29, 33, 36, 40, 45, 49, 55, 60, 64, 67, 67, 66, 63, 60,
1187 55, 47, 42, 35, 27, 20, 15, 12, 8, 5, 2, -2, -5, -8, -10, -12, -11, -9, -6, -1,
1188 5, 12, 21, 29, 38, 44, 49, 52, 53, 54, 54, 54, 53, 51, 48, 44, 40, 35, 28, 22,
1189 13, 5, -5, -16, -25, -33, -40, -47, -51, -54, -57, -59, -58, -55, -52, -49, -48,
1190 -47, -44, -42, -37, -30, -24, -19, -13, -9, -5, 1, 4, 8, 12, 10, 9, 6, 1, -4,
1191 -9, -14, -18, -25, -31, -36, -39, -41, -41, -42, -42, -42, -44, -44, -44, -42,
1192 -37, -37, -35, -34, -34, -31, -28, -24, -19, -19, -22, -22, -14, -7, 1, 15, 31,
1193 39, 42, 52, 54, 50, 53, 49, 43, 37, 29, 27, 24, 27, 29, 28, 29, 24, 19, 14, 11,
1194 6, 0, -3, -8, -9, -7, -6, 2, 10, 16, 17, 17, 19, 17, 19, 24, 28, 35, 37, 43, 51,
1195 57, 64, 67, 67, 61, 54, 45, 37, 32, 27, 23, 20, 14, 10, 5, 1, -3, -8, -14, -20,
1196 -26, -30, -32, -29, -25, -21, -19, -17, -14, -14, -15, -14, -15, -18, -21, -22,
1197 -23, -21, -18, -16, -14, -17, -20, -23, -27, -30, -32, -34, -37, -37, -37, -36,
1198 -33, -29, -28, -30, -29, -29, -28, -26, -27, -23, -21, -24, -18, -11, -10, -6,
1199 -1, -3, -8, -13, -17, -20, -27, -27, -26, -33, -35, -35, -38, -42, -43, -35,
1200 -30, -26, -14, -1, 14, 27, 40, 54, 55, 56, 58, 55, 54, 51, 50, 50, 47, 47, 46,
1201 44, 41, 36, 32, 22, 12, 1, -8, -16, -19, -18, -21, -18, -14, -11, -4, -1, 4, 9,
1202 11, 16, 22, 28, 36, 45, 55, 62, 68, 72, 72, 70, 66, 60, 52, 43, 34, 27, 20, 14,
1203 9, 3, -4, -9, -16, -21, -25, -28, -29, -30, -29, -27, -23, -21, -16, -10, -8,
1204 -7, -7, -8, -10, -12, -11, -10, -11, -10, -11, -16, -18, -21, -26, -30, -33,
1205 -37, -40, -43, -47, -47, -47, -48, -39, -34, -36, -30, -27, -31, -27, -22, -16,
1206 -14, -11, -2, -3, -1, 6, 2, 1, 1, -8, -16, -18, -22, -26, -25, -26, -28, -36,
1207 -38, -40, -52, -49, -48, -55, -45, -36, -26, -5, 16, 28, 40, 51, 50, 51, 51, 50,
1208 48, 46, 46, 46, 47, 51, 50, 50, 46, 38, 30, 19, 8, 0 };
1209 
1210 #endif /* BLAHBLAH4B_H_ */
#define CONSTTABLE_STORAGE(X)
Declare a variable such that it will be stored in flash memory, instead of RAM, on platforms where th...
+
1 #ifndef BLAHBLAH4B_H_
+
2 #define BLAHBLAH4B_H_
+
3 
+
4 #include <Arduino.h>
+
5 #include "mozzi_pgmspace.h"
+
6 
+
7 #define BLAHBLAH4B_NUM_CELLS 22569
+
8 #define BLAHBLAH4B_SAMPLERATE 16384
+
9 
+
10 CONSTTABLE_STORAGE(int8_t) BLAHBLAH4B_DATA [] = { -1, 2, 6, 9, 12, 15, 17, 20, 22, 25, 28, 30,
+
11 32, 34, 37, 38, 40, 42, 44, 46, 47, 49, 50, 52, 53, 53, 54, 55, 55, 55, 54, 54,
+
12 53, 51, 48, 46, 42, 38, 34, 29, 25, 20, 15, 10, 5, -1, -6, -11, -16, -21, -25,
+
13 -29, -33, -37, -40, -43, -47, -50, -52, -55, -57, -58, -59, -59, -59, -59, -58,
+
14 -57, -56, -55, -54, -53, -51, -50, -48, -45, -42, -39, -35, -32, -27, -23, -18,
+
15 -14, -9, -5, -1, 3, 7, 10, 13, 16, 19, 22, 25, 28, 30, 33, 36, 38, 40, 43, 45,
+
16 47, 49, 51, 53, 54, 56, 57, 57, 58, 58, 58, 58, 58, 57, 56, 55, 52, 49, 46, 41,
+
17 37, 33, 28, 23, 17, 12, 7, 1, -5, -10, -15, -20, -25, -30, -34, -38, -42, -46,
+
18 -49, -52, -55, -57, -59, -61, -62, -63, -62, -62, -61, -60, -59, -58, -57, -56,
+
19 -54, -52, -51, -48, -45, -42, -38, -34, -31, -26, -22, -18, -13, -9, -5, -1, 3,
+
20 6, 9, 12, 15, 18, 21, 24, 27, 29, 32, 34, 37, 39, 41, 43, 45, 47, 49, 51, 53,
+
21 55, 56, 57, 59, 59, 59, 59, 58, 58, 57, 55, 53, 50, 47, 43, 38, 34, 29, 24, 19,
+
22 15, 9, 4, -2, -8, -13, -18, -24, -28, -32, -37, -40, -44, -47, -50, -54, -56,
+
23 -59, -61, -62, -64, -64, -64, -63, -62, -61, -60, -58, -58, -57, -55, -53, -50,
+
24 -48, -45, -42, -39, -35, -31, -27, -22, -22, -17, -8, -2, 4, 8, 12, 14, 17, 21,
+
25 23, 25, 28, 30, 32, 36, 39, 42, 44, 45, 46, 48, 50, 51, 53, 54, 56, 58, 58, 60,
+
26 60, 59, 59, 57, 55, 53, 51, 49, 46, 42, 39, 35, 29, 24, 19, 13, 8, 2, -4, -10,
+
27 -15, -20, -27, -31, -33, -39, -41, -45, -49, -50, -55, -56, -59, -61, -62, -64,
+
28 -64, -63, -62, -61, -59, -58, -54, -52, -50, -47, -44, -42, -42, -41, -39, -37,
+
29 -35, -34, -33, -30, -23, -15, -8, -2, 4, 6, 8, 11, 13, 16, 22, 26, 27, 27, 27,
+
30 28, 29, 29, 30, 33, 36, 40, 44, 47, 49, 49, 48, 48, 47, 46, 47, 48, 51, 53, 55,
+
31 56, 57, 56, 53, 49, 43, 39, 34, 30, 26, 22, 19, 17, 14, 9, 3, -2, -8, -14, -22,
+
32 -28, -32, -36, -38, -39, -41, -41, -43, -46, -49, -52, -55, -58, -60, -61, -59,
+
33 -58, -57, -55, -52, -50, -51, -51, -50, -49, -48, -47, -46, -42, -37, -34, -29,
+
34 -24, -20, -16, -12, -10, -7, -3, 0, 3, 6, 10, 14, 17, 20, 23, 26, 28, 29, 31,
+
35 33, 35, 36, 39, 42, 44, 47, 48, 50, 52, 53, 53, 54, 54, 55, 56, 56, 56, 56, 56,
+
36 54, 51, 47, 42, 37, 33, 29, 24, 19, 15, 10, 6, 0, -5, -10, -15, -21, -27, -33,
+
37 -37, -40, -42, -45, -48, -48, -50, -53, -55, -56, -57, -59, -60, -60, -58, -57,
+
38 -56, -55, -53, -52, -54, -53, -49, -48, -46, -48, -48, -48, -52, -43, -28, -21,
+
39 -14, -17, -20, -9, 0, 7, 14, 14, 13, 15, 21, 29, 34, 33, 32, 32, 32, 37, 44, 46,
+
40 46, 46, 45, 46, 49, 55, 56, 55, 55, 51, 49, 52, 54, 57, 58, 56, 55, 54, 52, 50,
+
41 48, 44, 35, 28, 23, 17, 13, 10, 5, -2, -11, -20, -26, -27, -33, -41, -44, -51,
+
42 -59, -62, -64, -65, -65, -66, -68, -70, -68, -67, -66, -63, -65, -59, -54, -57,
+
43 -52, -41, -38, -41, -43, -38, -32, -32, -31, -27, -23, -20, -23, -24, -12, -3,
+
44 0, 7, 11, 11, 14, 13, 17, 22, 16, 15, 20, 23, 28, 34, 38, 43, 40, 37, 37, 38,
+
45 44, 47, 47, 48, 47, 48, 51, 53, 57, 56, 54, 55, 56, 55, 55, 54, 54, 50, 43, 40,
+
46 39, 36, 32, 26, 16, 7, 0, -7, -14, -19, -23, -29, -38, -47, -52, -60, -65, -72,
+
47 -80, -84, -86, -87, -85, -86, -83, -84, -86, -82, -79, -73, -64, -57, -41, -30,
+
48 -32, -27, -15, -5, -6, -10, 0, 12, 16, 15, 19, 30, 33, 28, 29, 31, 31, 31, 21,
+
49 17, 17, 15, 18, 19, 22, 20, 17, 19, 19, 17, 14, 8, 8, 11, 11, 10, 8, 15, 21, 16,
+
50 10, 15, 24, 23, 18, 24, 30, 29, 30, 35, 37, 36, 37, 38, 40, 40, 37, 40, 43, 40,
+
51 34, 30, 27, 26, 19, 13, 9, 4, -1, -9, -15, -18, -28, -34, -37, -48, -54, -58,
+
52 -61, -60, -67, -71, -72, -72, -70, -77, -76, -70, -69, -68, -66, -60, -52, -42,
+
53 -33, -35, -32, -20, -14, -14, -15, -6, 6, 8, 7, 13, 22, 28, 26, 29, 36, 32, 32,
+
54 37, 40, 41, 39, 42, 48, 46, 42, 36, 33, 34, 30, 26, 23, 22, 26, 25, 19, 14, 16,
+
55 21, 13, 9, 16, 19, 16, 13, 18, 21, 14, 17, 21, 20, 20, 21, 27, 31, 26, 26, 26,
+
56 25, 24, 20, 18, 16, 14, 11, 5, 3, 0, -7, -10, -16, -20, -28, -33, -33, -39, -43,
+
57 -50, -53, -51, -58, -61, -60, -61, -61, -62, -63, -60, -60, -58, -53, -53, -52,
+
58 -48, -37, -25, -25, -24, -11, -1, -1, -3, 2, 13, 17, 18, 19, 24, 33, 36, 37, 38,
+
59 38, 37, 38, 39, 39, 39, 41, 41, 39, 38, 33, 29, 28, 25, 23, 18, 16, 18, 18, 14,
+
60 8, 4, 9, 14, 6, 1, 10, 18, 14, 8, 11, 16, 15, 15, 18, 19, 21, 25, 28, 31, 28,
+
61 23, 25, 28, 23, 15, 12, 19, 20, 10, 3, 1, -2, -7, -16, -22, -27, -30, -31, -37,
+
62 -46, -51, -52, -53, -57, -63, -66, -64, -62, -63, -65, -65, -61, -57, -56, -57,
+
63 -54, -51, -46, -40, -35, -24, -17, -15, -5, 4, 7, 2, 5, 20, 27, 24, 25, 31, 43,
+
64 46, 39, 39, 44, 44, 41, 38, 40, 42, 42, 43, 39, 35, 31, 26, 24, 23, 18, 14, 12,
+
65 13, 13, 8, 2, 4, 11, 8, -2, 1, 10, 10, 6, 6, 11, 11, 10, 12, 14, 17, 18, 20, 26,
+
66 26, 21, 20, 24, 24, 15, 10, 13, 15, 9, 3, 3, 0, -7, -13, -18, -21, -29, -34,
+
67 -32, -37, -46, -49, -49, -50, -56, -59, -59, -61, -59, -58, -59, -57, -54, -51,
+
68 -50, -49, -47, -42, -38, -36, -34, -24, -10, -11, -9, 3, 12, 13, 7, 14, 28, 30,
+
69 29, 30, 39, 48, 44, 44, 50, 49, 45, 43, 43, 44, 41, 39, 41, 38, 35, 29, 23, 23,
+
70 20, 14, 8, 4, 4, 6, 1, -2, 0, 5, 1, -5, -2, 2, 2, 1, 4, 8, 8, 8, 13, 16, 18, 17,
+
71 20, 26, 25, 21, 21, 23, 22, 17, 13, 14, 12, 9, 6, 3, -1, -8, -13, -14, -20, -29,
+
72 -32, -30, -36, -47, -45, -46, -51, -52, -55, -54, -55, -56, -53, -54, -52, -49,
+
73 -49, -44, -43, -42, -35, -34, -32, -27, -25, -15, -1, -3, -3, 8, 18, 17, 10, 18,
+
74 30, 30, 31, 29, 35, 45, 42, 40, 44, 43, 39, 37, 38, 38, 33, 34, 33, 30, 29, 22,
+
75 17, 17, 15, 11, 4, 0, 1, 4, 3, -4, -4, 5, 4, -4, -3, 4, 6, 5, 5, 11, 13, 13, 16,
+
76 19, 22, 19, 19, 27, 26, 20, 18, 21, 22, 16, 11, 8, 8, 7, -1, -6, -9, -16, -19,
+
77 -21, -27, -36, -38, -35, -43, -50, -47, -50, -53, -51, -52, -54, -54, -51, -47,
+
78 -48, -48, -44, -41, -36, -36, -36, -29, -27, -23, -19, -19, -13, 1, 8, 2, 4, 16,
+
79 22, 17, 15, 24, 32, 32, 28, 30, 38, 39, 34, 36, 41, 35, 29, 31, 32, 30, 25, 22,
+
80 23, 22, 18, 12, 10, 11, 8, 3, -1, -4, -2, 3, 0, -2, 3, 6, 3, 2, 6, 8, 7, 8, 13,
+
81 17, 17, 16, 22, 25, 23, 19, 21, 24, 19, 15, 16, 17, 12, 6, 5, 5, 0, -10, -11,
+
82 -9, -17, -26, -29, -28, -32, -40, -41, -41, -45, -46, -47, -50, -50, -50, -49,
+
83 -48, -49, -45, -42, -41, -37, -36, -34, -32, -30, -25, -22, -20, -17, -14, -5,
+
84 9, 6, 0, 11, 21, 22, 12, 13, 28, 32, 28, 24, 26, 35, 34, 30, 33, 34, 30, 29, 30,
+
85 29, 25, 21, 23, 22, 20, 16, 10, 13, 14, 9, 3, -3, -2, 3, 2, -4, -4, 7, 9, 0, -1,
+
86 5, 7, 4, 5, 10, 13, 13, 14, 18, 21, 18, 15, 21, 24, 16, 13, 14, 18, 14, 6, 3, 6,
+
87 5, -6, -7, -4, -14, -20, -17, -21, -31, -35, -29, -33, -39, -37, -40, -43, -39,
+
88 -43, -46, -42, -42, -41, -36, -36, -35, -32, -28, -29, -31, -25, -22, -23, -18,
+
89 -16, -16, -4, 6, -1, -2, 8, 13, 11, 6, 10, 20, 22, 19, 14, 20, 27, 22, 21, 28,
+
90 26, 22, 25, 24, 22, 21, 16, 16, 17, 15, 11, 9, 12, 11, 7, 2, -2, -1, 4, 3, -2,
+
91 3, 9, 8, 6, 4, 8, 12, 11, 9, 14, 19, 18, 19, 24, 26, 22, 22, 28, 27, 21, 19, 21,
+
92 22, 17, 9, 9, 11, 5, -3, -2, -2, -11, -18, -15, -20, -32, -32, -30, -35, -38,
+
93 -38, -40, -42, -42, -43, -46, -44, -41, -41, -38, -37, -37, -33, -31, -31, -30,
+
94 -27, -25, -25, -20, -19, -20, -16, -3, 2, -6, -4, 5, 12, 7, 0, 9, 19, 18, 13,
+
95 11, 19, 22, 19, 20, 23, 22, 22, 23, 22, 23, 18, 16, 18, 16, 15, 12, 11, 14, 13,
+
96 11, 5, 2, 5, 9, 7, 8, 12, 13, 14, 14, 13, 14, 15, 19, 21, 23, 24, 23, 28, 31,
+
97 30, 27, 29, 32, 29, 24, 23, 24, 20, 14, 11, 8, 6, 1, 0, -2, -8, -13, -20, -21,
+
98 -28, -33, -33, -38, -37, -41, -45, -44, -48, -47, -48, -50, -50, -49, -46, -45,
+
99 -45, -41, -37, -38, -37, -35, -34, -29, -29, -27, -24, -25, -20, -6, -1, -10,
+
100 -7, 7, 12, 3, -2, 12, 22, 18, 14, 13, 23, 29, 23, 26, 31, 28, 28, 30, 29, 28,
+
101 26, 27, 27, 23, 24, 22, 21, 23, 21, 17, 13, 8, 11, 15, 12, 12, 20, 19, 16, 17,
+
102 19, 18, 16, 21, 23, 20, 23, 24, 25, 29, 27, 24, 26, 28, 22, 18, 18, 18, 15, 8,
+
103 3, 5, 4, -6, -8, -7, -13, -24, -28, -25, -36, -44, -39, -42, -44, -49, -51, -49,
+
104 -52, -56, -56, -57, -57, -54, -52, -50, -49, -46, -40, -43, -42, -35, -34, -32,
+
105 -30, -28, -24, -22, -22, -19, -3, 6, -3, -4, 10, 18, 10, 4, 15, 26, 29, 24, 22,
+
106 31, 39, 36, 32, 37, 36, 35, 39, 37, 36, 37, 37, 36, 32, 31, 29, 25, 25, 24, 18,
+
107 14, 9, 8, 14, 12, 9, 11, 11, 11, 10, 6, 5, 6, 11, 11, 8, 10, 14, 16, 19, 18, 14,
+
108 16, 20, 16, 11, 10, 12, 12, 6, 2, 1, -1, -6, -9, -12, -19, -24, -28, -31, -35,
+
109 -40, -41, -44, -45, -47, -53, -51, -52, -54, -53, -55, -56, -53, -48, -45, -44,
+
110 -41, -38, -35, -32, -30, -29, -24, -18, -18, -16, -12, -10, -7, -4, 1, 13, 14,
+
111 9, 14, 24, 29, 21, 20, 33, 39, 37, 33, 32, 41, 47, 40, 38, 40, 41, 43, 39, 36,
+
112 35, 33, 34, 28, 21, 23, 20, 16, 14, 8, 3, 0, -5, -6, -3, -3, -4, -7, -5, 0, -6,
+
113 -10, -7, -1, 2, -2, -1, 6, 11, 11, 12, 14, 16, 17, 19, 15, 12, 14, 16, 13, 9, 8,
+
114 7, 5, 2, -4, -8, -11, -19, -21, -22, -29, -33, -31, -32, -37, -41, -41, -44,
+
115 -45, -43, -47, -48, -43, -41, -41, -38, -35, -33, -31, -27, -25, -25, -19, -16,
+
116 -15, -11, -9, -7, -3, 0, 1, 1, 1, 9, 21, 17, 11, 19, 29, 30, 20, 21, 33, 36, 33,
+
117 28, 27, 33, 34, 29, 31, 31, 27, 27, 24, 20, 17, 13, 14, 10, 4, 4, 1, -3, -4, -8,
+
118 -11, -14, -17, -12, -7, -10, -12, -8, -4, -5, -8, -4, 3, 7, 9, 10, 13, 19, 24,
+
119 26, 29, 30, 31, 33, 32, 27, 26, 26, 27, 26, 20, 16, 17, 13, 6, 1, -4, -8, -14,
+
120 -20, -19, -26, -32, -29, -34, -38, -41, -45, -44, -46, -48, -48, -49, -46, -41,
+
121 -42, -41, -37, -35, -31, -31, -31, -25, -23, -22, -18, -16, -13, -12, -10, -6,
+
122 -6, -5, -6, 2, 13, 9, 6, 13, 22, 22, 13, 15, 23, 25, 25, 20, 18, 26, 28, 25, 26,
+
123 23, 22, 23, 18, 14, 11, 11, 14, 8, 4, 6, 2, 0, -2, -4, -2, -5, -9, -2, 4, 1, -1,
+
124 3, 10, 10, 7, 10, 14, 20, 23, 22, 25, 32, 37, 37, 37, 40, 40, 39, 36, 32, 31,
+
125 29, 27, 26, 23, 17, 13, 11, 5, -4, -8, -11, -20, -24, -25, -32, -38, -36, -38,
+
126 -47, -50, -49, -52, -55, -56, -57, -56, -54, -53, -52, -47, -45, -43, -39, -39,
+
127 -38, -33, -30, -27, -24, -18, -14, -14, -10, -8, -5, -2, -2, -1, 9, 17, 11, 13,
+
128 23, 29, 27, 20, 24, 30, 32, 30, 24, 28, 35, 34, 30, 30, 30, 29, 27, 21, 17, 17,
+
129 18, 16, 10, 10, 10, 7, 7, 3, 3, 5, 3, 3, 5, 7, 7, 7, 11, 13, 13, 14, 16, 19, 24,
+
130 25, 24, 30, 33, 35, 35, 35, 36, 34, 32, 27, 23, 23, 21, 17, 11, 8, 6, -2, -7,
+
131 -13, -17, -20, -27, -35, -38, -39, -45, -50, -50, -50, -57, -63, -58, -59, -64,
+
132 -61, -60, -56, -55, -54, -49, -47, -43, -40, -38, -34, -30, -26, -20, -16, -14,
+
133 -9, -5, -3, 1, 2, 6, 8, 8, 20, 25, 24, 26, 32, 39, 36, 29, 33, 39, 39, 36, 33,
+
134 36, 41, 38, 36, 35, 32, 31, 28, 23, 21, 17, 19, 19, 13, 10, 8, 6, 4, -1, -4, -6,
+
135 -9, -7, -5, -7, -6, -4, -2, 0, -3, -2, 0, 4, 7, 6, 8, 14, 18, 21, 22, 23, 25,
+
136 24, 22, 22, 20, 18, 17, 18, 17, 10, 8, 9, 4, -3, -8, -9, -14, -20, -24, -27,
+
137 -30, -33, -35, -37, -41, -44, -44, -46, -51, -50, -47, -46, -45, -44, -40, -39,
+
138 -37, -34, -32, -29, -27, -22, -17, -15, -12, -7, -3, 0, 0, 2, 5, 7, 7, 7, 9, 13,
+
139 16, 21, 22, 22, 25, 27, 26, 23, 23, 25, 26, 25, 23, 23, 25, 25, 23, 22, 21, 18,
+
140 16, 14, 11, 10, 9, 8, 5, 1, -2, -5, -7, -9, -12, -12, -10, -11, -11, -8, -6, -6,
+
141 -6, -3, -1, -1, 2, 5, 9, 13, 16, 21, 26, 29, 32, 34, 37, 38, 38, 39, 38, 37, 38,
+
142 36, 33, 31, 26, 24, 19, 13, 8, 3, 0, -9, -14, -16, -23, -28, -32, -35, -39, -44,
+
143 -46, -49, -51, -52, -53, -54, -54, -51, -51, -49, -46, -44, -38, -38, -36, -28,
+
144 -27, -24, -18, -15, -13, -10, -5, -1, -1, 2, 5, 5, 6, 7, 7, 8, 8, 7, 12, 13, 12,
+
145 12, 15, 17, 14, 9, 12, 11, 9, 8, 5, 6, 8, 7, 6, 5, 4, 5, 4, 1, 0, -2, 2, 4, 1,
+
146 5, 9, 10, 13, 13, 17, 22, 22, 24, 28, 30, 32, 32, 37, 42, 41, 43, 47, 49, 51,
+
147 51, 50, 52, 51, 49, 44, 40, 37, 32, 25, 20, 13, 8, 2, -6, -9, -17, -27, -29,
+
148 -32, -40, -50, -52, -54, -61, -65, -67, -71, -71, -67, -71, -73, -69, -66, -62,
+
149 -63, -58, -54, -51, -43, -42, -34, -27, -26, -18, -11, -8, -5, 0, 6, 8, 9, 9,
+
150 13, 14, 16, 14, 16, 26, 27, 24, 28, 30, 30, 27, 23, 23, 22, 21, 18, 14, 15, 18,
+
151 16, 15, 14, 10, 11, 10, 4, 2, 3, 5, 1, -1, 2, 2, 2, 2, 2, 4, 4, 4, 8, 13, 14,
+
152 17, 21, 25, 27, 28, 32, 34, 37, 39, 39, 41, 46, 47, 47, 48, 49, 48, 45, 42, 38,
+
153 31, 28, 22, 15, 9, 2, 0, -5, -15, -19, -22, -30, -37, -42, -47, -54, -61, -59,
+
154 -64, -70, -67, -69, -68, -69, -70, -64, -64, -62, -56, -55, -49, -45, -41, -31,
+
155 -30, -24, -14, -13, -6, -1, 1, 7, 9, 14, 16, 16, 21, 20, 20, 23, 20, 21, 26, 26,
+
156 24, 26, 28, 28, 24, 23, 22, 18, 19, 17, 12, 14, 14, 13, 14, 13, 11, 11, 10, 8,
+
157 5, 4, 4, 1, -1, 1, -3, -3, -3, -3, -2, -1, 3, 4, 5, 11, 13, 14, 16, 19, 23, 25,
+
158 27, 30, 34, 38, 40, 42, 47, 48, 48, 50, 50, 47, 45, 42, 38, 33, 28, 23, 17, 12,
+
159 6, -2, -8, -14, -21, -28, -34, -42, -47, -51, -58, -64, -64, -65, -71, -71, -68,
+
160 -70, -71, -67, -66, -64, -58, -57, -52, -45, -39, -36, -30, -20, -17, -13, -5,
+
161 -2, 2, 6, 9, 12, 15, 19, 19, 20, 24, 24, 21, 22, 20, 16, 16, 13, 13, 12, 10, 11,
+
162 10, 11, 8, 4, 4, 3, -2, -5, -5, -6, -6, -5, -5, -4, -2, 0, 0, -1, 4, 5, 6, 9,
+
163 11, 15, 19, 21, 26, 31, 36, 39, 40, 43, 46, 46, 47, 46, 48, 51, 50, 49, 51, 52,
+
164 52, 48, 46, 44, 38, 32, 26, 19, 12, 4, -4, -8, -16, -26, -28, -34, -42, -48,
+
165 -50, -57, -63, -65, -69, -71, -73, -76, -75, -71, -69, -76, -68, -60, -62, -61,
+
166 -52, -44, -43, -35, -27, -24, -18, -11, -5, 0, 5, 7, 12, 18, 18, 20, 23, 25, 23,
+
167 22, 22, 19, 17, 15, 12, 14, 16, 12, 9, 13, 15, 9, 3, 3, 2, -1, -5, -9, -9, -5,
+
168 -4, -5, -3, -1, 1, 2, 2, -2, -3, 1, 2, -1, -1, 3, 8, 14, 18, 21, 31, 38, 38, 39,
+
169 44, 46, 42, 44, 48, 48, 49, 53, 55, 59, 61, 59, 59, 60, 57, 51, 45, 42, 36, 29,
+
170 21, 11, 6, 1, -8, -16, -19, -25, -38, -47, -47, -55, -65, -67, -68, -73, -76,
+
171 -76, -77, -78, -77, -73, -71, -71, -68, -62, -57, -52, -49, -40, -32, -29, -20,
+
172 -12, -8, -3, 6, 13, 13, 16, 20, 24, 25, 26, 27, 29, 29, 29, 27, 25, 22, 19, 20,
+
173 20, 14, 13, 16, 16, 12, 9, 9, 9, 7, 5, 2, 0, 2, 3, 4, 4, 4, 6, 9, 9, 8, 8, 10,
+
174 10, 8, 8, 6, 5, 7, 8, 8, 8, 10, 15, 16, 16, 18, 20, 21, 20, 21, 22, 22, 24, 28,
+
175 29, 30, 33, 36, 38, 38, 38, 39, 37, 35, 33, 30, 25, 22, 20, 15, 11, 6, 3, -1,
+
176 -8, -14, -21, -27, -33, -40, -43, -50, -52, -53, -55, -57, -62, -59, -57, -62,
+
177 -61, -59, -58, -58, -52, -48, -46, -40, -31, -26, -24, -18, -13, -10, -5, -4, 1,
+
178 3, 5, 9, 11, 14, 15, 17, 18, 17, 14, 12, 9, 4, 2, 0, -1, -1, -3, 0, 3, 5, 3, 0,
+
179 2, 2, -2, -4, -5, -4, 0, 2, 3, 7, 12, 17, 18, 17, 19, 22, 25, 24, 23, 29, 35,
+
180 37, 40, 45, 50, 54, 54, 53, 53, 53, 50, 47, 47, 46, 45, 45, 46, 46, 46, 44, 40,
+
181 37, 32, 25, 17, 10, 2, -5, -12, -19, -22, -28, -34, -36, -43, -49, -52, -58,
+
182 -62, -68, -71, -70, -74, -75, -72, -69, -67, -67, -60, -56, -55, -51, -46, -39,
+
183 -36, -34, -25, -19, -15, -9, -2, 5, 10, 14, 17, 19, 19, 23, 23, 20, 21, 19, 18,
+
184 13, 8, 9, 4, 5, 8, 5, 5, 6, 6, 6, 2, -1, -1, -3, -5, -8, -10, -4, -2, -1, 5, 8,
+
185 10, 12, 13, 13, 10, 11, 12, 10, 11, 12, 13, 18, 24, 27, 29, 35, 42, 41, 39, 42,
+
186 43, 41, 40, 39, 42, 43, 44, 46, 48, 50, 50, 49, 48, 46, 41, 39, 33, 28, 23, 15,
+
187 7, 0, -3, -10, -22, -25, -28, -37, -45, -51, -53, -58, -64, -67, -70, -71, -74,
+
188 -74, -73, -73, -72, -69, -64, -62, -59, -52, -47, -42, -35, -28, -24, -19, -8,
+
189 -4, -3, 5, 11, 14, 17, 20, 25, 25, 27, 29, 26, 26, 25, 20, 18, 16, 11, 8, 10,
+
190 10, 8, 8, 10, 8, 5, 5, 3, -1, 0, -2, -4, -3, -2, 1, 4, 7, 9, 10, 13, 12, 10, 10,
+
191 8, 6, 6, 5, 4, 5, 8, 9, 9, 12, 14, 15, 17, 17, 16, 19, 19, 19, 21, 24, 27, 29,
+
192 33, 36, 37, 40, 42, 42, 43, 43, 43, 42, 40, 38, 34, 31, 26, 21, 16, 11, 3, -3,
+
193 -8, -16, -22, -29, -36, -40, -47, -51, -56, -59, -63, -68, -67, -69, -70, -68,
+
194 -67, -65, -63, -58, -55, -52, -45, -41, -35, -29, -25, -19, -12, -7, -3, 1, 7,
+
195 9, 10, 13, 15, 14, 16, 18, 15, 14, 13, 9, 6, 1, -2, -2, -1, -2, -4, 0, 2, 0, 0,
+
196 1, 0, -2, -3, -4, -5, -3, 0, 2, 6, 10, 13, 16, 19, 19, 21, 27, 26, 24, 28, 33,
+
197 35, 36, 42, 46, 49, 51, 50, 49, 51, 49, 46, 45, 45, 43, 42, 43, 43, 43, 44, 42,
+
198 38, 36, 32, 25, 21, 17, 9, 2, -4, -10, -17, -22, -26, -33, -35, -39, -48, -51,
+
199 -53, -57, -61, -63, -64, -67, -66, -65, -68, -62, -59, -56, -56, -53, -45, -44,
+
200 -40, -34, -28, -22, -20, -14, -6, -3, -1, 4, 11, 12, 13, 13, 16, 18, 18, 17, 13,
+
201 15, 14, 6, 2, 1, -2, -6, -7, -6, -7, -6, -4, -4, -3, -2, -4, -4, -3, -4, -5, -3,
+
202 1, 3, 7, 12, 14, 19, 23, 24, 25, 25, 25, 23, 23, 21, 19, 19, 22, 22, 20, 25, 31,
+
203 32, 33, 35, 38, 35, 32, 32, 30, 30, 29, 28, 30, 34, 36, 38, 40, 42, 42, 41, 39,
+
204 35, 31, 27, 20, 13, 9, 3, -4, -8, -13, -19, -24, -29, -37, -42, -48, -55, -60,
+
205 -65, -68, -70, -72, -74, -71, -69, -68, -67, -63, -59, -59, -55, -48, -46, -42,
+
206 -32, -28, -23, -14, -8, -3, 4, 8, 9, 13, 16, 15, 16, 20, 20, 16, 18, 19, 12, 10,
+
207 7, 2, -1, -1, -2, -2, 0, 1, 2, 5, 6, 4, 5, 8, 6, 4, 7, 10, 12, 18, 22, 24, 30,
+
208 36, 37, 38, 40, 39, 37, 37, 35, 31, 30, 31, 29, 27, 27, 24, 21, 20, 16, 12, 9,
+
209 6, 3, 1, 1, -1, -1, 3, 5, 4, 6, 8, 9, 10, 10, 12, 12, 13, 14, 12, 12, 10, 8, 8,
+
210 6, 1, 0, -2, -7, -10, -13, -17, -22, -25, -29, -34, -37, -41, -46, -44, -49,
+
211 -51, -48, -49, -48, -48, -45, -41, -40, -35, -33, -30, -24, -23, -20, -14, -10,
+
212 -7, -4, 2, 6, 6, 11, 10, 9, 13, 8, 4, 4, 1, -5, -7, -11, -14, -17, -19, -16,
+
213 -17, -15, -11, -10, -5, -5, -7, -2, 0, -1, 0, 4, 8, 11, 17, 23, 28, 35, 40, 43,
+
214 46, 47, 47, 47, 46, 44, 42, 42, 42, 40, 42, 42, 40, 39, 36, 33, 28, 21, 19, 13,
+
215 9, 7, 4, 4, 6, 6, 8, 9, 10, 11, 10, 9, 7, 4, 2, -1, -6, -9, -12, -13, -12, -17,
+
216 -20, -20, -19, -24, -30, -30, -31, -38, -40, -43, -47, -46, -45, -46, -48, -43,
+
217 -41, -45, -41, -40, -38, -37, -36, -30, -28, -23, -21, -17, -7, -6, -3, 1, 2, 2,
+
218 5, 4, 1, 2, 2, 0, -2, 0, -2, -7, -6, -5, -12, -15, -16, -17, -16, -14, -14, -14,
+
219 -7, -3, -3, -2, 1, 3, 4, 6, 5, 5, 10, 14, 17, 19, 22, 26, 30, 32, 30, 29, 29,
+
220 28, 24, 21, 24, 24, 27, 36, 37, 40, 46, 48, 48, 46, 46, 42, 37, 37, 34, 32, 35,
+
221 37, 40, 45, 47, 46, 46, 45, 38, 30, 23, 12, 1, -7, -15, -24, -28, -31, -35, -40,
+
222 -43, -47, -53, -57, -64, -71, -73, -77, -81, -78, -74, -74, -70, -61, -55, -54,
+
223 -47, -40, -39, -34, -29, -26, -21, -14, -8, -2, 5, 11, 15, 21, 24, 21, 23, 20,
+
224 14, 12, 11, 6, -1, -2, -2, -7, -10, -12, -12, -10, -8, -9, -11, -7, -4, -4, -2,
+
225 -1, 3, 9, 14, 15, 19, 28, 34, 38, 40, 44, 47, 49, 50, 48, 47, 47, 45, 43, 38,
+
226 35, 32, 29, 25, 20, 15, 11, 5, 1, -2, -6, -10, -11, -11, -11, -12, -11, -8, -4,
+
227 -2, 1, 2, 7, 11, 13, 17, 20, 22, 26, 27, 26, 24, 23, 22, 19, 15, 11, 5, 2, -2,
+
228 -7, -11, -17, -20, -25, -32, -38, -43, -45, -51, -55, -55, -57, -59, -56, -53,
+
229 -53, -50, -43, -42, -39, -33, -30, -27, -22, -17, -12, -7, -3, 1, 7, 11, 12, 12,
+
230 15, 15, 11, 8, 4, 2, -2, -8, -12, -14, -17, -21, -21, -17, -18, -18, -13, -8,
+
231 -9, -8, -4, -3, 0, 1, 2, 6, 13, 17, 22, 30, 37, 42, 48, 52, 52, 52, 53, 52, 49,
+
232 46, 44, 43, 42, 40, 38, 37, 35, 31, 27, 24, 18, 12, 7, 3, -2, -5, -5, -5, -4, 0,
+
233 1, 3, 7, 9, 9, 9, 9, 7, 6, 4, 1, -3, -5, -6, -8, -9, -10, -11, -14, -16, -16,
+
234 -21, -24, -28, -32, -34, -39, -45, -45, -44, -47, -48, -46, -46, -42, -37, -36,
+
235 -36, -30, -22, -23, -25, -16, -9, -11, -11, -2, 1, 0, 3, 7, 8, 8, 9, 6, 4, 4,
+
236 -3, -7, -7, -11, -16, -17, -18, -22, -21, -16, -12, -11, -9, -4, -3, -1, -1, -2,
+
237 2, 4, 4, 4, 6, 12, 18, 21, 25, 28, 31, 33, 31, 29, 28, 25, 22, 21, 16, 15, 20,
+
238 25, 27, 30, 38, 42, 40, 39, 41, 38, 34, 31, 28, 28, 28, 28, 33, 39, 43, 46, 48,
+
239 48, 45, 40, 35, 25, 14, 5, -7, -18, -23, -29, -34, -37, -40, -44, -47, -51, -55,
+
240 -60, -65, -70, -74, -76, -76, -77, -72, -65, -61, -53, -46, -38, -31, -26, -21,
+
241 -16, -10, -9, -5, 2, 3, 9, 15, 19, 22, 25, 27, 25, 23, 19, 13, 9, 3, -5, -13,
+
242 -17, -18, -23, -26, -25, -26, -23, -19, -18, -16, -11, -7, -6, -3, -1, 3, 9, 14,
+
243 18, 22, 31, 37, 41, 45, 48, 48, 47, 46, 42, 37, 32, 27, 23, 18, 13, 8, 6, 5, 0,
+
244 -4, -6, -8, -10, -12, -13, -13, -12, -8, -4, -1, 4, 11, 18, 25, 30, 34, 41, 45,
+
245 48, 50, 51, 52, 53, 50, 46, 40, 35, 28, 20, 11, 1, -7, -17, -26, -34, -43, -52,
+
246 -57, -60, -69, -74, -73, -77, -82, -79, -76, -78, -74, -66, -62, -58, -49, -39,
+
247 -33, -23, -12, -8, -1, 11, 16, 18, 24, 27, 28, 30, 30, 26, 25, 26, 19, 14, 11,
+
248 6, -1, -9, -14, -23, -30, -35, -39, -38, -37, -35, -30, -23, -18, -13, -6, 0, 3,
+
249 8, 12, 16, 20, 27, 35, 42, 51, 57, 63, 70, 72, 72, 70, 67, 61, 53, 45, 36, 30,
+
250 24, 17, 12, 6, 1, -4, -8, -14, -21, -26, -30, -33, -36, -36, -34, -30, -23, -16,
+
251 -8, 1, 9, 16, 23, 28, 32, 35, 37, 37, 35, 33, 31, 26, 21, 19, 17, 11, 4, 0, -6,
+
252 -18, -24, -29, -40, -48, -52, -62, -69, -68, -72, -73, -68, -69, -67, -59, -53,
+
253 -51, -46, -33, -28, -29, -15, -6, -6, 5, 15, 17, 23, 32, 31, 30, 35, 33, 27, 24,
+
254 21, 12, 7, 4, -8, -13, -11, -20, -26, -19, -16, -22, -20, -12, -12, -14, -12,
+
255 -11, -10, -5, -4, -5, 3, 12, 16, 23, 31, 36, 41, 47, 46, 42, 43, 42, 34, 28, 25,
+
256 20, 16, 16, 14, 11, 15, 16, 14, 13, 12, 11, 8, 6, 4, 1, 3, 4, 5, 12, 17, 20, 27,
+
257 33, 34, 36, 36, 32, 26, 20, 11, 2, -5, -10, -17, -23, -24, -28, -34, -35, -36,
+
258 -42, -48, -54, -57, -64, -71, -70, -68, -70, -64, -53, -48, -41, -30, -21, -13,
+
259 -10, -5, 0, 4, 6, 4, 10, 17, 18, 20, 25, 27, 27, 28, 23, 17, 11, 3, -5, -19,
+
260 -27, -32, -43, -44, -46, -48, -39, -33, -29, -19, -12, -6, 0, 3, 7, 12, 15, 20,
+
261 23, 29, 40, 45, 52, 61, 65, 68, 69, 65, 60, 52, 42, 32, 21, 11, 1, -8, -13, -17,
+
262 -21, -22, -23, -25, -24, -25, -26, -25, -24, -21, -18, -13, -5, 5, 15, 26, 37,
+
263 47, 56, 62, 67, 70, 70, 66, 61, 56, 45, 34, 25, 14, 3, -5, -16, -29, -35, -43,
+
264 -57, -64, -71, -81, -86, -86, -94, -100, -90, -83, -83, -75, -62, -52, -42, -27,
+
265 -19, -9, 5, 14, 19, 26, 35, 38, 44, 49, 49, 52, 53, 50, 46, 42, 33, 21, 12, 3,
+
266 -13, -26, -35, -45, -54, -62, -68, -66, -61, -58, -51, -41, -32, -23, -13, -4,
+
267 4, 12, 22, 29, 35, 43, 53, 62, 70, 76, 81, 84, 84, 82, 75, 67, 57, 45, 31, 17,
+
268 3, -9, -19, -29, -37, -42, -48, -51, -52, -53, -53, -51, -45, -40, -35, -24,
+
269 -13, -2, 11, 25, 38, 50, 60, 70, 79, 83, 84, 84, 81, 76, 67, 56, 43, 30, 17, 2,
+
270 -11, -26, -38, -51, -64, -71, -79, -93, -99, -96, -101, -108, -105, -95, -86,
+
271 -81, -70, -55, -39, -24, -15, -2, 16, 27, 32, 45, 52, 53, 59, 63, 63, 62, 60,
+
272 54, 47, 41, 31, 16, 5, -4, -21, -36, -47, -60, -68, -76, -87, -88, -79, -76,
+
273 -73, -58, -42, -31, -19, -4, 7, 19, 31, 38, 44, 55, 64, 70, 77, 83, 87, 92, 92,
+
274 86, 81, 75, 62, 46, 32, 16, -1, -14, -26, -39, -46, -49, -52, -53, -50, -48,
+
275 -43, -38, -35, -32, -24, -12, -1, 10, 18, 26, 41, 59, 72, 80, 82, 79, 79, 79,
+
276 73, 60, 42, 21, 5, -6, -22, -39, -45, -55, -70, -74, -73, -81, -91, -91, -92,
+
277 -97, -97, -92, -89, -81, -69, -55, -36, -18, -6, 13, 32, 43, 55, 64, 68, 68, 71,
+
278 69, 61, 57, 55, 47, 38, 32, 21, 10, 1, -13, -27, -41, -57, -72, -85, -95, -96,
+
279 -88, -83, -79, -63, -41, -25, -13, 4, 21, 33, 40, 43, 47, 56, 62, 64, 68, 74,
+
280 78, 83, 84, 81, 77, 71, 58, 41, 25, 9, -9, -23, -35, -45, -48, -46, -42, -36,
+
281 -28, -19, -10, -3, 3, 8, 11, 14, 19, 24, 30, 33, 40, 49, 52, 53, 53, 50, 42, 29,
+
282 15, 1, -14, -34, -48, -57, -68, -78, -83, -81, -80, -82, -83, -79, -71, -71,
+
283 -70, -61, -51, -44, -34, -20, -7, 10, 25, 37, 50, 62, 68, 69, 73, 72, 64, 57,
+
284 49, 40, 28, 17, 5, -5, -13, -26, -39, -47, -56, -64, -68, -69, -70, -68, -59,
+
285 -51, -44, -32, -17, -4, 7, 17, 28, 39, 48, 54, 58, 65, 67, 67, 68, 66, 61, 57,
+
286 52, 43, 33, 23, 12, 1, -8, -20, -29, -34, -37, -40, -38, -32, -26, -17, -6, 1,
+
287 10, 21, 28, 35, 40, 42, 44, 47, 47, 43, 38, 35, 30, 20, 9, 1, -5, -20, -32, -37,
+
288 -50, -62, -65, -72, -82, -84, -84, -86, -83, -79, -70, -61, -51, -40, -27, -13,
+
289 -3, 9, 24, 31, 36, 46, 51, 51, 55, 53, 51, 48, 42, 34, 24, 16, 4, -9, -21, -35,
+
290 -47, -55, -64, -68, -62, -61, -58, -45, -33, -24, -13, 0, 11, 19, 25, 32, 38,
+
291 44, 49, 52, 58, 60, 62, 66, 65, 61, 56, 51, 42, 29, 16, 4, -8, -18, -29, -37,
+
292 -41, -41, -41, -38, -32, -25, -16, -6, 3, 9, 18, 28, 34, 39, 43, 47, 50, 49, 43,
+
293 39, 35, 27, 16, 4, -7, -18, -29, -41, -53, -59, -67, -76, -77, -79, -83, -80,
+
294 -74, -71, -64, -55, -45, -32, -19, -8, 4, 19, 31, 40, 50, 56, 59, 63, 64, 58,
+
295 53, 48, 39, 28, 16, 3, -9, -20, -32, -45, -56, -64, -68, -69, -71, -70, -61,
+
296 -52, -45, -33, -18, -6, 8, 21, 31, 41, 52, 61, 67, 70, 72, 75, 76, 72, 65, 61,
+
297 56, 46, 35, 24, 13, 1, -10, -22, -32, -39, -43, -46, -47, -44, -39, -32, -22,
+
298 -12, -2, 9, 18, 28, 37, 41, 42, 45, 45, 42, 38, 30, 23, 18, 9, -5, -14, -20,
+
299 -29, -39, -47, -56, -60, -64, -71, -73, -69, -68, -66, -58, -49, -42, -30, -15,
+
300 -6, 3, 17, 27, 34, 42, 46, 47, 49, 48, 43, 37, 32, 24, 15, 6, -4, -13, -20, -27,
+
301 -34, -38, -41, -43, -42, -41, -42, -38, -31, -27, -23, -15, -6, 3, 12, 21, 30,
+
302 39, 47, 52, 55, 58, 58, 57, 53, 48, 42, 37, 31, 24, 18, 12, 7, 4, 1, -3, -6, -6,
+
303 -7, -8, -8, -8, -6, -6, -7, -8, -10, -11, -13, -18, -21, -25, -29, -33, -35,
+
304 -37, -37, -37, -37, -33, -30, -30, -26, -20, -18, -17, -12, -8, -4, 0, 3, 8, 13,
+
305 17, 21, 24, 26, 27, 25, 22, 17, 11, 4, -3, -11, -20, -23, -25, -28, -29, -27,
+
306 -25, -20, -15, -12, -9, -6, -4, -2, 1, 3, 6, 9, 11, 17, 24, 28, 30, 34, 35, 34,
+
307 33, 29, 23, 17, 10, 4, -1, -5, -9, -10, -11, -10, -7, -5, -2, 1, 2, 4, 5, 5, 5,
+
308 4, 1, 1, -1, -3, -6, -8, -11, -14, -17, -19, -24, -26, -27, -30, -34, -32, -30,
+
309 -30, -30, -27, -22, -18, -15, -9, -5, -1, 3, 7, 11, 15, 15, 16, 17, 16, 15, 12,
+
310 9, 7, 8, 6, 5, 6, 8, 8, 8, 9, 10, 8, 5, 3, 0, -3, -5, -7, -8, -8, -6, -3, -1, 1,
+
311 4, 6, 6, 6, 6, 4, 1, 0, -2, -4, -3, -3, -2, 1, 5, 8, 10, 13, 14, 16, 16, 15, 12,
+
312 8, 5, 2, -1, -5, -9, -14, -18, -22, -27, -31, -34, -39, -42, -43, -44, -44, -42,
+
313 -38, -32, -26, -21, -13, -6, 2, 8, 13, 18, 22, 23, 25, 25, 24, 22, 19, 15, 11,
+
314 6, 1, -4, -9, -14, -16, -17, -18, -19, -17, -15, -11, -8, -6, -2, 2, 4, 6, 10,
+
315 13, 15, 16, 19, 21, 21, 21, 20, 18, 16, 12, 8, 4, -1, -6, -10, -13, -14, -15,
+
316 -16, -15, -14, -11, -8, -5, -1, 2, 4, 7, 9, 10, 11, 10, 10, 8, 5, 2, -1, -8,
+
317 -13, -20, -28, -33, -39, -47, -50, -51, -54, -51, -45, -42, -36, -28, -18, -11,
+
318 -4, 4, 9, 14, 18, 20, 22, 23, 21, 20, 18, 15, 11, 6, -1, -7, -12, -17, -21, -25,
+
319 -28, -30, -29, -28, -26, -23, -19, -15, -10, -5, 1, 7, 12, 15, 21, 26, 29, 30,
+
320 31, 30, 29, 27, 23, 18, 14, 8, 2, -2, -6, -10, -14, -17, -19, -19, -19, -19,
+
321 -18, -16, -14, -11, -8, -4, -2, 0, 2, 5, 6, 5, 4, 5, 2, -4, -7, -9, -16, -23,
+
322 -27, -29, -33, -36, -35, -34, -32, -27, -24, -20, -14, -10, -7, -4, -1, 1, 1, 0,
+
323 0, 0, -1, -4, -6, -7, -10, -12, -13, -13, -13, -13, -12, -9, -7, -6, -4, -3, -1,
+
324 0, 0, 2, 3, 4, 4, 5, 7, 7, 7, 7, 7, 5, 3, 1, -1, -4, -8, -10, -12, -12, -12,
+
325 -12, -11, -8, -5, -1, 2, 6, 9, 12, 15, 17, 18, 19, 19, 17, 15, 14, 10, 5, -1,
+
326 -7, -13, -20, -28, -34, -39, -47, -52, -53, -52, -53, -51, -42, -34, -28, -18,
+
327 -5, 4, 12, 20, 27, 30, 32, 32, 30, 25, 21, 15, 7, 0, -6, -13, -18, -20, -22,
+
328 -25, -25, -24, -24, -22, -22, -21, -20, -20, -18, -16, -13, -11, -6, -2, 2, 6,
+
329 10, 13, 14, 14, 14, 12, 9, 5, 1, -3, -6, -9, -10, -11, -10, -9, -7, -5, -3, -1,
+
330 0, 1, 2, 3, 3, 4, 4, 4, 4, 4, 4, 1, -1, -4, -8, -13, -19, -23, -28, -35, -38,
+
331 -39, -42, -45, -41, -37, -35, -29, -19, -14, -7, 3, 9, 14, 21, 24, 24, 24, 23,
+
332 20, 14, 8, 2, -6, -13, -18, -22, -26, -29, -28, -25, -24, -21, -15, -13, -10,
+
333 -5, -2, 0, 3, 5, 5, 8, 10, 11, 12, 13, 13, 13, 12, 9, 7, 2, -3, -7, -11, -16,
+
334 -20, -23, -25, -25, -24, -22, -19, -15, -10, -6, -1, 3, 6, 9, 10, 12, 12, 12,
+
335 11, 10, 9, 6, 4, 1, -2, -6, -9, -13, -18, -22, -26, -32, -36, -37, -42, -46,
+
336 -44, -42, -41, -35, -28, -22, -14, -4, 4, 10, 16, 20, 19, 19, 17, 11, 4, -2, -9,
+
337 -15, -18, -21, -23, -19, -16, -14, -7, -1, 1, 3, 7, 7, 6, 7, 5, 3, 3, 4, 4, 4,
+
338 7, 9, 9, 10, 11, 9, 5, 2, -2, -7, -11, -16, -19, -20, -20, -19, -16, -12, -7,
+
339 -1, 4, 9, 13, 16, 17, 18, 17, 14, 11, 8, 4, 1, -2, -5, -8, -10, -11, -15, -16,
+
340 -18, -23, -24, -27, -31, -34, -36, -36, -37, -37, -33, -30, -25, -17, -10, -3,
+
341 4, 11, 15, 19, 21, 19, 17, 13, 6, -1, -7, -15, -20, -22, -26, -27, -24, -21,
+
342 -17, -12, -6, -3, 0, 4, 5, 5, 6, 4, 3, 4, 4, 4, 5, 7, 9, 10, 12, 12, 11, 9, 7,
+
343 3, 0, -5, -9, -12, -14, -14, -13, -11, -7, -3, 2, 7, 10, 14, 17, 17, 17, 16, 14,
+
344 11, 7, 5, 2, 0, -2, -4, -4, -5, -6, -7, -8, -11, -14, -16, -21, -26, -29, -34,
+
345 -35, -36, -38, -35, -30, -24, -17, -9, -2, 6, 14, 19, 20, 22, 21, 15, 11, 5, -3,
+
346 -9, -14, -19, -22, -21, -19, -17, -13, -8, -5, 0, 3, 4, 6, 5, 4, 4, 2, 1, 0, 0,
+
347 2, 3, 4, 6, 7, 8, 9, 8, 5, 3, 0, -4, -7, -10, -12, -13, -13, -11, -9, -5, -1, 4,
+
348 8, 12, 15, 17, 18, 18, 16, 14, 11, 7, 5, 2, 0, 0, 0, 0, 2, 4, 5, 6, 6, 5, 3, 2,
+
349 -2, -6, -11, -16, -21, -26, -27, -32, -35, -32, -33, -29, -23, -21, -14, -7, -1,
+
350 6, 10, 14, 17, 18, 18, 17, 14, 11, 7, 4, 2, 0, -2, -3, -3, -3, -2, -1, -2, -2,
+
351 -1, -3, -3, -4, -6, -7, -6, -6, -5, -3, -1, 2, 5, 9, 11, 12, 14, 13, 12, 11, 8,
+
352 5, 2, -1, -3, -4, -4, -4, -2, 0, 3, 6, 9, 11, 13, 14, 15, 14, 12, 10, 8, 5, 2,
+
353 1, 0, -1, 1, 1, 3, 5, 5, 6, 6, 5, 2, 0, -3, -6, -9, -13, -15, -18, -20, -21,
+
354 -24, -22, -22, -21, -18, -14, -11, -7, -2, 1, 5, 8, 10, 12, 12, 11, 10, 8, 6, 4,
+
355 2, -1, -1, -3, -4, -3, -4, -3, -2, -2, -1, 0, 0, 1, 3, 4, 6, 8, 10, 12, 13, 14,
+
356 14, 13, 12, 9, 7, 4, 0, -3, -7, -9, -11, -13, -13, -13, -11, -8, -5, -2, 2, 6,
+
357 10, 13, 15, 17, 18, 18, 17, 16, 14, 12, 10, 7, 5, 3, 2, 1, 1, 1, 2, 2, 3, 4, 4,
+
358 4, 4, 4, 3, 1, 0, -1, -3, -5, -6, -10, -12, -16, -21, -24, -29, -33, -36, -38,
+
359 -36, -34, -28, -20, -11, 1, 12, 24, 33, 41, 45, 45, 44, 36, 29, 19, 6, -4, -15,
+
360 -24, -30, -34, -35, -33, -28, -22, -15, -7, 1, 7, 13, 17, 20, 21, 21, 20, 18,
+
361 16, 15, 12, 11, 9, 7, 6, 4, 2, -1, -4, -7, -10, -13, -15, -16, -16, -14, -11,
+
362 -7, -2, 4, 9, 15, 19, 22, 24, 23, 21, 17, 12, 6, -1, -7, -13, -17, -20, -21,
+
363 -20, -18, -14, -9, -3, 2, 7, 12, 15, 17, 18, 17, 15, 13, 11, 9, 8, 8, 9, 11, 14,
+
364 17, 20, 23, 24, 23, 21, 18, 11, 4, -3, -12, -20, -27, -33, -37, -38, -38, -35,
+
365 -32, -28, -23, -18, -10, -3, 2, 11, 16, 22, 28, 31, 34, 34, 32, 28, 24, 17, 9,
+
366 1, -7, -14, -20, -25, -27, -28, -26, -22, -17, -10, -2, 5, 12, 19, 24, 28, 30,
+
367 30, 30, 27, 24, 19, 14, 9, 4, 0, -5, -8, -10, -12, -13, -13, -12, -10, -8, -5,
+
368 -3, 1, 4, 7, 10, 13, 15, 16, 17, 17, 17, 16, 14, 11, 8, 4, 1, -3, -5, -8, -10,
+
369 -11, -11, -11, -9, -7, -4, -1, 3, 6, 9, 12, 14, 16, 17, 17, 17, 15, 13, 12, 9,
+
370 7, 4, 2, 1, -1, 0, 1, 4, 8, 12, 18, 23, 27, 31, 32, 31, 27, 21, 13, 4, -6, -16,
+
371 -24, -31, -35, -37, -36, -32, -27, -19, -11, -4, 4, 10, 15, 18, 19, 19, 18, 15,
+
372 12, 9, 5, 2, -1, -3, -6, -7, -8, -11, -12, -13, -14, -15, -14, -13, -10, -6, -2,
+
373 4, 9, 16, 21, 26, 30, 31, 32, 30, 26, 20, 14, 7, -1, -7, -14, -19, -22, -24,
+
374 -23, -22, -18, -14, -9, -3, 2, 7, 12, 16, 19, 21, 22, 22, 21, 20, 19, 16, 14,
+
375 11, 8, 5, 2, -2, -5, -8, -11, -13, -15, -15, -15, -14, -11, -8, -3, 1, 7, 13,
+
376 21, 30, 34, 41, 43, 42, 42, 35, 26, 15, 3, -10, -22, -32, -40, -46, -48, -47,
+
377 -43, -37, -29, -20, -11, 0, 9, 17, 24, 28, 32, 33, 33, 31, 26, 23, 17, 12, 7, 1,
+
378 -3, -7, -9, -11, -11, -11, -9, -7, -4, -1, 3, 6, 8, 11, 11, 12, 12, 10, 9, 5, 2,
+
379 -2, -6, -8, -10, -12, -12, -12, -10, -7, -5, -2, 1, 3, 6, 7, 8, 8, 8, 7, 7, 6,
+
380 6, 6, 5, 6, 6, 6, 7, 6, 6, 6, 4, 3, 1, 0, -2, -4, -5, -6, -6, -6, -4, -3, 2, 5,
+
381 9, 16, 18, 23, 27, 28, 29, 27, 25, 20, 15, 8, 1, -6, -12, -16, -20, -20, -20,
+
382 -18, -14, -11, -6, -2, 1, 3, 4, 3, 3, 0, -3, -5, -7, -9, -8, -7, -5, -1, 2, 8,
+
383 12, 16, 18, 19, 19, 17, 13, 8, 2, -4, -10, -14, -17, -18, -18, -16, -11, -6, 1,
+
384 8, 14, 20, 24, 26, 27, 26, 22, 18, 13, 8, 3, -2, -5, -7, -9, -8, -7, -6, -4, -2,
+
385 0, 3, 3, 4, 4, 3, 2, 1, 1, 0, 1, 1, 2, 4, 6, 9, 11, 13, 14, 14, 14, 13, 11, 8,
+
386 5, 2, -2, -5, -8, -4, -4, 1, 7, 9, 18, 22, 26, 29, 28, 25, 20, 14, 6, -2, -11,
+
387 -19, -25, -30, -31, -31, -29, -23, -17, -10, -2, 5, 12, 17, 22, 24, 24, 23, 21,
+
388 18, 14, 11, 8, 5, 4, 3, 3, 4, 5, 6, 7, 8, 8, 7, 6, 4, 2, 0, -1, -3, -3, -4, -3,
+
389 -3, -2, -1, -1, -1, 0, 0, -1, -1, -3, -2, -2, -2, -2, -2, -1, 0, 1, 3, 4, 5, 7,
+
390 9, 9, 11, 11, 11, 12, 11, 11, 10, 9, 8, 7, 7, 7, 6, 6, 7, 8, 9, 10, 11, 12, 13,
+
391 13, 13, 13, 12, 11, 9, 8, 7, 5, 4, 3, 2, 1, 1, 1, 1, 0, 0, 0, 0, -1, -1, -3, -3,
+
392 -5, -6, -7, -9, -9, -10, -10, -10, -10, -10, -9, -8, -6, -5, -4, -2, 1, 4, 5, 8,
+
393 9, 11, 13, 13, 13, 12, 11, 9, 7, 6, 4, 2, 1, 1, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3,
+
394 3, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 9, 8, 6, 5, 3, 2, 0,
+
395 -1, -1, -2, -2, -1, 0, 1, 3, 4, 6, 7, 8, 9, 9, 9, 9, 8, 7, 6, 4, 3, 2, 1, 0, 1,
+
396 2, 5, 9, 12, 17, 19, 21, 22, 20, 17, 12, 6, 0, -7, -13, -18, -22, -23, -23, -21,
+
397 -18, -13, -8, -2, 4, 9, 12, 14, 16, 16, 14, 12, 9, 6, 3, 1, 0, -1, 0, 1, 3, 6,
+
398 8, 11, 13, 13, 14, 13, 11, 8, 4, -1, -6, -11, -16, -22, -24, -26, -26, -24, -22,
+
399 -17, -12, -5, 2, 7, 12, 17, 20, 22, 23, 21, 20, 17, 14, 12, 8, 5, 3, 1, 1, 0, 0,
+
400 2, 2, 3, 4, 4, 4, 5, 4, 3, 3, 2, 2, 2, 2, 3, 4, 6, 8, 10, 12, 14, 15, 16, 15,
+
401 14, 13, 11, 8, 5, 2, -1, -4, -6, -8, -9, -10, -10, -10, -9, -8, -8, -7, -7, -7,
+
402 -6, -7, -6, -7, -8, -8, -8, -7, -6, -5, -4, -2, 0, 1, 4, 5, 6, 9, 9, 10, 10, 9,
+
403 10, 9, 8, 7, 5, 4, 3, 2, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4,
+
404 5, 6, 7, 8, 9, 9, 9, 10, 9, 8, 7, 6, 4, 2, 1, -1, -2, -3, -3, -3, -3, -2, -1, 1,
+
405 2, 4, 5, 6, 7, 7, 7, 7, 7, 6, 5, 5, 3, 7, 9, 10, 17, 15, 19, 22, 19, 20, 16, 10,
+
406 5, -3, -9, -15, -22, -25, -27, -28, -24, -21, -16, -9, -3, 4, 10, 15, 19, 21,
+
407 22, 22, 21, 18, 15, 12, 9, 7, 5, 4, 3, 4, 5, 6, 7, 9, 9, 9, 8, 6, 5, 0, -3, -8,
+
408 -13, -18, -24, -26, -28, -27, -24, -22, -16, -9, 0, 8, 16, 22, 28, 31, 33, 33,
+
409 30, 25, 19, 12, 5, -2, -9, -13, -17, -19, -19, -18, -15, -11, -7, -2, 3, 7, 11,
+
410 14, 16, 17, 18, 17, 17, 16, 14, 14, 12, 11, 10, 9, 9, 8, 7, 7, 5, 4, 2, 0, -2,
+
411 -4, -7, -9, -12, -14, -15, -17, -17, -17, -16, -14, -13, -9, -7, -5, 0, 2, 5, 8,
+
412 9, 10, 11, 10, 8, 6, 3, 0, -1, -5, -5, -6, -6, -3, -2, 0, 3, 5, 7, 8, 9, 8, 8,
+
413 5, 3, 2, -2, -3, -4, -5, -5, -4, -3, -1, 1, 3, 5, 6, 7, 8, 7, 7, 5, 3, 2, 0, -2,
+
414 -3, -4, -4, -3, -2, -1, 1, 2, 4, 6, 6, 7, 7, 6, 6, 4, 3, 1, -1, -1, -2, -2, -2,
+
415 1, 5, 6, 15, 17, 21, 29, 28, 31, 32, 25, 22, 16, 5, -1, -12, -22, -27, -35, -37,
+
416 -37, -38, -32, -27, -20, -11, -3, 5, 13, 18, 23, 25, 26, 26, 23, 20, 16, 12, 9,
+
417 5, 2, 1, -1, -1, 0, 0, 2, 3, 3, 4, 3, 1, -1, -5, -9, -15, -23, -29, -32, -34,
+
418 -35, -33, -30, -23, -12, -3, 9, 19, 27, 35, 41, 45, 44, 41, 34, 27, 18, 7, -2,
+
419 -12, -19, -24, -27, -27, -25, -21, -16, -9, -2, 4, 10, 14, 17, 19, 18, 17, 15,
+
420 13, 11, 9, 8, 7, 7, 8, 9, 10, 12, 12, 13, 12, 11, 8, 4, 0, -5, -10, -16, -20,
+
421 -24, -27, -28, -28, -26, -23, -17, -12, -6, 1, 6, 12, 16, 19, 21, 21, 20, 18,
+
422 15, 11, 7, 3, -1, -5, -10, -13, -16, -18, -17, -18, -18, -15, -13, -10, -5, -2,
+
423 1, 4, 6, 8, 10, 11, 11, 11, 10, 10, 9, 8, 7, 5, 5, 3, 2, 2, 0, -1, -1, -2, -3,
+
424 -3, -4, -4, -4, -4, -4, -4, -3, -2, -1, 0, 1, 3, 4, 5, 6, 6, 6, 6, 6, 5, 4, 2,
+
425 2, 1, 0, 1, 2, 3, 6, 8, 10, 13, 14, 16, 17, 16, 15, 12, 8, 4, -2, -7, -13, -18,
+
426 -22, -26, -28, -29, -29, -27, -23, -19, -14, -8, -2, 4, 9, 13, 17, 20, 21, 22,
+
427 21, 21, 19, 17, 15, 12, 10, 8, 6, 4, 3, 2, 1, -1, -2, -3, -4, -6, -8, -10, -13,
+
428 -16, -20, -26, -29, -28, -29, -28, -26, -23, -14, -5, 3, 13, 20, 27, 32, 37, 40,
+
429 38, 35, 30, 24, 17, 10, 2, -5, -11, -16, -19, -20, -20, -19, -17, -14, -10, -6,
+
430 -4, -1, 0, 1, 2, 2, 1, 0, 0, 1, 2, 4, 8, 10, 15, 21, 25, 29, 31, 32, 31, 28, 24,
+
431 18, 10, 1, -7, -16, -23, -30, -35, -38, -39, -37, -33, -29, -22, -16, -9, -1, 5,
+
432 10, 15, 17, 19, 20, 19, 19, 17, 16, 14, 13, 11, 10, 10, 9, 9, 8, 8, 7, 6, 4, 1,
+
433 -1, -5, -10, -14, -21, -28, -32, -34, -36, -37, -36, -31, -24, -15, -5, 5, 14,
+
434 23, 31, 38, 42, 42, 40, 36, 31, 24, 16, 7, -1, -9, -15, -20, -22, -24, -25, -23,
+
435 -20, -17, -13, -9, -6, -4, -1, 0, 2, 2, 1, 1, 1, 1, 2, 3, 4, 5, 8, 12, 14, 17,
+
436 20, 21, 24, 25, 25, 24, 20, 17, 12, 7, 1, -5, -11, -17, -21, -24, -27, -28, -27,
+
437 -26, -23, -19, -15, -10, -7, -3, 0, 3, 6, 8, 8, 9, 10, 11, 11, 11, 12, 12, 12,
+
438 13, 14, 14, 13, 12, 11, 9, 7, 5, 2, -1, -4, -7, -9, -11, -13, -15, -15, -16,
+
439 -18, -21, -23, -22, -21, -22, -20, -18, -13, -8, -3, 4, 8, 14, 19, 23, 27, 27,
+
440 26, 26, 22, 20, 15, 10, 6, -1, -5, -8, -12, -14, -16, -16, -16, -15, -12, -10,
+
441 -9, -7, -4, -2, 0, 1, 2, 4, 7, 8, 12, 14, 16, 20, 23, 26, 28, 27, 28, 25, 22,
+
442 19, 13, 7, 0, -7, -13, -20, -25, -29, -32, -33, -33, -30, -27, -23, -17, -11,
+
443 -5, 2, 7, 12, 15, 18, 20, 20, 20, 19, 17, 15, 13, 11, 9, 7, 6, 5, 4, 3, 2, 1,
+
444 -1, -3, -5, -10, -14, -18, -21, -24, -27, -28, -28, -25, -22, -16, -10, -4, 3,
+
445 11, 17, 23, 27, 30, 31, 31, 29, 26, 21, 16, 10, 5, 1, -4, -8, -11, -12, -13,
+
446 -12, -11, -9, -9, -7, -5, -4, -3, -3, -3, -3, -4, -4, -4, -4, -3, -1, 1, 4, 7,
+
447 9, 13, 17, 19, 22, 24, 25, 25, 25, 24, 21, 17, 13, 8, 2, -3, -8, -13, -17, -21,
+
448 -23, -24, -25, -24, -23, -21, -18, -15, -11, -9, -6, -2, 0, 2, 4, 5, 6, 7, 8, 9,
+
449 9, 10, 11, 12, 13, 13, 13, 13, 12, 12, 10, 9, 7, 4, 2, -1, -3, -5, -8, -9, -11,
+
450 -12, -12, -13, -14, -16, -18, -19, -19, -18, -19, -19, -18, -14, -11, -7, -3, 1,
+
451 6, 10, 15, 19, 21, 22, 23, 23, 22, 19, 16, 12, 7, 3, 0, -3, -7, -11, -13, -13,
+
452 -13, -13, -13, -11, -10, -9, -7, -4, -4, -4, -3, -2, 2, 4, 4, 8, 11, 14, 17, 20,
+
453 22, 19, 20, 20, 17, 15, 10, 5, 2, -5, -9, -12, -17, -20, -23, -22, -21, -21,
+
454 -19, -17, -14, -10, -7, -3, 0, 2, 4, 6, 8, 8, 7, 7, 7, 6, 7, 5, 5, 5, 4, 4, 4,
+
455 3, 2, -1, -3, -4, -6, -8, -12, -13, -14, -15, -14, -13, -12, -11, -8, -4, -1, 2,
+
456 5, 8, 11, 13, 14, 16, 15, 14, 12, 11, 10, 7, 4, 2, 0, -1, -3, -4, -4, -5, -5,
+
457 -4, -3, -3, -3, -2, -2, -2, -2, -2, -3, -3, -4, -3, -3, -3, -2, -1, 0, 2, 3, 5,
+
458 7, 8, 11, 14, 15, 17, 18, 20, 20, 20, 20, 17, 13, 12, 8, 4, 1, -5, -8, -11, -15,
+
459 -16, -18, -19, -20, -20, -18, -17, -16, -14, -13, -11, -8, -6, -4, -2, -1, 1, 3,
+
460 5, 7, 8, 10, 11, 13, 14, 15, 15, 16, 16, 16, 15, 14, 13, 11, 10, 8, 6, 3, 0, -3,
+
461 -6, -9, -12, -15, -17, -20, -23, -25, -27, -27, -26, -26, -25, -22, -18, -14,
+
462 -9, -3, 2, 6, 11, 16, 20, 22, 22, 23, 23, 23, 20, 17, 15, 12, 8, 5, 2, 0, -4,
+
463 -6, -8, -8, -10, -12, -12, -12, -13, -13, -12, -10, -8, -7, -4, 1, 5, 8, 11, 16,
+
464 18, 19, 20, 21, 20, 18, 15, 12, 9, 4, 0, -4, -7, -11, -13, -15, -17, -17, -17,
+
465 -17, -16, -15, -13, -12, -10, -9, -7, -5, -4, -4, -2, -2, -1, 0, 0, 1, 1, 1, 0,
+
466 -1, -2, -1, -2, -4, -5, -4, -4, -4, -3, -3, -3, -2, -1, 0, 1, 0, 0, 1, 1, 1, 0,
+
467 0, -1, -2, -2, -1, -1, -2, -2, -1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, -1, -2,
+
468 -2, -3, -3, -4, -4, -3, -3, -3, -2, -1, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 3,
+
469 3, 5, 7, 9, 11, 13, 15, 16, 16, 15, 14, 13, 10, 6, 2, -2, -7, -11, -14, -19,
+
470 -22, -24, -25, -26, -26, -25, -24, -21, -18, -15, -12, -9, -5, -2, 1, 4, 6, 8,
+
471 9, 11, 12, 13, 14, 14, 14, 15, 15, 15, 14, 14, 13, 12, 11, 9, 7, 5, 2, -1, -5,
+
472 -9, -13, -17, -22, -26, -30, -31, -32, -34, -34, -31, -28, -24, -19, -13, -6,
+
473 -1, 5, 12, 18, 21, 24, 27, 29, 29, 27, 25, 23, 19, 15, 11, 8, 4, 0, -4, -5, -7,
+
474 -9, -11, -11, -11, -11, -11, -11, -11, -11, -11, -9, -7, -6, -5, -2, 2, 4, 7,
+
475 11, 13, 15, 17, 19, 20, 19, 19, 17, 15, 12, 9, 5, 1, -4, -8, -11, -15, -19, -21,
+
476 -23, -24, -24, -23, -22, -21, -19, -16, -13, -10, -7, -5, -2, 0, 2, 3, 3, 3, 3,
+
477 2, 1, 1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 6, 4, 4, 2, -1, -3, -4, -6,
+
478 -8, -9, -9, -9, -9, -9, -7, -5, -4, -2, 0, 3, 4, 6, 7, 8, 9, 8, 8, 8, 6, 5, 3,
+
479 2, 0, -1, -2, -2, -3, -3, -2, -2, -1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2,
+
480 4, 6, 8, 10, 11, 13, 14, 15, 15, 14, 12, 10, 8, 4, 0, -4, -8, -12, -16, -20,
+
481 -22, -24, -26, -26, -25, -24, -22, -20, -16, -13, -9, -5, -1, 3, 6, 9, 11, 14,
+
482 16, 16, 17, 17, 17, 17, 16, 15, 14, 13, 12, 10, 9, 7, 4, 2, -1, -5, -9, -13,
+
483 -17, -20, -24, -28, -30, -31, -32, -32, -30, -27, -23, -19, -14, -7, -1, 5, 10,
+
484 15, 21, 24, 26, 28, 29, 28, 26, 24, 21, 18, 13, 9, 5, 2, -1, -4, -7, -8, -9,
+
485 -10, -11, -11, -11, -11, -11, -11, -11, -11, -11, -9, -7, -8, -5, 0, 1, 4, 10,
+
486 13, 14, 18, 22, 23, 23, 24, 22, 20, 19, 14, 9, 5, -2, -7, -11, -16, -21, -24,
+
487 -26, -29, -29, -28, -27, -26, -23, -21, -18, -14, -12, -9, -7, -6, -4, -2, -2,
+
488 -3, -2, 0, 0, 0, 2, 3, 5, 7, 8, 11, 13, 13, 13, 14, 15, 13, 11, 9, 7, 4, 1, -3,
+
489 -6, -9, -12, -15, -16, -17, -18, -18, -17, -16, -14, -12, -10, -7, -4, -2, 1, 3,
+
490 5, 7, 8, 8, 9, 9, 8, 7, 7, 6, 5, 3, 2, 1, 0, -1, -2, -2, -3, -4, -4, -4, -5, -5,
+
491 -5, -4, -4, -4, -2, -1, 0, 2, 4, 5, 6, 8, 9, 10, 10, 10, 9, 8, 7, 5, 2, -1, -4,
+
492 -7, -10, -14, -17, -19, -22, -24, -24, -24, -24, -23, -21, -19, -16, -13, -10,
+
493 -7, -3, 0, 3, 6, 8, 10, 12, 13, 14, 14, 14, 13, 13, 11, 9, 7, 4, 0, -3, -6, -9,
+
494 -12, -15, -17, -18, -19, -19, -20, -19, -17, -16, -13, -11, -8, -5, -3, 0, 3, 6,
+
495 7, 9, 11, 12, 12, 12, 12, 12, 11, 10, 9, 9, 7, 6, 4, 4, 2, 1, 0, -1, -2, -3, -4,
+
496 -5, -6, -7, -8, -9, -9, -10, -10, -10, -10, -9, -8, -7, -4, -1, 2, 4, 9, 13, 15,
+
497 19, 22, 24, 24, 25, 25, 23, 21, 17, 13, 10, 5, -1, -5, -10, -15, -19, -22, -25,
+
498 -27, -28, -29, -28, -26, -24, -22, -19, -15, -13, -9, -6, -4, -1, 1, 1, 3, 4, 3,
+
499 3, 3, 2, 3, 3, 2, 3, 4, 5, 6, 8, 10, 11, 11, 12, 13, 13, 12, 10, 9, 7, 4, 1, -2,
+
500 -5, -9, -11, -14, -15, -16, -17, -16, -15, -13, -11, -8, -5, -2, 1, 4, 7, 9, 11,
+
501 12, 12, 12, 12, 11, 9, 7, 5, 3, 1, -1, -2, -3, -5, -5, -6, -6, -6, -5, -5, -3,
+
502 -1, 0, 2, 4, 7, 7, 9, 11, 11, 11, 12, 12, 11, 10, 8, 6, 4, 2, -1, -4, -7, -10,
+
503 -12, -14, -16, -18, -19, -20, -20, -19, -19, -18, -17, -15, -13, -11, -9, -7,
+
504 -4, -2, 0, 3, 6, 7, 9, 11, 12, 13, 14, 14, 13, 13, 12, 10, 8, 5, 1, -2, -5, -8,
+
505 -12, -14, -17, -19, -19, -20, -21, -20, -19, -17, -15, -12, -10, -7, -4, -1, 2,
+
506 4, 6, 7, 9, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -3,
+
507 -4, -5, -6, -8, -8, -9, -10, -10, -9, -8, -7, -5, -3, 0, 2, 6, 9, 11, 14, 16,
+
508 18, 19, 19, 19, 18, 16, 14, 11, 8, 4, -1, -5, -9, -14, -18, -22, -25, -27, -29,
+
509 -30, -30, -30, -28, -26, -23, -20, -16, -12, -9, -5, -1, 1, 4, 6, 7, 8, 8, 9, 9,
+
510 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 8, 8, 7, 5, 4, 2, -1, -3, -6, -8, -10,
+
511 -12, -14, -14, -15, -14, -14, -12, -10, -8, -6, -3, 0, 3, 5, 8, 10, 11, 13, 13,
+
512 13, 13, 13, 12, 10, 9, 7, 6, 4, 2, 0, -1, -2, -2, -2, -3, -1, 1, 2, 4, 7, 9, 10,
+
513 12, 14, 14, 15, 14, 13, 12, 10, 6, 3, 0, -6, -10, -14, -18, -22, -25, -27, -29,
+
514 -29, -29, -28, -26, -23, -20, -16, -11, -7, -2, 3, 6, 10, 14, 16, 18, 20, 20,
+
515 19, 19, 16, 14, 11, 7, 4, 1, -2, -6, -9, -11, -12, -13, -14, -14, -13, -11, -11,
+
516 -9, -7, -5, -4, -3, -1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 5, 6, 7,
+
517 7, 8, 9, 9, 9, 8, 8, 6, 5, 3, 1, -1, -3, -5, -7, -9, -10, -11, -13, -13, -10,
+
518 -9, -9, -4, 0, 2, 6, 11, 14, 18, 20, 23, 25, 25, 25, 23, 21, 19, 13, 8, 5, -2,
+
519 -8, -13, -19, -25, -28, -32, -35, -36, -36, -36, -35, -31, -28, -24, -20, -15,
+
520 -10, -5, -2, 3, 7, 10, 11, 13, 14, 14, 13, 13, 12, 10, 10, 9, 7, 7, 7, 6, 6, 7,
+
521 7, 8, 8, 8, 8, 8, 7, 6, 5, 3, 0, -2, -4, -7, -10, -12, -15, -16, -17, -18, -19,
+
522 -18, -17, -15, -13, -9, -6, -3, 1, 5, 9, 12, 15, 17, 19, 20, 20, 20, 19, 18, 16,
+
523 13, 10, 8, 5, 2, 1, -2, -3, -2, -2, -2, 0, 2, 3, 5, 7, 9, 10, 11, 11, 10, 9, 8,
+
524 4, 1, -2, -7, -11, -14, -19, -22, -24, -28, -29, -29, -29, -28, -25, -23, -19,
+
525 -15, -10, -5, 0, 5, 9, 13, 16, 19, 20, 21, 21, 19, 18, 15, 12, 9, 6, 2, 0, -2,
+
526 -4, -6, -7, -7, -6, -6, -4, -3, -1, 0, 2, 3, 5, 5, 5, 5, 4, 3, 2, 0, -2, -3, -5,
+
527 -7, -8, -8, -9, -9, -8, -7, -5, -2, 0, 2, 5, 8, 10, 12, 14, 15, 15, 16, 15, 14,
+
528 13, 10, 8, 6, 3, 0, -2, -3, -3, -6, -6, -3, -3, -1, 3, 5, 8, 10, 13, 16, 17, 17,
+
529 18, 15, 15, 13, 8, 5, 1, -6, -9, -14, -21, -24, -27, -31, -33, -33, -33, -32,
+
530 -31, -28, -25, -21, -17, -12, -8, -3, 1, 4, 8, 10, 12, 14, 16, 15, 15, 15, 14,
+
531 13, 13, 11, 11, 10, 9, 9, 9, 9, 8, 7, 8, 7, 7, 6, 5, 4, 3, 1, -2, -3, -5, -8,
+
532 -11, -13, -14, -16, -17, -18, -18, -17, -16, -15, -12, -9, -7, -4, 0, 4, 7, 10,
+
533 13, 16, 18, 19, 20, 21, 21, 20, 19, 17, 15, 14, 12, 10, 8, 8, 7, 5, 6, 6, 6, 6,
+
534 6, 7, 7, 6, 5, 3, 1, 0, -4, -7, -9, -14, -17, -20, -24, -25, -27, -29, -30, -28,
+
535 -28, -26, -24, -21, -16, -13, -10, -5, -1, 3, 6, 9, 12, 15, 16, 17, 18, 18, 18,
+
536 18, 17, 16, 15, 13, 11, 10, 9, 8, 6, 5, 4, 3, 3, 3, 2, 1, 1, 0, -1, -1, -2, -3,
+
537 -4, -6, -6, -7, -8, -9, -10, -10, -10, -10, -10, -8, -7, -6, -4, -2, 1, 4, 6, 9,
+
538 11, 13, 15, 16, 17, 18, 18, 17, 17, 16, 14, 13, 14, 12, 9, 11, 11, 9, 11, 11,
+
539 10, 11, 10, 10, 11, 9, 8, 6, 2, 2, -2, -7, -9, -14, -18, -20, -26, -27, -28,
+
540 -32, -33, -32, -32, -30, -29, -27, -23, -19, -16, -11, -6, -1, 3, 7, 11, 16, 18,
+
541 20, 22, 24, 25, 25, 24, 24, 23, 20, 18, 16, 15, 12, 9, 7, 6, 4, 2, 0, -1, -2,
+
542 -3, -5, -5, -5, -7, -8, -9, -9, -10, -11, -12, -12, -12, -12, -12, -11, -10, -9,
+
543 -8, -6, -3, -1, 1, 3, 6, 8, 10, 12, 13, 15, 16, 16, 16, 16, 16, 15, 16, 16, 13,
+
544 14, 15, 13, 14, 14, 13, 13, 13, 12, 12, 10, 9, 6, 2, 1, -1, -7, -10, -13, -18,
+
545 -21, -26, -29, -30, -34, -36, -37, -37, -36, -36, -35, -31, -28, -26, -20, -15,
+
546 -10, -5, -1, 5, 10, 15, 18, 23, 26, 28, 29, 31, 32, 31, 30, 29, 27, 25, 22, 18,
+
547 15, 13, 8, 5, 2, -1, -4, -7, -9, -11, -13, -15, -16, -17, -17, -18, -18, -18,
+
548 -17, -17, -16, -15, -14, -12, -11, -9, -7, -5, -3, 0, 2, 5, 7, 9, 12, 14, 16,
+
549 17, 18, 20, 21, 21, 21, 22, 23, 22, 22, 22, 22, 22, 21, 19, 18, 17, 15, 12, 10,
+
550 6, 3, -1, -5, -9, -14, -18, -23, -27, -31, -34, -38, -40, -41, -42, -42, -42,
+
551 -40, -37, -35, -31, -26, -21, -16, -10, -4, 2, 7, 12, 18, 23, 27, 30, 33, 36,
+
552 38, 39, 39, 40, 39, 37, 35, 33, 30, 27, 22, 19, 15, 10, 6, 1, -3, -7, -11, -14,
+
553 -17, -19, -22, -24, -25, -25, -26, -26, -25, -24, -23, -21, -19, -16, -14, -11,
+
554 -8, -4, -1, 3, 6, 10, 13, 16, 19, 22, 25, 27, 29, 31, 33, 34, 36, 36, 36, 36,
+
555 35, 34, 32, 29, 26, 22, 18, 13, 8, 3, -3, -9, -14, -20, -26, -30, -35, -39, -43,
+
556 -45, -47, -48, -49, -48, -46, -44, -41, -37, -32, -27, -22, -16, -9, -3, 2, 7,
+
557 14, 18, 22, 26, 30, 34, 36, 37, 39, 40, 40, 39, 38, 37, 35, 33, 30, 27, 24, 20,
+
558 16, 12, 9, 4, 0, -4, -7, -11, -15, -18, -21, -23, -25, -27, -28, -28, -29, -29,
+
559 -28, -26, -25, -23, -20, -17, -14, -11, -7, -3, 1, 4, 9, 13, 17, 21, 26, 30, 34,
+
560 37, 41, 44, 45, 46, 47, 46, 45, 42, 39, 34, 29, 22, 15, 8, 1, -7, -15, -22, -29,
+
561 -35, -41, -46, -50, -53, -55, -55, -55, -54, -51, -47, -43, -38, -32, -26, -20,
+
562 -14, -9, -2, 4, 9, 13, 18, 22, 25, 28, 31, 33, 35, 35, 36, 37, 38, 37, 37, 36,
+
563 35, 33, 31, 29, 27, 24, 20, 17, 13, 9, 5, 0, -4, -8, -12, -16, -19, -22, -25,
+
564 -28, -29, -30, -30, -30, -29, -28, -26, -23, -20, -17, -13, -9, -6, -2, 4, 8,
+
565 11, 17, 21, 24, 29, 32, 35, 37, 38, 38, 38, 37, 35, 32, 27, 25, 19, 13, 8, 2,
+
566 -3, -10, -16, -20, -24, -29, -33, -36, -38, -40, -41, -40, -39, -38, -36, -33,
+
567 -29, -26, -23, -19, -14, -11, -8, -3, 0, 3, 6, 9, 13, 16, 18, 21, 23, 26, 27,
+
568 29, 31, 32, 33, 33, 34, 33, 32, 31, 29, 27, 24, 20, 17, 13, 9, 4, 0, -4, -8,
+
569 -12, -15, -18, -21, -23, -24, -25, -25, -25, -24, -23, -21, -19, -17, -15, -10,
+
570 -7, -3, 2, 7, 11, 16, 20, 24, 27, 29, 30, 31, 30, 29, 27, 23, 20, 16, 10, 5, 0,
+
571 -5, -10, -16, -20, -23, -26, -29, -31, -31, -30, -30, -29, -26, -24, -22, -20,
+
572 -17, -13, -10, -8, -6, -4, -2, 0, 1, 3, 5, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19,
+
573 20, 21, 22, 22, 21, 21, 21, 20, 18, 15, 13, 11, 9, 6, 4, 1, -1, -4, -6, -7, -8,
+
574 -9, -11, -11, -11, -11, -11, -10, -10, -9, -7, -6, -3, 0, 2, 5, 8, 11, 14, 15,
+
575 17, 18, 19, 18, 17, 16, 14, 12, 9, 5, 2, -2, -6, -10, -13, -17, -19, -22, -23,
+
576 -25, -26, -26, -26, -25, -24, -23, -21, -19, -18, -16, -14, -11, -10, -8, -6,
+
577 -4, -2, 0, 3, 5, 7, 9, 11, 14, 16, 17, 18, 21, 22, 22, 23, 23, 23, 22, 21, 20,
+
578 19, 17, 14, 12, 9, 7, 4, 2, 0, -2, -4, -6, -7, -8, -8, -8, -9, -8, -8, -7, -6,
+
579 -5, -3, 0, 1, 3, 7, 10, 12, 14, 17, 18, 19, 18, 18, 18, 17, 13, 10, 8, 5, 1, -3,
+
580 -7, -10, -14, -18, -20, -23, -24, -26, -28, -28, -28, -28, -27, -26, -24, -23,
+
581 -22, -20, -17, -15, -13, -12, -9, -6, -5, -2, 0, 3, 5, 6, 9, 11, 13, 15, 17, 18,
+
582 19, 20, 21, 21, 21, 21, 20, 18, 17, 16, 14, 11, 9, 7, 5, 3, 1, -1, -2, -3, -4,
+
583 -5, -5, -5, -5, -5, -4, -3, -2, -1, 2, 4, 5, 8, 10, 11, 13, 13, 13, 13, 12, 10,
+
584 9, 7, 4, 1, -2, -4, -7, -10, -13, -15, -17, -20, -22, -22, -23, -24, -24, -24,
+
585 -24, -23, -22, -21, -20, -19, -18, -16, -14, -12, -11, -10, -8, -7, -6, -4, -3,
+
586 -1, -1, 0, 2, 3, 5, 7, 8, 9, 10, 10, 12, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7,
+
587 7, 7, 7, 7, 7, 6, 6, 7, 7, 7, 8, 8, 8, 9, 10, 10, 11, 11, 11, 11, 11, 9, 8, 7,
+
588 5, 2, 0, -2, -5, -7, -10, -13, -15, -18, -20, -21, -22, -24, -25, -24, -25, -25,
+
589 -24, -24, -23, -21, -21, -19, -17, -15, -13, -12, -9, -7, -6, -4, -2, -1, 0, 0,
+
590 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 3, 3, 3, 4, 5, 6, 6,
+
591 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, 18, 16, 16, 15, 12, 10,
+
592 8, 5, 2, -1, -4, -7, -10, -13, -16, -18, -21, -23, -25, -26, -27, -29, -29, -29,
+
593 -29, -29, -29, -28, -26, -25, -24, -22, -19, -16, -14, -11, -9, -6, -4, -3, -2,
+
594 0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 11, 11, 11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 7,
+
595 6, 7, 7, 7, 7, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 15, 14, 12,
+
596 11, 9, 6, 4, 1, -1, -3, -6, -8, -11, -13, -15, -17, -19, -20, -22, -23, -24,
+
597 -25, -26, -27, -27, -27, -26, -26, -25, -22, -20, -18, -16, -14, -12, -10, -10,
+
598 -10, -9, -8, -7, -6, -4, -3, -2, -1, -1, 0, 0, 1, 1, 1, 2, 3, 4, 4, 5, 7, 8, 9,
+
599 10, 12, 13, 13, 14, 15, 16, 17, 17, 18, 19, 19, 19, 20, 20, 21, 20, 20, 19, 18,
+
600 17, 15, 13, 11, 8, 5, 2, -1, -3, -7, -10, -12, -15, -17, -20, -22, -24, -25,
+
601 -27, -28, -29, -29, -30, -30, -29, -28, -27, -25, -23, -20, -16, -14, -11, -9,
+
602 -8, -8, -7, -7, -7, -5, -4, -4, -4, -3, -3, -3, -3, -4, -4, -4, -5, -5, -4, -4,
+
603 -4, -3, -2, -1, 1, 2, 3, 5, 7, 8, 10, 11, 13, 14, 15, 17, 19, 20, 21, 22, 24,
+
604 24, 25, 25, 24, 24, 22, 21, 19, 17, 15, 13, 10, 8, 5, 2, 0, -2, -5, -8, -11,
+
605 -14, -16, -18, -20, -23, -25, -27, -29, -30, -30, -31, -30, -29, -28, -26, -23,
+
606 -21, -18, -16, -17, -16, -18, -16, -11, -11, -12, -13, -10, -6, -5, -5, -7, -6,
+
607 -4, -2, -2, -2, -2, 0, 2, 3, 4, 5, 7, 8, 10, 10, 11, 12, 13, 14, 15, 16, 16, 17,
+
608 19, 20, 20, 21, 21, 21, 21, 20, 20, 19, 17, 16, 14, 12, 11, 9, 7, 5, 3, 1, -1,
+
609 -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -22, -23, -24, -25, -25, -24, -23,
+
610 -22, -20, -19, -17, -16, -16, -16, -16, -16, -16, -15, -14, -13, -13, -13, -12,
+
611 -11, -10, -10, -9, -8, -7, -6, -5, -4, -2, -1, 0, 2, 4, 5, 6, 8, 10, 11, 13, 14,
+
612 16, 18, 20, 21, 23, 24, 25, 26, 26, 26, 26, 25, 24, 23, 22, 20, 17, 15, 13, 11,
+
613 8, 6, 4, 1, -1, -4, -6, -9, -11, -13, -16, -18, -20, -22, -24, -25, -26, -27,
+
614 -26, -26, -24, -23, -21, -20, -19, -19, -19, -19, -18, -18, -18, -17, -16, -15,
+
615 -14, -13, -12, -11, -10, -9, -7, -6, -5, -3, -1, 0, 2, 4, 5, 7, 8, 10, 11, 12,
+
616 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 22, 22, 21, 20, 20, 19, 17, 16, 15,
+
617 13, 12, 10, 8, 6, 4, 2, 0, -2, -4, -5, -8, -10, -12, -14, -16, -18, -19, -21,
+
618 -22, -23, -23, -22, -21, -21, -20, -19, -18, -18, -19, -20, -21, -21, -21, -20,
+
619 -19, -18, -18, -17, -16, -14, -12, -11, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10,
+
620 12, 14, 15, 17, 19, 20, 22, 23, 25, 26, 26, 27, 28, 28, 27, 27, 26, 25, 23, 21,
+
621 19, 17, 15, 12, 10, 8, 5, 2, 0, -3, -5, -8, -11, -13, -16, -18, -20, -22, -24,
+
622 -26, -27, -27, -28, -28, -27, -25, -23, -21, -20, -19, -18, -18, -20, -19, -18,
+
623 -18, -17, -16, -15, -14, -13, -11, -9, -8, -6, -5, -3, -1, 0, 2, 4, 6, 8, 9, 11,
+
624 13, 14, 15, 16, 18, 19, 20, 21, 21, 22, 22, 23, 23, 22, 22, 22, 21, 19, 18, 17,
+
625 16, 14, 12, 11, 9, 7, 5, 3, 1, -2, -5, -7, -10, -13, -15, -18, -20, -23, -25,
+
626 -26, -27, -28, -27, -26, -25, -23, -22, -20, -20, -21, -22, -24, -24, -24, -24,
+
627 -23, -22, -21, -20, -18, -15, -13, -11, -9, -7, -5, -3, -1, 2, 4, 6, 8, 10, 12,
+
628 14, 16, 18, 19, 20, 22, 23, 25, 26, 26, 27, 27, 27, 27, 27, 25, 24, 23, 21, 19,
+
629 17, 14, 12, 10, 7, 4, 2, 0, -3, -5, -8, -10, -13, -16, -18, -20, -23, -25, -27,
+
630 -28, -30, -31, -31, -30, -29, -27, -25, -23, -21, -21, -21, -22, -22, -22, -22,
+
631 -21, -20, -18, -17, -15, -13, -10, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13,
+
632 15, 17, 18, 20, 21, 22, 24, 25, 26, 27, 27, 27, 27, 27, 26, 25, 23, 22, 20, 18,
+
633 16, 14, 12, 9, 6, 4, 1, -1, -4, -7, -9, -13, -15, -18, -20, -22, -26, -27, -29,
+
634 -30, -31, -31, -30, -29, -27, -25, -23, -20, -19, -19, -18, -18, -18, -19, -20,
+
635 -19, -19, -18, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 4, 5, 7, 9, 11, 13,
+
636 16, 17, 19, 21, 23, 25, 26, 28, 29, 30, 30, 30, 30, 30, 28, 27, 26, 23, 22, 19,
+
637 16, 15, 12, 8, 5, 3, 0, -3, -6, -9, -12, -15, -19, -22, -24, -27, -30, -32, -33,
+
638 -34, -35, -35, -34, -33, -31, -29, -26, -23, -21, -20, -20, -19, -19, -19, -18,
+
639 -17, -17, -16, -15, -12, -10, -7, -5, -3, 0, 2, 4, 7, 9, 10, 12, 14, 15, 17, 19,
+
640 21, 22, 24, 25, 26, 28, 28, 29, 29, 28, 28, 27, 26, 25, 22, 20, 18, 16, 13, 10,
+
641 8, 5, 3, -1, -3, -5, -7, -10, -12, -15, -17, -20, -22, -24, -26, -29, -31, -33,
+
642 -34, -35, -35, -34, -33, -32, -30, -27, -23, -21, -20, -20, -19, -19, -19, -19,
+
643 -18, -17, -16, -15, -13, -10, -8, -5, -4, -1, 1, 3, 5, 7, 9, 11, 12, 14, 16, 18,
+
644 20, 21, 23, 24, 26, 28, 29, 30, 30, 30, 30, 29, 29, 27, 26, 23, 21, 18, 15, 12,
+
645 9, 5, 2, -1, -4, -7, -10, -13, -16, -19, -22, -25, -26, -28, -31, -33, -35, -36,
+
646 -37, -38, -37, -37, -36, -34, -32, -28, -25, -23, -21, -20, -19, -18, -17, -17,
+
647 -16, -16, -15, -14, -11, -9, -6, -4, -2, 1, 3, 5, 8, 10, 12, 14, 15, 17, 19, 21,
+
648 23, 25, 26, 27, 29, 30, 31, 32, 32, 32, 31, 30, 29, 28, 25, 22, 19, 16, 13, 10,
+
649 7, 4, 0, -3, -6, -8, -11, -14, -16, -19, -21, -23, -26, -27, -29, -31, -34, -35,
+
650 -35, -36, -36, -36, -36, -34, -32, -29, -26, -23, -22, -20, -19, -18, -17, -17,
+
651 -16, -16, -15, -14, -13, -11, -8, -6, -3, -1, 1, 4, 6, 9, 11, 12, 14, 15, 17,
+
652 19, 21, 23, 24, 26, 27, 29, 31, 32, 33, 33, 34, 32, 32, 30, 28, 27, 24, 20, 18,
+
653 15, 11, 9, 4, 1, -2, -6, -9, -11, -15, -18, -20, -23, -26, -28, -31, -33, -35,
+
654 -38, -39, -39, -40, -40, -40, -40, -37, -34, -32, -28, -25, -23, -21, -21, -19,
+
655 -18, -17, -17, -16, -14, -14, -12, -9, -7, -4, -2, 1, 4, 6, 9, 11, 12, 14, 15,
+
656 17, 19, 20, 22, 23, 24, 26, 27, 29, 30, 31, 32, 32, 32, 31, 30, 29, 27, 24, 21,
+
657 18, 15, 12, 9, 6, 2, -1, -4, -6, -9, -12, -13, -16, -19, -21, -23, -25, -28,
+
658 -30, -33, -35, -36, -38, -39, -39, -38, -38, -37, -35, -32, -29, -27, -24, -23,
+
659 -21, -20, -20, -19, -18, -18, -17, -16, -15, -12, -10, -8, -5, -2, 1, 3, 6, 8,
+
660 10, 12, 14, 15, 17, 19, 21, 22, 24, 26, 27, 29, 31, 32, 32, 33, 33, 32, 32, 30,
+
661 28, 27, 23, 20, 17, 13, 10, 7, 3, 0, -4, -6, -8, -11, -13, -15, -17, -19, -22,
+
662 -24, -27, -29, -32, -34, -36, -37, -38, -39, -39, -39, -38, -37, -34, -32, -29,
+
663 -26, -25, -22, -21, -20, -19, -19, -18, -17, -16, -14, -12, -9, -7, -4, -1, 2,
+
664 4, 7, 9, 11, 13, 14, 16, 18, 20, 22, 24, 25, 27, 28, 29, 31, 32, 33, 33, 34, 32,
+
665 31, 30, 28, 25, 23, 20, 16, 14, 10, 6, 4, 0, -3, -5, -8, -10, -12, -14, -16,
+
666 -19, -21, -23, -25, -27, -30, -32, -34, -35, -36, -37, -37, -37, -36, -35, -34,
+
667 -31, -28, -27, -25, -23, -22, -20, -20, -19, -18, -17, -16, -15, -12, -9, -6,
+
668 -3, 0, 3, 6, 7, 10, 12, 14, 16, 17, 19, 21, 23, 24, 26, 28, 29, 31, 32, 32, 33,
+
669 33, 32, 32, 30, 29, 26, 23, 22, 17, 14, 12, 8, 6, 3, -1, -2, -6, -9, -10, -13,
+
670 -15, -17, -20, -22, -24, -26, -28, -30, -32, -33, -34, -35, -36, -36, -36, -35,
+
671 -34, -32, -30, -28, -27, -25, -24, -23, -22, -22, -22, -20, -19, -17, -15, -12,
+
672 -9, -7, -4, -1, 2, 5, 7, 9, 12, 14, 16, 18, 21, 23, 25, 27, 29, 31, 32, 34, 35,
+
673 36, 36, 35, 34, 33, 32, 30, 26, 24, 20, 16, 14, 11, 7, 6, 3, -1, -2, -5, -8, -9,
+
674 -12, -15, -16, -20, -22, -23, -26, -28, -28, -31, -32, -33, -35, -34, -34, -35,
+
675 -34, -33, -32, -30, -28, -27, -25, -23, -22, -21, -20, -20, -19, -18, -17, -15,
+
676 -12, -10, -6, -4, -1, 2, 4, 7, 9, 11, 14, 15, 17, 19, 22, 23, 26, 28, 30, 31,
+
677 33, 34, 35, 35, 35, 35, 34, 32, 31, 28, 25, 23, 19, 17, 15, 12, 9, 8, 5, 3, 1,
+
678 -2, -5, -7, -11, -14, -15, -19, -21, -22, -25, -27, -28, -31, -31, -32, -34,
+
679 -34, -34, -35, -34, -33, -32, -30, -29, -28, -27, -25, -25, -24, -23, -23, -21,
+
680 -20, -18, -15, -13, -11, -7, -5, -2, 1, 3, 6, 8, 10, 13, 15, 17, 20, 23, 24, 27,
+
681 30, 32, 34, 35, 36, 38, 38, 37, 37, 35, 35, 32, 29, 27, 24, 20, 19, 16, 13, 13,
+
682 10, 7, 6, 2, -1, -3, -7, -10, -12, -16, -18, -19, -22, -24, -25, -28, -29, -30,
+
683 -31, -32, -33, -34, -34, -34, -34, -33, -32, -31, -29, -28, -28, -26, -26, -26,
+
684 -24, -24, -22, -20, -18, -16, -13, -11, -8, -5, -3, 0, 2, 4, 6, 9, 10, 13, 15,
+
685 18, 21, 23, 26, 29, 31, 33, 35, 36, 37, 37, 37, 37, 35, 33, 31, 28, 25, 23, 19,
+
686 18, 17, 14, 13, 12, 8, 7, 4, 0, -3, -6, -9, -11, -14, -17, -19, -21, -24, -25,
+
687 -27, -29, -30, -31, -33, -34, -35, -36, -36, -36, -36, -35, -34, -34, -33, -32,
+
688 -31, -30, -29, -29, -27, -25, -23, -20, -18, -15, -12, -10, -7, -4, -2, 0, 3, 4,
+
689 7, 9, 11, 14, 17, 19, 22, 25, 26, 31, 32, 35, 36, 36, 37, 37, 36, 35, 34, 32,
+
690 29, 26, 23, 22, 20, 18, 17, 16, 14, 12, 10, 7, 4, 1, -3, -5, -8, -11, -14, -16,
+
691 -18, -20, -22, -23, -25, -26, -27, -28, -30, -31, -32, -33, -34, -34, -34, -34,
+
692 -34, -33, -32, -31, -30, -29, -28, -27, -25, -23, -21, -18, -16, -13, -10, -8,
+
693 -6, -3, -1, 1, 3, 5, 8, 10, 12, 15, 17, 20, 23, 26, 29, 31, 33, 35, 37, 37, 38,
+
694 38, 37, 36, 35, 33, 30, 28, 26, 23, 22, 21, 20, 19, 17, 15, 14, 10, 7, 4, 0, -3,
+
695 -6, -9, -12, -14, -17, -19, -20, -22, -24, -25, -26, -27, -28, -30, -31, -32,
+
696 -34, -35, -35, -35, -35, -34, -34, -32, -30, -29, -27, -25, -24, -22, -20, -18,
+
697 -16, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 10, 12, 14, 17, 20, 23, 25, 28,
+
698 31, 33, 35, 36, 37, 38, 37, 37, 35, 34, 32, 30, 27, 25, 24, 22, 21, 20, 20, 17,
+
699 16, 14, 10, 7, 3, -2, -5, -7, -11, -13, -15, -18, -20, -22, -24, -24, -26, -27,
+
700 -28, -29, -30, -31, -33, -34, -35, -36, -36, -36, -36, -35, -34, -32, -30, -28,
+
701 -26, -23, -21, -20, -18, -16, -14, -12, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 10,
+
702 12, 15, 18, 21, 23, 26, 29, 31, 34, 35, 36, 37, 38, 36, 36, 35, 32, 30, 29, 26,
+
703 23, 22, 20, 20, 19, 18, 16, 14, 11, 8, 4, 0, -5, -8, -12, -16, -17, -20, -22,
+
704 -23, -25, -26, -27, -27, -28, -29, -29, -31, -31, -33, -34, -35, -37, -37, -38,
+
705 -38, -37, -35, -34, -31, -28, -25, -22, -19, -17, -15, -14, -13, -12, -10, -9,
+
706 -7, -6, -4, -1, 0, 3, 5, 7, 10, 12, 15, 18, 22, 25, 27, 31, 33, 34, 36, 37, 38,
+
707 38, 37, 36, 36, 33, 30, 29, 26, 23, 22, 21, 19, 19, 18, 16, 14, 11, 8, 3, -1,
+
708 -6, -10, -13, -16, -19, -20, -21, -23, -23, -24, -24, -24, -25, -26, -26, -27,
+
709 -29, -30, -32, -34, -35, -37, -37, -37, -37, -36, -34, -32, -29, -25, -21, -17,
+
710 -14, -13, -11, -10, -10, -10, -9, -8, -7, -5, -3, 0, 3, 6, 8, 11, 14, 17, 19,
+
711 23, 26, 28, 31, 34, 35, 37, 38, 38, 39, 39, 38, 37, 36, 34, 31, 29, 26, 24, 21,
+
712 19, 17, 16, 14, 12, 10, 7, 3, -1, -5, -9, -12, -16, -18, -19, -20, -20, -21,
+
713 -21, -21, -22, -22, -23, -24, -25, -26, -28, -29, -30, -33, -34, -35, -36, -36,
+
714 -36, -35, -34, -32, -30, -27, -24, -20, -17, -15, -12, -10, -10, -9, -8, -8, -7,
+
715 -6, -5, -2, 1, 4, 8, 12, 15, 18, 20, 23, 26, 28, 30, 32, 34, 36, 37, 38, 39, 40,
+
716 40, 39, 38, 37, 35, 33, 30, 28, 24, 20, 17, 14, 12, 10, 8, 7, 5, 2, -1, -5, -9,
+
717 -12, -16, -19, -19, -21, -21, -21, -22, -21, -23, -24, -24, -26, -26, -28, -29,
+
718 -31, -32, -34, -35, -36, -38, -38, -37, -37, -35, -32, -30, -28, -25, -23, -19,
+
719 -17, -14, -11, -10, -7, -6, -5, -3, -2, -1, 1, 4, 7, 11, 14, 18, 21, 23, 26, 28,
+
720 30, 32, 34, 36, 37, 38, 39, 41, 40, 41, 40, 39, 39, 37, 36, 33, 30, 27, 22, 17,
+
721 14, 9, 6, 4, 3, 2, 1, -2, -5, -7, -11, -16, -19, -22, -23, -25, -25, -25, -25,
+
722 -26, -27, -27, -28, -29, -31, -32, -32, -34, -35, -35, -37, -38, -39, -40, -39,
+
723 -37, -35, -33, -29, -27, -24, -21, -18, -16, -13, -11, -8, -5, -3, 0, 2, 4, 6,
+
724 8, 10, 14, 17, 20, 24, 27, 29, 32, 34, 36, 38, 39, 40, 42, 43, 44, 45, 45, 45,
+
725 44, 43, 42, 38, 39, 36, 28, 29, 21, 16, 14, 5, 0, -2, -6, -9, -7, -10, -12, -11,
+
726 -15, -19, -21, -26, -30, -30, -32, -33, -30, -30, -30, -29, -30, -32, -32, -34,
+
727 -35, -35, -36, -36, -35, -37, -38, -37, -38, -37, -35, -33, -29, -25, -22, -18,
+
728 -15, -13, -10, -8, -6, -3, -1, 2, 6, 8, 10, 13, 15, 18, 22, 24, 27, 31, 33, 37,
+
729 40, 41, 43, 45, 45, 46, 48, 49, 49, 50, 50, 49, 48, 46, 43, 40, 36, 32, 27, 22,
+
730 17, 11, 5, -1, -7, -11, -16, -19, -19, -21, -21, -22, -24, -27, -28, -32, -36,
+
731 -36, -38, -38, -36, -35, -34, -33, -34, -35, -35, -36, -38, -38, -38, -37, -37,
+
732 -37, -36, -36, -34, -34, -33, -29, -25, -22, -18, -14, -11, -7, -5, -3, 0, 2, 4,
+
733 7, 10, 13, 17, 21, 24, 27, 30, 32, 35, 38, 40, 43, 45, 47, 49, 50, 50, 51, 52,
+
734 52, 52, 52, 51, 50, 48, 44, 40, 37, 31, 26, 21, 14, 8, 2, -5, -11, -15, -23,
+
735 -25, -26, -28, -29, -29, -30, -31, -32, -38, -39, -41, -46, -45, -44, -43, -40,
+
736 -38, -39, -37, -37, -40, -38, -40, -40, -37, -38, -36, -34, -33, -33, -30, -29,
+
737 -27, -22, -20, -15, -10, -5, -1, 2, 4, 7, 9, 11, 14, 17, 20, 24, 27, 30, 34, 36,
+
738 38, 41, 43, 45, 48, 50, 51, 54, 55, 55, 55, 55, 54, 53, 52, 50, 49, 47, 43, 39,
+
739 36, 30, 24, 21, 14, 7, 3, -4, -11, -14, -21, -28, -29, -35, -41, -41, -44, -47,
+
740 -45, -48, -48, -46, -48, -48, -47, -47, -47, -46, -46, -44, -43, -43, -41, -39,
+
741 -39, -37, -36, -34, -32, -30, -28, -25, -23, -19, -15, -12, -7, -4, 0, 4, 8, 10,
+
742 14, 17, 19, 22, 25, 27, 31, 34, 35, 38, 41, 42, 45, 47, 48, 50, 51, 52, 52, 53,
+
743 54, 52, 52, 52, 50, 49, 48, 44, 42, 40, 34, 31, 27, 20, 15, 10, 4, -3, -8, -16,
+
744 -21, -27, -35, -39, -44, -48, -51, -54, -56, -56, -58, -59, -58, -57, -56, -54,
+
745 -54, -54, -51, -50, -48, -44, -42, -39, -36, -35, -32, -30, -29, -27, -24, -22,
+
746 -17, -14, -11, -4, 0, 2, 7, 9, 12, 16, 18, 20, 25, 27, 29, 33, 35, 36, 38, 40,
+
747 41, 43, 45, 47, 49, 50, 51, 52, 51, 51, 51, 50, 48, 47, 47, 45, 44, 42, 39, 37,
+
748 33, 27, 23, 19, 12, 7, 3, -5, -11, -15, -24, -28, -33, -43, -46, -49, -56, -58,
+
749 -59, -64, -62, -62, -66, -63, -61, -62, -59, -55, -55, -51, -47, -47, -41, -39,
+
750 -38, -33, -30, -29, -25, -21, -19, -14, -11, -8, -3, 1, 5, 8, 13, 17, 19, 23,
+
751 26, 28, 32, 33, 35, 38, 40, 41, 44, 46, 47, 49, 51, 51, 53, 53, 52, 53, 53, 51,
+
752 51, 50, 48, 46, 45, 43, 41, 39, 36, 33, 29, 25, 20, 15, 11, 4, -2, -7, -13, -22,
+
753 -26, -32, -40, -44, -50, -55, -56, -60, -65, -64, -66, -70, -68, -67, -68, -65,
+
754 -63, -61, -57, -53, -51, -47, -42, -40, -35, -32, -27, -23, -20, -16, -12, -8,
+
755 -4, 1, 6, 12, 17, 21, 26, 29, 32, 35, 37, 40, 42, 43, 46, 49, 49, 52, 54, 54,
+
756 55, 56, 55, 56, 56, 54, 54, 54, 51, 50, 49, 45, 43, 42, 38, 35, 34, 30, 26, 25,
+
757 19, 14, 10, 4, -2, -7, -14, -20, -24, -31, -37, -41, -47, -52, -58, -60, -64,
+
758 -68, -69, -71, -71, -73, -72, -72, -71, -69, -68, -64, -61, -57, -53, -48, -43,
+
759 -38, -33, -29, -23, -18, -15, -9, -4, 2, 6, 13, 19, 24, 29, 33, 38, 41, 44, 47,
+
760 49, 51, 53, 55, 56, 58, 59, 60, 60, 60, 60, 59, 59, 58, 56, 55, 53, 51, 49, 46,
+
761 43, 40, 37, 33, 30, 26, 22, 18, 14, 9, 4, -2, -8, -12, -19, -25, -30, -36, -43,
+
762 -46, -53, -57, -59, -66, -70, -70, -74, -78, -76, -77, -77, -75, -74, -73, -68,
+
763 -66, -65, -59, -54, -51, -46, -40, -36, -30, -25, -20, -13, -8, -2, 4, 10, 17,
+
764 23, 28, 34, 40, 43, 46, 51, 53, 54, 57, 59, 59, 62, 63, 63, 66, 65, 64, 65, 65,
+
765 62, 61, 60, 57, 54, 52, 49, 46, 43, 39, 35, 32, 28, 23, 19, 16, 10, 4, 0, -7,
+
766 -14, -19, -26, -33, -37, -44, -50, -54, -58, -63, -68, -70, -74, -77, -79, -80,
+
767 -81, -81, -80, -80, -78, -75, -72, -69, -64, -59, -56, -50, -44, -39, -34, -29,
+
768 -21, -15, -9, -2, 4, 11, 19, 25, 30, 37, 43, 47, 52, 56, 59, 62, 64, 65, 67, 68,
+
769 69, 70, 71, 71, 70, 71, 70, 68, 66, 64, 61, 58, 55, 51, 48, 45, 40, 36, 33, 28,
+
770 23, 18, 13, 9, 2, -3, -9, -16, -21, -29, -37, -41, -45, -55, -60, -62, -67, -73,
+
771 -76, -77, -80, -81, -84, -85, -83, -82, -84, -82, -76, -75, -73, -67, -62, -58,
+
772 -52, -47, -42, -34, -29, -23, -15, -8, 0, 6, 14, 23, 29, 35, 44, 49, 52, 59, 62,
+
773 65, 69, 71, 72, 75, 78, 77, 78, 81, 79, 78, 78, 77, 74, 72, 69, 64, 62, 57, 52,
+
774 49, 44, 38, 34, 30, 24, 19, 14, 9, 3, -4, -10, -17, -24, -30, -37, -46, -50,
+
775 -55, -66, -66, -72, -78, -80, -84, -88, -89, -89, -91, -91, -90, -88, -88, -86,
+
776 -78, -78, -73, -66, -64, -55, -50, -44, -38, -29, -23, -17, -9, -2, 7, 15, 22,
+
777 31, 37, 44, 52, 57, 61, 68, 70, 73, 77, 77, 79, 82, 82, 82, 82, 83, 82, 80, 79,
+
778 77, 73, 70, 67, 61, 58, 53, 47, 44, 38, 32, 28, 23, 17, 11, 5, -1, -8, -15, -21,
+
779 -27, -35, -39, -48, -54, -56, -65, -69, -72, -77, -81, -85, -88, -89, -90, -91,
+
780 -91, -93, -87, -87, -87, -79, -76, -73, -66, -62, -55, -48, -42, -36, -29, -21,
+
781 -15, -9, 1, 9, 16, 25, 32, 41, 47, 54, 61, 65, 70, 72, 74, 78, 79, 80, 82, 82,
+
782 82, 83, 82, 82, 80, 78, 76, 72, 69, 65, 59, 56, 51, 45, 41, 36, 32, 26, 22, 18,
+
783 12, 6, 0, -5, -11, -19, -24, -31, -38, -42, -49, -56, -58, -62, -70, -72, -73,
+
784 -80, -81, -83, -87, -86, -86, -88, -87, -84, -82, -80, -78, -69, -67, -65, -54,
+
785 -51, -46, -35, -33, -27, -18, -13, -6, 1, 10, 18, 24, 34, 41, 47, 56, 61, 65,
+
786 69, 72, 74, 75, 78, 78, 77, 80, 78, 77, 79, 77, 76, 74, 71, 68, 65, 61, 57, 52,
+
787 48, 42, 37, 34, 29, 24, 21, 17, 13, 7, 2, -2, -9, -15, -21, -28, -34, -39, -47,
+
788 -52, -54, -61, -66, -68, -72, -75, -79, -80, -82, -85, -83, -86, -87, -83, -82,
+
789 -82, -76, -72, -68, -63, -57, -51, -46, -38, -32, -29, -20, -15, -10, -1, 4, 12,
+
790 19, 27, 35, 41, 51, 57, 60, 67, 70, 72, 75, 76, 76, 76, 76, 76, 74, 75, 75, 72,
+
791 72, 70, 66, 65, 60, 56, 53, 47, 42, 37, 33, 30, 25, 21, 18, 14, 10, 5, 1, -3,
+
792 -9, -15, -21, -26, -32, -38, -43, -50, -53, -56, -64, -65, -69, -72, -74, -79,
+
793 -81, -79, -83, -85, -81, -83, -79, -79, -76, -70, -68, -62, -58, -51, -44, -40,
+
794 -33, -28, -20, -17, -11, -2, 3, 8, 17, 24, 30, 40, 45, 52, 59, 62, 66, 68, 72,
+
795 73, 71, 73, 73, 72, 71, 71, 70, 69, 67, 65, 62, 61, 58, 53, 51, 46, 41, 38, 33,
+
796 30, 27, 23, 21, 18, 15, 12, 8, 4, -2, -7, -12, -18, -24, -29, -33, -39, -44,
+
797 -48, -52, -56, -60, -65, -66, -72, -75, -77, -80, -80, -83, -83, -80, -79, -78,
+
798 -72, -69, -63, -58, -56, -47, -43, -38, -32, -27, -20, -16, -11, -4, 3, 10, 16,
+
799 24, 33, 39, 46, 53, 58, 65, 66, 68, 71, 70, 71, 70, 69, 70, 68, 67, 67, 66, 65,
+
800 64, 61, 58, 55, 51, 46, 42, 38, 32, 30, 26, 24, 21, 20, 19, 17, 16, 13, 10, 7,
+
801 1, -5, -9, -15, -21, -26, -30, -33, -39, -42, -42, -51, -53, -53, -62, -65, -67,
+
802 -72, -76, -78, -78, -80, -79, -77, -74, -71, -66, -61, -58, -51, -45, -43, -39,
+
803 -30, -27, -24, -17, -14, -8, 0, 3, 11, 20, 27, 35, 41, 49, 55, 58, 62, 64, 64,
+
804 64, 65, 64, 62, 63, 62, 61, 63, 61, 60, 61, 59, 55, 52, 48, 45, 39, 33, 30, 25,
+
805 22, 20, 18, 18, 19, 18, 16, 15, 13, 9, 5, -1, -8, -11, -18, -24, -27, -31, -35,
+
806 -38, -41, -43, -45, -51, -54, -56, -64, -68, -72, -77, -77, -82, -81, -79, -77,
+
807 -73, -70, -64, -58, -53, -49, -44, -38, -34, -30, -26, -21, -18, -12, -9, -2, 5,
+
808 11, 20, 25, 34, 42, 47, 53, 57, 59, 61, 61, 59, 59, 59, 58, 56, 56, 56, 56, 57,
+
809 56, 56, 55, 52, 49, 44, 40, 35, 29, 24, 20, 18, 17, 17, 17, 18, 19, 19, 18, 16,
+
810 14, 9, 3, -4, -8, -15, -21, -24, -28, -31, -33, -36, -38, -40, -41, -47, -53,
+
811 -55, -63, -70, -71, -77, -81, -79, -79, -79, -75, -67, -64, -59, -50, -48, -43,
+
812 -37, -35, -32, -28, -24, -22, -18, -13, -7, 0, 8, 15, 24, 33, 40, 47, 52, 57,
+
813 58, 58, 58, 56, 57, 56, 54, 54, 55, 55, 56, 57, 57, 57, 56, 53, 48, 44, 38, 31,
+
814 26, 20, 16, 14, 13, 14, 16, 17, 19, 21, 20, 19, 16, 13, 7, 0, -7, -12, -17, -22,
+
815 -24, -27, -28, -28, -29, -33, -33, -36, -44, -49, -57, -62, -68, -74, -77, -80,
+
816 -78, -76, -74, -69, -61, -56, -52, -47, -42, -38, -36, -33, -32, -29, -25, -22,
+
817 -19, -12, -4, 2, 10, 19, 27, 34, 41, 46, 49, 52, 53, 52, 50, 51, 50, 49, 50, 50,
+
818 51, 53, 55, 55, 55, 55, 52, 49, 44, 39, 33, 28, 24, 19, 17, 19, 20, 21, 24, 26,
+
819 28, 28, 28, 25, 20, 16, 9, 0, -5, -10, -15, -17, -19, -21, -22, -22, -26, -31,
+
820 -30, -38, -46, -53, -62, -66, -75, -81, -80, -81, -81, -76, -74, -67, -59, -58,
+
821 -52, -47, -44, -42, -41, -37, -34, -31, -29, -23, -15, -10, -2, 6, 15, 24, 29,
+
822 35, 42, 46, 48, 49, 50, 51, 50, 50, 49, 52, 54, 53, 55, 56, 57, 56, 54, 52, 49,
+
823 44, 39, 33, 28, 24, 20, 19, 18, 19, 21, 22, 25, 26, 26, 27, 24, 21, 16, 11, 6,
+
824 -1, -6, -9, -12, -15, -16, -16, -18, -20, -25, -28, -31, -40, -47, -54, -62,
+
825 -68, -74, -79, -78, -79, -78, -74, -70, -65, -61, -56, -53, -49, -46, -45, -41,
+
826 -38, -35, -31, -27, -20, -13, -8, 0, 9, 16, 22, 28, 34, 38, 42, 44, 45, 48, 48,
+
827 48, 49, 50, 52, 52, 53, 54, 54, 54, 53, 50, 48, 44, 41, 36, 32, 29, 23, 21, 20,
+
828 19, 19, 20, 22, 23, 24, 25, 24, 23, 21, 18, 14, 10, 6, 0, -4, -5, -9, -10, -11,
+
829 -13, -15, -19, -24, -27, -33, -41, -48, -56, -60, -67, -73, -73, -74, -75, -72,
+
830 -70, -67, -61, -59, -56, -52, -48, -46, -44, -40, -37, -33, -28, -23, -15, -10,
+
831 -3, 3, 9, 17, 20, 25, 32, 34, 37, 40, 42, 45, 46, 48, 50, 51, 52, 52, 53, 53,
+
832 52, 51, 49, 47, 44, 40, 38, 34, 31, 29, 25, 24, 22, 21, 21, 21, 23, 23, 23, 25,
+
833 23, 22, 21, 18, 15, 11, 8, 3, 0, -2, -6, -8, -10, -14, -17, -20, -25, -31, -36,
+
834 -42, -49, -56, -62, -65, -70, -74, -73, -74, -72, -70, -68, -63, -60, -56, -53,
+
835 -50, -45, -43, -39, -35, -30, -24, -20, -13, -7, -2, 5, 9, 15, 20, 25, 30, 32,
+
836 37, 40, 41, 46, 46, 48, 50, 49, 51, 50, 50, 50, 48, 48, 45, 42, 40, 37, 36, 33,
+
837 30, 28, 25, 24, 22, 20, 21, 20, 22, 22, 23, 23, 23, 23, 23, 21, 19, 16, 13, 8,
+
838 5, 2, -2, -4, -7, -10, -13, -16, -21, -28, -30, -36, -45, -48, -56, -62, -64,
+
839 -71, -71, -72, -73, -70, -70, -66, -61, -59, -55, -51, -47, -44, -39, -35, -32,
+
840 -25, -21, -17, -8, -5, 2, 8, 12, 18, 22, 28, 31, 34, 39, 40, 44, 46, 46, 49, 48,
+
841 49, 50, 47, 49, 47, 45, 44, 42, 40, 37, 35, 33, 30, 29, 26, 23, 21, 19, 19, 18,
+
842 18, 19, 19, 21, 22, 23, 24, 23, 23, 21, 19, 17, 13, 10, 6, 4, 0, -3, -4, -8,
+
843 -12, -15, -21, -25, -30, -38, -44, -50, -56, -60, -65, -68, -69, -70, -70, -67,
+
844 -65, -62, -59, -57, -53, -49, -46, -42, -38, -33, -28, -22, -17, -12, -6, -1, 4,
+
845 8, 13, 18, 21, 26, 29, 32, 36, 39, 42, 45, 46, 48, 48, 49, 48, 46, 46, 45, 43,
+
846 41, 39, 37, 35, 34, 32, 29, 28, 26, 23, 21, 20, 19, 18, 18, 19, 20, 21, 22, 23,
+
847 24, 25, 25, 24, 23, 20, 17, 14, 10, 7, 3, 0, -3, -8, -10, -14, -21, -24, -29,
+
848 -36, -42, -47, -55, -60, -63, -69, -71, -72, -72, -72, -69, -66, -63, -60, -54,
+
849 -52, -48, -43, -39, -35, -30, -24, -20, -15, -9, -4, 1, 6, 11, 15, 19, 25, 28,
+
850 32, 36, 38, 41, 44, 46, 47, 47, 47, 47, 45, 45, 44, 43, 40, 40, 37, 34, 33, 31,
+
851 28, 27, 24, 22, 20, 18, 17, 16, 17, 17, 19, 21, 22, 24, 25, 26, 27, 26, 25, 24,
+
852 21, 18, 14, 11, 9, 5, 2, -1, -5, -8, -14, -18, -24, -30, -35, -45, -50, -55,
+
853 -64, -68, -72, -75, -75, -76, -74, -72, -69, -65, -63, -57, -54, -49, -45, -42,
+
854 -36, -33, -27, -21, -17, -8, -3, 2, 10, 13, 19, 24, 28, 33, 35, 39, 42, 43, 48,
+
855 48, 50, 51, 52, 52, 50, 49, 48, 45, 44, 40, 38, 35, 31, 29, 25, 24, 21, 18, 18,
+
856 15, 14, 13, 13, 14, 14, 17, 19, 20, 23, 24, 25, 26, 26, 27, 25, 25, 22, 18, 17,
+
857 13, 11, 7, 4, 1, -5, -9, -14, -21, -28, -34, -43, -50, -55, -61, -68, -71, -73,
+
858 -76, -76, -74, -74, -71, -68, -65, -63, -59, -54, -52, -46, -40, -34, -28, -20,
+
859 -13, -7, 0, 7, 11, 17, 23, 26, 29, 34, 36, 38, 41, 45, 48, 50, 53, 53, 54, 53,
+
860 51, 48, 46, 43, 39, 35, 32, 29, 25, 23, 21, 20, 19, 18, 16, 14, 14, 11, 10, 11,
+
861 11, 12, 14, 17, 19, 21, 25, 27, 29, 31, 32, 31, 29, 27, 23, 19, 17, 13, 11, 7,
+
862 3, -1, -6, -11, -19, -25, -30, -41, -48, -56, -64, -70, -77, -78, -80, -82, -79,
+
863 -79, -77, -73, -69, -66, -62, -55, -51, -47, -40, -36, -28, -21, -14, -5, 1, 9,
+
864 14, 20, 27, 29, 34, 37, 39, 41, 41, 43, 44, 46, 48, 48, 49, 48, 47, 45, 42, 40,
+
865 36, 31, 28, 23, 20, 15, 12, 10, 8, 8, 6, 6, 5, 4, 3, 3, 3, 6, 8, 11, 14, 17, 20,
+
866 24, 28, 31, 34, 37, 38, 38, 36, 34, 32, 28, 26, 23, 19, 15, 9, 5, -3, -10, -16,
+
867 -25, -33, -41, -51, -59, -66, -74, -79, -81, -83, -84, -82, -81, -79, -75, -73,
+
868 -68, -64, -58, -53, -50, -42, -35, -30, -22, -13, -4, 4, 11, 17, 22, 27, 29, 32,
+
869 35, 35, 36, 37, 37, 40, 41, 44, 47, 48, 49, 47, 45, 41, 38, 33, 27, 23, 17, 12,
+
870 9, 5, 4, 3, 4, 4, 4, 5, 3, 2, 1, 0, 2, 4, 7, 11, 15, 20, 25, 31, 38, 44, 48, 51,
+
871 53, 52, 49, 47, 43, 39, 36, 32, 29, 24, 20, 14, 6, 2, -5, -16, -22, -34, -46,
+
872 -55, -66, -74, -80, -85, -88, -89, -88, -89, -86, -82, -79, -74, -70, -65, -61,
+
873 -58, -52, -47, -41, -32, -25, -15, -6, 2, 10, 15, 22, 28, 31, 36, 37, 37, 36,
+
874 36, 37, 38, 42, 45, 47, 50, 49, 48, 46, 43, 40, 35, 30, 24, 17, 12, 6, 2, 2, 1,
+
875 2, 4, 4, 5, 4, 3, 2, 2, 5, 8, 10, 14, 19, 23, 28, 35, 42, 48, 54, 57, 59, 59,
+
876 57, 54, 51, 50, 47, 42, 38, 33, 28, 21, 15, 7, -1, -9, -20, -32, -43, -54, -65,
+
877 -75, -82, -87, -91, -95, -97, -97, -97, -96, -93, -89, -85, -81, -76, -72, -66,
+
878 -60, -53, -44, -35, -25, -15, -6, 3, 11, 19, 24, 30, 36, 38, 41, 42, 41, 42, 41,
+
879 41, 44, 47, 50, 51, 52, 51, 49, 46, 41, 38, 32, 25, 18, 11, 6, 1, -3, -4, -3,
+
880 -3, -3, -3, -5, -7, -8, -8, -8, -6, -2, 4, 9, 16, 25, 31, 38, 46, 53, 59, 62,
+
881 61, 62, 63, 61, 59, 58, 59, 58, 54, 52, 48, 42, 35, 26, 15, 5, -8, -24, -38,
+
882 -49, -62, -73, -80, -87, -91, -96, -99, -100, -102, -102, -103, -102, -98, -99,
+
883 -96, -91, -86, -78, -71, -59, -49, -37, -24, -16, -4, 6, 14, 22, 28, 35, 39, 41,
+
884 44, 46, 48, 49, 51, 52, 52, 57, 56, 56, 58, 54, 52, 48, 43, 37, 30, 24, 16, 11,
+
885 6, 2, -1, -4, -4, -4, -5, -4, -6, -6, -6, -8, -9, -9, -9, -8, -5, 1, 7, 14, 22,
+
886 29, 36, 42, 47, 50, 52, 54, 54, 54, 54, 52, 52, 52, 51, 51, 48, 43, 37, 30, 19,
+
887 10, 1, -14, -23, -33, -47, -52, -60, -69, -72, -77, -81, -84, -88, -92, -94,
+
888 -95, -97, -97, -93, -89, -83, -78, -70, -60, -53, -43, -33, -24, -14, -7, 0, 7,
+
889 13, 20, 24, 30, 35, 38, 42, 45, 47, 48, 49, 50, 48, 48, 48, 46, 45, 43, 40, 38,
+
890 34, 30, 25, 21, 18, 12, 8, 5, 1, -2, -4, -6, -7, -8, -9, -11, -10, -10, -12,
+
891 -12, -11, -9, -7, -1, 4, 9, 16, 20, 24, 30, 33, 37, 39, 41, 43, 45, 46, 47, 49,
+
892 52, 53, 54, 53, 51, 46, 38, 31, 22, 14, 6, -4, -12, -20, -30, -37, -42, -50,
+
893 -56, -57, -65, -72, -75, -83, -89, -90, -92, -92, -88, -87, -84, -75, -70, -64,
+
894 -55, -49, -40, -34, -28, -21, -18, -12, -8, -2, 4, 11, 17, 20, 26, 30, 32, 35,
+
895 35, 35, 32, 28, 27, 24, 25, 25, 25, 27, 27, 25, 24, 22, 20, 16, 13, 9, 4, 1, -5,
+
896 -7, -8, -9, -6, -5, -1, 3, 5, 8, 10, 12, 14, 16, 17, 21, 24, 27, 31, 37, 41, 46,
+
897 52, 57, 61, 64, 66, 67, 68, 68, 66, 64, 62, 58, 54, 48, 40, 31, 24, 14, 4, -4,
+
898 -14, -26, -36, -45, -54, -62, -68, -75, -80, -83, -90, -95, -96, -100, -100,
+
899 -100, -99, -94, -91, -86, -80, -72, -63, -58, -49, -40, -33, -26, -20, -14, -8,
+
900 -2, 4, 8, 16, 19, 20, 23, 24, 26, 25, 24, 24, 29, 35, 36, 41, 44, 43, 43, 39,
+
901 38, 35, 30, 26, 21, 17, 12, 7, 5, 5, 7, 6, 6, 6, 1, -1, -5, -10, -14, -18, -22,
+
902 -24, -23, -20, -16, -5, 6, 17, 29, 39, 45, 48, 51, 53, 54, 57, 57, 60, 66, 69,
+
903 72, 78, 87, 93, 96, 98, 94, 86, 73, 54, 37, 22, 6, -9, -20, -27, -37, -44, -51,
+
904 -57, -61, -65, -72, -80, -89, -100, -110, -121, -125, -127, -128, -121, -115,
+
905 -106, -94, -87, -75, -64, -56, -46, -40, -36, -33, -31, -28, -22, -15, -8, 4,
+
906 15, 23, 33, 37, 41, 45, 41, 42, 48, 47, 48, 49, 47, 46, 46, 44, 46, 49, 48, 46,
+
907 43, 38, 32, 24, 17, 14, 9, 4, 0, -7, -11, -14, -20, -22, -23, -24, -27, -28,
+
908 -30, -33, -33, -32, -28, -21, -11, -2, 6, 16, 24, 31, 40, 47, 53, 61, 67, 70,
+
909 73, 77, 81, 85, 91, 96, 100, 101, 99, 92, 84, 73, 59, 46, 35, 21, 8, -6, -19,
+
910 -31, -42, -51, -58, -65, -73, -81, -90, -100, -107, -116, -122, -122, -124,
+
911 -123, -119, -116, -108, -101, -98, -84, -74, -69, -58, -50, -45, -38, -34, -31,
+
912 -22, -14, -9, 0, 7, 12, 18, 20, 24, 28, 28, 34, 39, 43, 48, 49, 49, 49, 49, 47,
+
913 45, 45, 41, 38, 34, 28, 25, 19, 17, 16, 13, 12, 7, 4, 1, -6, -9, -13, -13, -13,
+
914 -13, -9, -6, -2, 2, 7, 14, 20, 27, 30, 35, 40, 41, 45, 49, 52, 59, 64, 70, 75,
+
915 79, 82, 83, 84, 82, 79, 75, 67, 58, 47, 36, 24, 12, 2, -7, -14, -23, -32, -40,
+
916 -49, -57, -65, -74, -81, -88, -96, -103, -107, -112, -114, -112, -110, -103,
+
917 -97, -91, -83, -77, -69, -61, -53, -43, -37, -30, -23, -18, -12, -7, 0, 8, 15,
+
918 22, 23, 28, 31, 29, 29, 27, 25, 20, 13, 10, 10, 13, 15, 17, 23, 26, 26, 25, 23,
+
919 23, 19, 14, 11, 8, 4, 0, -2, 0, 3, 7, 9, 14, 16, 16, 15, 9, 5, 2, -4, -7, -8,
+
920 -8, -8, -5, 1, 9, 18, 27, 35, 41, 44, 46, 46, 44, 44, 43, 45, 49, 51, 55, 60,
+
921 65, 70, 73, 76, 76, 72, 64, 54, 42, 28, 14, 3, -5, -12, -20, -25, -30, -35, -41,
+
922 -47, -53, -60, -68, -75, -84, -92, -100, -105, -106, -104, -102, -96, -86, -80,
+
923 -73, -67, -61, -53, -50, -44, -37, -35, -31, -29, -27, -20, -15, -10, -1, 7, 11,
+
924 15, 16, 15, 16, 12, 6, 3, -2, -3, 0, 3, 8, 14, 19, 24, 28, 29, 31, 30, 26, 23,
+
925 19, 14, 13, 11, 12, 16, 20, 25, 30, 34, 37, 38, 35, 31, 27, 22, 17, 12, 9, 8, 7,
+
926 8, 12, 17, 23, 28, 30, 33, 34, 33, 31, 28, 27, 27, 27, 28, 32, 36, 41, 46, 50,
+
927 54, 55, 53, 48, 41, 33, 23, 13, 5, -1, -5, -8, -12, -15, -16, -20, -24, -28,
+
928 -35, -42, -50, -59, -68, -74, -80, -85, -83, -82, -79, -72, -68, -64, -58, -56,
+
929 -53, -51, -47, -47, -45, -41, -41, -37, -33, -29, -21, -17, -11, -7, -2, 2, -1,
+
930 0, -2, -5, -9, -17, -19, -19, -17, -7, 0, 10, 20, 24, 27, 29, 30, 27, 25, 22,
+
931 17, 16, 11, 8, 11, 15, 22, 29, 35, 41, 43, 41, 38, 31, 23, 16, 11, 7, 6, 7, 8,
+
932 14, 20, 28, 39, 46, 51, 52, 51, 49, 45, 40, 37, 37, 41, 43, 47, 54, 60, 65, 68,
+
933 71, 71, 67, 58, 45, 33, 19, 5, -7, -15, -18, -21, -23, -26, -29, -32, -38, -44,
+
934 -52, -60, -69, -79, -86, -94, -99, -101, -100, -93, -89, -82, -73, -70, -64,
+
935 -58, -56, -50, -47, -45, -39, -36, -35, -31, -25, -23, -16, -8, -4, 3, 6, 8, 9,
+
936 6, 5, 1, -3, -6, -14, -17, -15, -14, -6, 3, 11, 19, 23, 25, 24, 24, 20, 16, 12,
+
937 8, 7, 3, 3, 9, 13, 21, 30, 36, 44, 47, 46, 43, 38, 32, 26, 23, 21, 22, 24, 27,
+
938 34, 40, 48, 57, 61, 64, 64, 60, 56, 50, 44, 40, 40, 41, 42, 45, 49, 53, 55, 56,
+
939 54, 50, 43, 31, 18, 5, -9, -21, -30, -35, -37, -38, -39, -40, -42, -45, -49,
+
940 -55, -63, -69, -77, -85, -90, -96, -98, -96, -93, -88, -79, -70, -63, -55, -50,
+
941 -48, -42, -39, -37, -33, -31, -28, -23, -20, -13, -6, 1, 7, 14, 17, 19, 21, 16,
+
942 15, 13, 6, 2, -3, -10, -13, -14, -9, 0, 8, 18, 26, 28, 28, 25, 20, 19, 16, 9, 7,
+
943 8, 4, 4, 8, 14, 23, 32, 38, 43, 44, 41, 34, 25, 20, 14, 10, 11, 14, 17, 23, 30,
+
944 37, 47, 56, 60, 62, 60, 54, 47, 41, 36, 33, 36, 41, 46, 53, 59, 64, 67, 68, 66,
+
945 61, 52, 39, 23, 8, -6, -20, -29, -32, -33, -33, -33, -35, -40, -43, -48, -57,
+
946 -62, -70, -80, -86, -93, -97, -97, -95, -89, -81, -70, -64, -58, -50, -47, -42,
+
947 -39, -34, -29, -29, -25, -23, -19, -13, -8, 0, 9, 18, 19, 21, 24, 18, 16, 13, 7,
+
948 5, -2, -10, -18, -22, -21, -18, -8, 4, 13, 19, 20, 20, 16, 12, 10, 6, 4, 2, -1,
+
949 -2, 0, 5, 13, 24, 36, 44, 50, 51, 47, 41, 33, 26, 22, 19, 19, 19, 22, 27, 32,
+
950 41, 51, 60, 65, 65, 61, 53, 46, 38, 32, 31, 32, 36, 40, 46, 51, 56, 61, 63, 63,
+
951 60, 51, 39, 23, 9, -5, -17, -22, -26, -26, -25, -26, -28, -31, -34, -39, -47,
+
952 -55, -64, -75, -84, -90, -95, -95, -91, -86, -78, -71, -65, -58, -54, -50, -46,
+
953 -43, -40, -39, -37, -34, -31, -23, -16, -7, 4, 11, 15, 18, 18, 17, 14, 11, 7, 3,
+
954 -1, -5, -9, -13, -15, -18, -23, -22, -18, -17, -11, -4, -3, 0, 2, 0, 2, 6, 6, 8,
+
955 11, 14, 16, 20, 26, 35, 42, 48, 55, 56, 58, 58, 53, 49, 47, 42, 39, 40, 40, 40,
+
956 43, 44, 46, 50, 51, 51, 47, 42, 35, 28, 24, 20, 18, 20, 24, 27, 30, 35, 39, 41,
+
957 44, 42, 40, 36, 27, 17, 7, -2, -12, -18, -21, -24, -24, -26, -28, -31, -35, -39,
+
958 -44, -51, -57, -65, -74, -78, -84, -88, -85, -84, -81, -75, -69, -64, -58, -52,
+
959 -48, -40, -34, -31, -24, -21, -14, -11, -9, -1, 4, 7, 14, 18, 21, 25, 26, 25,
+
960 28, 27, 21, 20, 15, 12, 9, 3, -2, -7, -11, -16, -16, -11, -10, -8, -4, -4, -3,
+
961 -1, 3, 12, 19, 22, 24, 21, 19, 18, 17, 24, 34, 37, 40, 46, 47, 49, 51, 50, 56,
+
962 60, 57, 54, 49, 45, 40, 36, 37, 41, 41, 40, 36, 32, 28, 24, 20, 21, 23, 22, 19,
+
963 16, 14, 15, 17, 20, 23, 25, 21, 14, 5, -4, -13, -20, -24, -25, -27, -30, -31,
+
964 -34, -35, -34, -32, -31, -32, -39, -46, -54, -65, -71, -73, -73, -68, -64, -60,
+
965 -54, -50, -43, -32, -25, -19, -10, -8, -10, -9, -8, -9, -7, -4, 0, 6, 8, 11, 13,
+
966 13, 17, 15, 9, 8, 2, -12, -20, -30, -43, -46, -47, -46, -35, -26, -16, -4, 4,
+
967 12, 17, 18, 20, 19, 13, 13, 13, 11, 17, 28, 37, 51, 63, 70, 76, 78, 75, 69, 62,
+
968 54, 45, 36, 29, 25, 23, 24, 29, 34, 40, 43, 40, 37, 32, 23, 15, 10, 5, 3, 5, 7,
+
969 13, 21, 29, 35, 42, 45, 42, 35, 28, 15, 3, -6, -16, -22, -22, -22, -20, -13, -9,
+
970 -3, 1, 0, -5, -16, -30, -43, -56, -64, -65, -68, -66, -59, -53, -40, -35, -33,
+
971 -22, -22, -30, -36, -30, -25, -39, -40, -29, -26, -26, -21, -7, 1, 2, -5, -3, 3,
+
972 -5, -8, -15, -14, -12, -32, -35, -30, -36, -37, -42, -43, -31, -25, -20, -2, 15,
+
973 21, 28, 32, 41, 51, 44, 45, 52, 50, 51, 52, 56, 63, 66, 69, 72, 74, 69, 58, 49,
+
974 39, 27, 13, 1, -2, -4, -5, -3, 3, 11, 18, 22, 26, 29, 28, 23, 22, 23, 25, 29,
+
975 32, 41, 55, 67, 78, 87, 95, 98, 95, 90, 80, 66, 50, 35, 21, 9, -1, -11, -17,
+
976 -20, -25, -29, -33, -38, -43, -49, -57, -63, -68, -71, -71, -70, -68, -63, -58,
+
977 -52, -42, -35, -33, -28, -27, -23, -16, -9, -1, 5, 1, 8, 15, 4, 0, 2, -2, -8,
+
978 -13, -12, -17, -28, -31, -33, -34, -35, -41, -46, -45, -51, -65, -66, -72, -76,
+
979 -65, -58, -39, -13, 5, 27, 47, 60, 73, 78, 79, 84, 82, 70, 65, 60, 54, 61, 67,
+
980 70, 76, 72, 61, 55, 43, 25, 6, -14, -35, -52, -67, -75, -73, -67, -55, -38, -24,
+
981 -7, 3, 9, 18, 22, 23, 26, 29, 35, 43, 53, 65, 82, 98, 112, 120, 121, 115, 102,
+
982 84, 67, 47, 25, 3, -17, -32, -43, -51, -55, -57, -59, -63, -67, -73, -81, -88,
+
983 -93, -94, -94, -90, -82, -73, -60, -46, -33, -24, -16, -10, -12, -12, -13, -13,
+
984 -14, -16, -13, -16, -20, -16, -15, -12, -8, -15, -26, -34, -48, -61, -65, -68,
+
985 -69, -71, -73, -67, -64, -60, -49, -44, -43, -41, -50, -61, -59, -54, -41, -16,
+
986 11, 36, 54, 69, 83, 91, 99, 102, 95, 82, 66, 44, 27, 23, 24, 27, 32, 32, 27, 18,
+
987 9, -1, -14, -28, -47, -68, -85, -95, -96, -84, -62, -38, -12, 13, 31, 42, 54,
+
988 62, 66, 67, 65, 61, 58, 59, 65, 77, 93, 106, 113, 114, 107, 93, 74, 54, 30, 3,
+
989 -23, -49, -68, -80, -84, -81, -76, -70, -67, -68, -69, -73, -76, -77, -79, -78,
+
990 -73, -70, -64, -50, -34, -15, 6, 19, 22, 19, 8, 1, -4, -10, -12, -17, -26, -35,
+
991 -37, -37, -36, -30, -30, -33, -43, -56, -64, -70, -71, -72, -73, -71, -68, -67,
+
992 -60, -44, -27, -17, -16, -16, -29, -39, -37, -38, -22, 7, 23, 38, 56, 67, 75,
+
993 88, 95, 93, 82, 57, 33, 11, 1, 3, 0, 5, 10, 4, 3, 4, -1, -5, -13, -26, -47, -66,
+
994 -78, -86, -82, -67, -43, -16, 9, 37, 60, 77, 91, 97, 97, 94, 84, 71, 66, 65, 66,
+
995 78, 90, 99, 103, 100, 95, 85, 71, 52, 26, -1, -28, -52, -67, -71, -71, -68, -61,
+
996 -55, -50, -45, -43, -43, -45, -48, -52, -56, -54, -47, -35, -21, -8, 3, 9, 11,
+
997 8, 3, -3, -15, -24, -36, -48, -52, -56, -59, -55, -50, -49, -46, -46, -53, -55,
+
998 -56, -59, -62, -61, -58, -57, -51, -40, -32, -24, -15, -12, -10, -8, -12, -18,
+
999 -21, -27, -36, -37, -27, -12, 11, 35, 47, 56, 62, 61, 60, 59, 52, 40, 25, 11, 6,
+
1000 6, 12, 23, 30, 35, 36, 28, 22, 17, 5, -10, -25, -41, -52, -53, -39, -16, 1, 19,
+
1001 34, 42, 49, 54, 54, 54, 49, 39, 36, 41, 45, 55, 72, 89, 101, 106, 106, 102, 93,
+
1002 80, 63, 44, 26, 7, -9, -14, -14, -14, -11, -8, -9, -12, -18, -27, -35, -41, -47,
+
1003 -52, -52, -49, -41, -29, -15, -1, 5, 7, 6, 1, -8, -16, -25, -38, -44, -44, -42,
+
1004 -36, -26, -19, -14, -11, -14, -21, -29, -40, -53, -63, -68, -71, -70, -59, -44,
+
1005 -32, -21, -8, -1, 1, 1, -8, -19, -26, -37, -44, -44, -43, -43, -40, -30, -16, 3,
+
1006 23, 42, 54, 53, 52, 46, 39, 40, 35, 27, 22, 18, 17, 26, 41, 50, 57, 56, 47, 38,
+
1007 26, 15, 4, -10, -21, -31, -37, -31, -21, -6, 11, 25, 34, 41, 47, 49, 50, 49, 46,
+
1008 46, 47, 52, 59, 68, 80, 89, 94, 97, 93, 85, 74, 62, 47, 34, 21, 9, -1, -7, -10,
+
1009 -9, -9, -10, -15, -20, -27, -34, -38, -40, -42, -41, -38, -31, -22, -11, 1, 9,
+
1010 14, 16, 10, 4, -4, -16, -26, -36, -46, -48, -46, -43, -35, -28, -26, -27, -32,
+
1011 -37, -40, -48, -56, -65, -72, -76, -74, -63, -48, -33, -23, -13, -9, -7, -7,
+
1012 -12, -17, -26, -37, -46, -52, -50, -47, -45, -43, -43, -34, -19, -3, 17, 29, 30,
+
1013 28, 28, 29, 33, 37, 36, 32, 30, 29, 35, 43, 51, 55, 49, 41, 30, 18, 10, 1, -10,
+
1014 -23, -36, -44, -46, -40, -30, -11, 4, 14, 27, 36, 41, 47, 49, 51, 53, 50, 48,
+
1015 54, 61, 69, 79, 86, 91, 89, 81, 76, 68, 56, 43, 25, 7, -9, -22, -29, -31, -33,
+
1016 -37, -40, -43, -45, -46, -47, -47, -49, -48, -45, -40, -31, -21, -11, -3, 0, 1,
+
1017 0, -5, -13, -21, -33, -42, -48, -52, -47, -41, -36, -33, -35, -35, -38, -47,
+
1018 -53, -62, -72, -78, -81, -79, -67, -55, -45, -27, -9, 1, 9, 16, 16, 9, 2, -6,
+
1019 -16, -17, -16, -22, -16, -7, -11, -12, -13, -7, 2, 6, 11, 8, 1, -2, 1, 4, 12,
+
1020 21, 14, 13, 18, 17, 25, 32, 34, 34, 30, 23, 15, 17, 19, 16, 12, 3, -2, -5, -1,
+
1021 9, 11, 16, 19, 17, 23, 33, 38, 39, 42, 43, 43, 47, 51, 54, 59, 62, 64, 64, 67,
+
1022 68, 65, 65, 63, 56, 49, 43, 34, 27, 22, 13, 5, 0, -6, -11, -15, -18, -20, -22,
+
1023 -22, -25, -26, -25, -26, -24, -21, -21, -24, -25, -25, -27, -27, -27, -31, -33,
+
1024 -34, -36, -40, -42, -44, -47, -46, -44, -43, -41, -36, -34, -31, -27, -28, -33,
+
1025 -35, -34, -35, -36, -35, -37, -33, -30, -27, -21, -16, -14, -17, -18, -18, -22,
+
1026 -30, -36, -41, -49, -55, -61, -58, -36, -14, 7, 24, 33, 40, 43, 47, 52, 50, 42,
+
1027 30, 22, 21, 25, 34, 42, 52, 55, 52, 47, 39, 33, 20, 3, -15, -37, -51, -55, -52,
+
1028 -42, -29, -14, -1, 14, 29, 38, 44, 44, 39, 36, 35, 35, 40, 48, 60, 72, 83, 91,
+
1029 97, 97, 94, 87, 74, 59, 41, 23, 9, 0, -7, -11, -13, -15, -16, -17, -20, -23,
+
1030 -29, -37, -46, -52, -53, -51, -45, -35, -24, -16, -9, -2, 2, 3, -1, -9, -17,
+
1031 -25, -35, -41, -41, -41, -39, -35, -29, -24, -24, -24, -30, -37, -44, -57, -65,
+
1032 -64, -65, -62, -52, -41, -29, -16, -7, 0, 6, 0, -6, -11, -21, -25, -30, -32,
+
1033 -28, -26, -22, -17, -15, -13, -18, -21, -13, -7, 0, 4, 7, 12, 20, 31, 41, 49,
+
1034 51, 48, 46, 44, 46, 46, 42, 41, 37, 33, 29, 24, 23, 19, 11, 1, -12, -19, -24,
+
1035 -27, -25, -19, -13, -7, 3, 14, 24, 31, 35, 40, 45, 47, 50, 56, 62, 68, 76, 83,
+
1036 88, 90, 89, 88, 84, 75, 63, 47, 31, 17, 4, -5, -12, -19, -25, -28, -30, -33,
+
1037 -34, -36, -40, -44, -47, -49, -47, -40, -33, -25, -17, -9, -4, 3, 7, 7, 4, -4,
+
1038 -10, -18, -25, -29, -32, -36, -40, -40, -36, -34, -32, -30, -33, -40, -48, -52,
+
1039 -54, -53, -54, -54, -48, -45, -39, -27, -15, -6, -4, -3, -2, -7, -9, -11, -12,
+
1040 -16, -19, -22, -27, -24, -24, -30, -24, -18, -10, 5, 12, 14, 21, 24, 26, 31, 35,
+
1041 34, 31, 27, 28, 33, 36, 41, 46, 43, 42, 37, 29, 27, 21, 8, -2, -14, -24, -26,
+
1042 -25, -22, -13, -4, 3, 11, 20, 26, 29, 31, 33, 35, 36, 39, 45, 53, 63, 71, 77,
+
1043 82, 85, 81, 78, 72, 61, 50, 36, 23, 12, 3, -2, -7, -9, -13, -16, -19, -22, -25,
+
1044 -29, -33, -38, -42, -41, -38, -31, -21, -14, -6, 0, 3, 7, 7, 4, -1, -9, -17,
+
1045 -23, -30, -34, -37, -40, -40, -41, -43, -41, -41, -41, -40, -40, -43, -46, -45,
+
1046 -46, -42, -37, -35, -31, -25, -22, -18, -9, -2, -1, 2, 1, -3, -7, -9, -10, -13,
+
1047 -14, -19, -28, -31, -34, -41, -42, -31, -23, -13, 3, 8, 13, 25, 28, 34, 41, 39,
+
1048 32, 29, 28, 30, 36, 40, 44, 45, 43, 43, 39, 34, 31, 19, 4, -7, -20, -27, -26,
+
1049 -23, -15, -7, -1, 7, 16, 24, 29, 32, 32, 31, 30, 32, 39, 46, 54, 63, 69, 74, 77,
+
1050 76, 74, 70, 60, 48, 36, 22, 12, 5, 0, -2, -5, -8, -10, -12, -14, -16, -19, -24,
+
1051 -29, -32, -34, -31, -27, -22, -15, -10, -6, -2, -1, -1, -2, -9, -15, -19, -25,
+
1052 -28, -29, -31, -32, -34, -33, -31, -31, -33, -36, -37, -37, -41, -42, -42, -41,
+
1053 -42, -35, -30, -29, -22, -16, -14, -8, -7, -8, -11, -13, -15, -17, -18, -19,
+
1054 -19, -20, -20, -23, -26, -27, -32, -39, -42, -38, -32, -20, -1, 9, 17, 26, 32,
+
1055 40, 48, 49, 44, 37, 30, 26, 28, 32, 36, 36, 35, 35, 32, 28, 26, 17, 4, -9, -23,
+
1056 -33, -35, -31, -23, -15, -8, -1, 7, 16, 24, 29, 29, 27, 25, 26, 32, 40, 47, 57,
+
1057 65, 70, 74, 76, 75, 72, 65, 54, 42, 29, 19, 12, 8, 6, 2, -2, -4, -8, -11, -14,
+
1058 -18, -25, -31, -35, -37, -35, -29, -25, -18, -11, -6, -1, 3, 3, 0, -5, -12, -21,
+
1059 -26, -29, -28, -28, -26, -26, -30, -28, -26, -26, -27, -29, -36, -45, -50, -52,
+
1060 -50, -48, -48, -42, -36, -31, -25, -17, -8, -5, -8, -7, -8, -12, -15, -13, -12,
+
1061 -13, -16, -18, -18, -19, -22, -24, -29, -39, -44, -40, -32, -18, -4, 2, 11, 19,
+
1062 25, 33, 39, 39, 33, 28, 22, 20, 24, 27, 33, 37, 35, 35, 31, 30, 28, 18, 8, -5,
+
1063 -19, -25, -23, -16, -10, -3, 3, 8, 16, 22, 28, 31, 30, 27, 26, 30, 35, 43, 53,
+
1064 64, 70, 73, 77, 78, 76, 72, 62, 50, 37, 24, 15, 9, 6, 2, -3, -7, -10, -14, -17,
+
1065 -19, -24, -30, -35, -38, -38, -33, -27, -22, -17, -11, -6, -3, 0, 0, -4, -10,
+
1066 -17, -21, -24, -26, -27, -28, -28, -29, -30, -31, -30, -29, -33, -37, -40, -44,
+
1067 -46, -46, -43, -41, -38, -33, -29, -22, -16, -12, -7, -4, -3, -5, -7, -10, -11,
+
1068 -12, -15, -15, -18, -21, -24, -27, -29, -34, -44, -47, -41, -35, -24, -7, 0, 7,
+
1069 16, 22, 31, 38, 37, 34, 31, 26, 24, 28, 32, 36, 38, 35, 34, 31, 26, 24, 15, 2,
+
1070 -12, -26, -32, -32, -27, -19, -12, -5, 2, 11, 19, 27, 31, 30, 30, 29, 32, 41,
+
1071 49, 60, 70, 77, 81, 85, 86, 84, 79, 69, 55, 41, 27, 18, 10, 6, 3, -2, -5, -7,
+
1072 -9, -11, -13, -18, -25, -30, -34, -35, -31, -27, -20, -13, -8, -3, 2, 5, 5, 3,
+
1073 -2, -9, -16, -23, -27, -31, -33, -34, -36, -36, -36, -38, -41, -41, -43, -48,
+
1074 -50, -51, -50, -48, -44, -35, -30, -27, -21, -15, -10, -8, -4, -3, -4, -4, -6,
+
1075 -7, -7, -8, -8, -10, -13, -17, -24, -29, -34, -40, -51, -61, -56, -46, -35, -16,
+
1076 0, 7, 16, 26, 34, 42, 42, 34, 30, 25, 21, 26, 33, 41, 47, 48, 49, 49, 45, 40,
+
1077 32, 17, 1, -16, -29, -32, -27, -23, -16, -7, 0, 8, 16, 23, 27, 26, 23, 21, 22,
+
1078 27, 35, 45, 57, 68, 73, 79, 84, 82, 79, 72, 59, 45, 32, 21, 15, 12, 10, 8, 6, 4,
+
1079 1, -3, -6, -12, -22, -30, -37, -41, -40, -36, -30, -23, -17, -12, -7, -3, -2,
+
1080 -3, -7, -12, -20, -28, -29, -29, -29, -28, -28, -28, -27, -23, -20, -19, -22,
+
1081 -30, -35, -39, -40, -40, -39, -38, -37, -34, -30, -23, -18, -13, -10, -13, -15,
+
1082 -15, -16, -16, -16, -17, -19, -22, -22, -22, -21, -20, -25, -29, -33, -42, -50,
+
1083 -47, -34, -23, -6, 9, 16, 28, 38, 47, 57, 57, 51, 42, 34, 31, 30, 33, 38, 41,
+
1084 39, 37, 38, 36, 35, 28, 13, -1, -16, -27, -29, -26, -24, -22, -17, -11, -4, 6,
+
1085 13, 17, 17, 16, 17, 18, 26, 34, 43, 53, 61, 68, 73, 79, 80, 77, 71, 60, 48, 37,
+
1086 28, 22, 16, 13, 9, 5, 3, 1, -1, -4, -9, -17, -24, -30, -34, -34, -32, -29, -26,
+
1087 -22, -16, -11, -7, -5, -7, -11, -15, -19, -21, -22, -24, -25, -24, -23, -21,
+
1088 -19, -22, -25, -28, -32, -33, -38, -41, -40, -42, -41, -38, -32, -27, -22, -18,
+
1089 -15, -11, -14, -14, -11, -12, -12, -13, -12, -11, -14, -14, -12, -13, -16, -21,
+
1090 -25, -31, -37, -48, -56, -58, -52, -42, -27, -4, 12, 22, 37, 47, 54, 57, 56, 51,
+
1091 44, 38, 34, 38, 45, 49, 54, 56, 57, 56, 51, 45, 34, 19, 4, -11, -21, -25, -25,
+
1092 -23, -17, -11, -7, 0, 5, 8, 9, 9, 9, 9, 13, 20, 31, 44, 56, 67, 74, 80, 82, 79,
+
1093 76, 68, 56, 45, 33, 24, 17, 13, 9, 5, 1, -4, -8, -12, -18, -25, -32, -38, -43,
+
1094 -45, -44, -39, -34, -28, -22, -18, -14, -10, -8, -7, -7, -8, -10, -11, -10, -9,
+
1095 -8, -9, -10, -12, -16, -19, -23, -27, -32, -35, -36, -36, -35, -33, -30, -25,
+
1096 -20, -16, -17, -19, -21, -20, -20, -20, -18, -17, -15, -12, -7, -3, -1, 1, -1,
+
1097 -5, -8, -14, -23, -28, -30, -37, -43, -45, -47, -46, -37, -23, -9, 9, 18, 24,
+
1098 33, 38, 40, 44, 43, 39, 34, 32, 34, 40, 46, 50, 53, 50, 47, 43, 36, 32, 21, 7,
+
1099 -5, -15, -21, -21, -18, -15, -11, -7, -4, 2, 6, 10, 12, 13, 14, 17, 22, 31, 41,
+
1100 52, 60, 67, 70, 72, 71, 67, 63, 54, 43, 33, 22, 16, 11, 7, 4, -2, -6, -10, -15,
+
1101 -19, -23, -29, -36, -40, -42, -43, -38, -34, -29, -23, -19, -15, -12, -9, -9,
+
1102 -12, -15, -16, -15, -14, -10, -8, -8, -9, -12, -13, -16, -22, -25, -30, -38,
+
1103 -42, -41, -41, -42, -38, -35, -33, -30, -25, -19, -16, -13, -12, -12, -11, -10,
+
1104 -9, -7, -8, -8, -8, -7, -5, -3, -2, -5, -8, -11, -18, -23, -27, -32, -41, -48,
+
1105 -48, -43, -35, -25, -7, 7, 15, 24, 31, 35, 37, 36, 34, 31, 28, 26, 31, 40, 45,
+
1106 50, 54, 54, 52, 47, 42, 36, 24, 13, 2, -4, -6, -6, -2, 3, 8, 9, 11, 14, 14, 14,
+
1107 14, 13, 13, 15, 21, 30, 41, 50, 58, 62, 63, 63, 59, 54, 47, 37, 28, 20, 13, 10,
+
1108 7, 5, 2, -2, -7, -14, -19, -25, -32, -38, -44, -46, -48, -46, -41, -35, -29,
+
1109 -21, -17, -13, -10, -9, -11, -13, -15, -15, -11, -9, -7, -3, -2, -5, -4, -2, -5,
+
1110 -10, -14, -19, -21, -22, -24, -25, -25, -27, -29, -24, -19, -19, -18, -17, -19,
+
1111 -18, -16, -13, -9, -7, -8, -8, -4, -1, 1, -1, -2, -7, -15, -18, -17, -19, -23,
+
1112 -25, -25, -29, -30, -27, -24, -23, -25, -23, -22, -22, -13, 0, 10, 17, 23, 29,
+
1113 34, 40, 45, 49, 48, 42, 40, 37, 35, 38, 40, 39, 38, 36, 33, 32, 31, 26, 21, 14,
+
1114 6, 1, -3, -2, 1, 2, 5, 8, 11, 15, 21, 26, 31, 35, 35, 36, 39, 41, 45, 47, 47,
+
1115 45, 42, 39, 36, 32, 26, 18, 10, 2, -6, -12, -16, -21, -26, -31, -35, -38, -39,
+
1116 -40, -41, -41, -41, -42, -37, -32, -29, -24, -17, -14, -11, -6, 0, 1, 0, 1, 0,
+
1117 -3, -6, -6, -5, -7, -11, -12, -11, -12, -14, -13, -14, -17, -22, -27, -29, -30,
+
1118 -33, -33, -29, -29, -29, -24, -20, -17, -14, -12, -12, -12, -12, -16, -15, -11,
+
1119 -15, -17, -17, -17, -20, -22, -23, -26, -27, -31, -34, -31, -30, -27, -25, -20,
+
1120 -15, -12, -1, 12, 20, 26, 33, 38, 38, 42, 46, 45, 46, 42, 39, 40, 39, 39, 40,
+
1121 40, 36, 31, 29, 25, 22, 17, 13, 7, 1, -1, -3, -2, 1, 3, 5, 9, 13, 17, 22, 28,
+
1122 32, 35, 37, 39, 43, 46, 48, 49, 48, 47, 43, 39, 35, 29, 22, 15, 6, -2, -8, -14,
+
1123 -19, -23, -27, -32, -35, -37, -39, -40, -40, -40, -39, -38, -34, -29, -24, -18,
+
1124 -13, -9, -6, -4, -3, -3, -4, -2, -3, -4, -5, -5, -3, -2, -3, -4, -6, -11, -17,
+
1125 -19, -23, -28, -31, -34, -33, -32, -31, -24, -21, -19, -18, -16, -16, -14, -13,
+
1126 -15, -12, -10, -12, -6, -1, 1, 2, 2, -2, -7, -10, -14, -18, -20, -22, -25, -26,
+
1127 -25, -22, -21, -20, -21, -27, -30, -32, -30, -25, -17, -9, -4, 6, 14, 21, 31,
+
1128 34, 33, 31, 28, 24, 21, 27, 31, 30, 37, 41, 44, 47, 50, 52, 47, 40, 30, 21, 18,
+
1129 13, 13, 17, 19, 21, 26, 33, 35, 38, 38, 34, 29, 25, 24, 22, 25, 28, 28, 32, 34,
+
1130 35, 35, 33, 28, 18, 9, 0, -10, -15, -20, -23, -24, -24, -22, -21, -19, -18, -19,
+
1131 -22, -29, -34, -38, -39, -41, -40, -34, -30, -24, -17, -11, -7, -8, -11, -14,
+
1132 -17, -19, -20, -20, -22, -22, -18, -16, -11, -10, -12, -13, -17, -21, -24, -24,
+
1133 -26, -29, -27, -26, -22, -17, -13, -9, -9, -11, -11, -13, -14, -15, -14, -14,
+
1134 -15, -14, -15, -12, -13, -15, -13, -17, -22, -23, -25, -26, -25, -22, -21, -22,
+
1135 -22, -21, -16, -13, -7, 0, 4, 7, 10, 15, 20, 23, 25, 26, 27, 26, 26, 27, 28, 31,
+
1136 31, 32, 34, 34, 36, 37, 37, 36, 31, 28, 25, 23, 21, 21, 23, 23, 25, 27, 30, 33,
+
1137 35, 36, 34, 32, 32, 30, 29, 29, 29, 29, 28, 27, 26, 25, 23, 18, 14, 7, 0, -5,
+
1138 -10, -14, -17, -20, -21, -21, -21, -22, -21, -22, -24, -27, -29, -31, -32, -32,
+
1139 -32, -33, -31, -29, -27, -23, -20, -18, -20, -21, -21, -20, -19, -20, -17, -16,
+
1140 -16, -15, -14, -11, -12, -13, -13, -14, -16, -17, -16, -15, -16, -15, -15, -15,
+
1141 -16, -17, -15, -13, -15, -16, -16, -15, -15, -13, -12, -13, -14, -16, -16, -17,
+
1142 -18, -17, -18, -19, -21, -20, -19, -19, -18, -18, -17, -18, -19, -16, -14, -12,
+
1143 -8, -4, 2, 5, 10, 16, 20, 22, 23, 25, 25, 24, 25, 28, 32, 33, 36, 40, 41, 42,
+
1144 44, 44, 43, 39, 36, 33, 30, 28, 27, 27, 26, 28, 27, 26, 27, 25, 24, 22, 19, 17,
+
1145 16, 15, 16, 18, 19, 19, 21, 21, 19, 18, 15, 11, 6, 1, -3, -7, -10, -12, -13,
+
1146 -14, -15, -16, -17, -18, -23, -27, -28, -31, -35, -37, -38, -37, -38, -37, -35,
+
1147 -31, -30, -30, -27, -24, -23, -22, -20, -18, -15, -15, -15, -10, -8, -9, -8, -4,
+
1148 -3, -6, -8, -7, -10, -13, -13, -14, -16, -19, -18, -16, -15, -15, -14, -13, -17,
+
1149 -18, -18, -21, -21, -21, -22, -22, -24, -22, -22, -24, -22, -22, -22, -23, -23,
+
1150 -20, -20, -20, -18, -20, -20, -15, -12, -11, -4, 1, 6, 10, 12, 18, 22, 23, 26,
+
1151 27, 27, 28, 30, 32, 33, 37, 39, 40, 42, 42, 43, 43, 41, 40, 36, 32, 30, 28, 26,
+
1152 26, 26, 26, 26, 25, 26, 26, 24, 24, 22, 21, 22, 20, 22, 23, 23, 24, 24, 24, 23,
+
1153 20, 18, 15, 10, 6, 3, -1, -5, -7, -8, -9, -11, -13, -16, -17, -20, -23, -26,
+
1154 -29, -32, -34, -37, -37, -36, -37, -36, -34, -32, -30, -27, -25, -22, -21, -20,
+
1155 -18, -17, -15, -15, -15, -12, -12, -13, -10, -9, -10, -8, -5, -5, -5, -5, -5,
+
1156 -7, -12, -11, -10, -14, -14, -13, -16, -17, -16, -18, -19, -19, -21, -22, -23,
+
1157 -25, -25, -26, -25, -24, -27, -27, -26, -29, -30, -29, -27, -24, -24, -19, -12,
+
1158 -8, -3, 7, 14, 15, 19, 26, 27, 26, 29, 35, 37, 39, 43, 46, 48, 49, 50, 52, 51,
+
1159 48, 45, 42, 38, 34, 32, 30, 28, 25, 23, 22, 21, 19, 18, 17, 15, 11, 9, 9, 9, 10,
+
1160 12, 15, 16, 18, 20, 22, 24, 25, 25, 24, 22, 20, 17, 15, 13, 10, 7, 4, 1, -3, -5,
+
1161 -8, -10, -14, -19, -23, -28, -33, -36, -39, -41, -44, -46, -46, -46, -44, -43,
+
1162 -41, -40, -38, -37, -36, -31, -26, -23, -20, -17, -13, -12, -12, -8, -4, -4, -3,
+
1163 -1, 0, -2, -2, 0, 3, 0, -2, -2, -3, -7, -11, -12, -13, -19, -24, -24, -28, -33,
+
1164 -33, -33, -36, -38, -39, -41, -44, -46, -46, -46, -45, -44, -44, -39, -33, -28,
+
1165 -20, -11, -2, 4, 10, 17, 22, 25, 31, 35, 37, 39, 42, 46, 50, 54, 57, 61, 63, 62,
+
1166 61, 60, 58, 53, 48, 44, 39, 34, 29, 27, 24, 22, 20, 17, 14, 10, 7, 6, 5, 3, 2,
+
1167 2, 2, 3, 5, 8, 10, 12, 13, 15, 15, 15, 15, 15, 14, 13, 12, 11, 9, 9, 8, 6, 4, 1,
+
1168 -3, -6, -10, -13, -16, -19, -22, -26, -28, -29, -31, -32, -32, -32, -33, -34,
+
1169 -34, -34, -33, -33, -31, -30, -28, -27, -24, -21, -20, -17, -15, -13, -11, -9,
+
1170 -10, -9, -6, -7, -7, -5, -4, -6, -6, -4, -4, -7, -7, -7, -10, -12, -14, -15,
+
1171 -18, -20, -22, -23, -25, -27, -28, -29, -31, -34, -33, -31, -33, -34, -30, -27,
+
1172 -25, -21, -17, -13, -9, -6, -3, 0, 2, 4, 7, 11, 13, 15, 20, 23, 25, 29, 34, 35,
+
1173 37, 40, 41, 41, 43, 44, 42, 42, 43, 42, 41, 41, 40, 38, 37, 35, 32, 30, 29, 27,
+
1174 25, 25, 23, 23, 22, 22, 21, 22, 21, 19, 19, 18, 17, 16, 15, 13, 12, 11, 10, 8,
+
1175 7, 5, 3, 2, 0, -3, -4, -5, -8, -11, -12, -14, -17, -20, -22, -25, -29, -32, -33,
+
1176 -35, -37, -38, -38, -38, -39, -40, -38, -37, -38, -37, -36, -36, -36, -35, -33,
+
1177 -31, -31, -28, -25, -23, -22, -20, -16, -14, -13, -11, -8, -9, -10, -8, -7, -7,
+
1178 -8, -7, -6, -7, -8, -7, -7, -9, -10, -11, -12, -15, -17, -16, -15, -17, -16,
+
1179 -10, -7, -8, -5, 1, 2, 2, 3, 6, 6, 6, 8, 11, 14, 17, 21, 25, 29, 31, 34, 37, 39,
+
1180 38, 40, 41, 41, 40, 40, 41, 42, 42, 42, 42, 40, 38, 35, 32, 31, 27, 24, 23, 22,
+
1181 22, 23, 23, 24, 24, 24, 23, 21, 19, 18, 16, 16, 14, 13, 13, 13, 12, 13, 13, 12,
+
1182 10, 7, 4, 1, -2, -5, -8, -11, -13, -15, -17, -19, -20, -22, -26, -30, -33, -36,
+
1183 -40, -43, -44, -44, -45, -43, -40, -38, -37, -34, -30, -29, -28, -27, -26, -25,
+
1184 -23, -20, -18, -15, -13, -12, -9, -7, -7, -4, -3, -3, -4, -4, -5, -7, -7, -8,
+
1185 -9, -12, -16, -19, -24, -27, -31, -36, -39, -41, -41, -39, -35, -30, -24, -13,
+
1186 -4, 1, 8, 14, 19, 25, 29, 33, 36, 40, 45, 49, 55, 60, 64, 67, 67, 66, 63, 60,
+
1187 55, 47, 42, 35, 27, 20, 15, 12, 8, 5, 2, -2, -5, -8, -10, -12, -11, -9, -6, -1,
+
1188 5, 12, 21, 29, 38, 44, 49, 52, 53, 54, 54, 54, 53, 51, 48, 44, 40, 35, 28, 22,
+
1189 13, 5, -5, -16, -25, -33, -40, -47, -51, -54, -57, -59, -58, -55, -52, -49, -48,
+
1190 -47, -44, -42, -37, -30, -24, -19, -13, -9, -5, 1, 4, 8, 12, 10, 9, 6, 1, -4,
+
1191 -9, -14, -18, -25, -31, -36, -39, -41, -41, -42, -42, -42, -44, -44, -44, -42,
+
1192 -37, -37, -35, -34, -34, -31, -28, -24, -19, -19, -22, -22, -14, -7, 1, 15, 31,
+
1193 39, 42, 52, 54, 50, 53, 49, 43, 37, 29, 27, 24, 27, 29, 28, 29, 24, 19, 14, 11,
+
1194 6, 0, -3, -8, -9, -7, -6, 2, 10, 16, 17, 17, 19, 17, 19, 24, 28, 35, 37, 43, 51,
+
1195 57, 64, 67, 67, 61, 54, 45, 37, 32, 27, 23, 20, 14, 10, 5, 1, -3, -8, -14, -20,
+
1196 -26, -30, -32, -29, -25, -21, -19, -17, -14, -14, -15, -14, -15, -18, -21, -22,
+
1197 -23, -21, -18, -16, -14, -17, -20, -23, -27, -30, -32, -34, -37, -37, -37, -36,
+
1198 -33, -29, -28, -30, -29, -29, -28, -26, -27, -23, -21, -24, -18, -11, -10, -6,
+
1199 -1, -3, -8, -13, -17, -20, -27, -27, -26, -33, -35, -35, -38, -42, -43, -35,
+
1200 -30, -26, -14, -1, 14, 27, 40, 54, 55, 56, 58, 55, 54, 51, 50, 50, 47, 47, 46,
+
1201 44, 41, 36, 32, 22, 12, 1, -8, -16, -19, -18, -21, -18, -14, -11, -4, -1, 4, 9,
+
1202 11, 16, 22, 28, 36, 45, 55, 62, 68, 72, 72, 70, 66, 60, 52, 43, 34, 27, 20, 14,
+
1203 9, 3, -4, -9, -16, -21, -25, -28, -29, -30, -29, -27, -23, -21, -16, -10, -8,
+
1204 -7, -7, -8, -10, -12, -11, -10, -11, -10, -11, -16, -18, -21, -26, -30, -33,
+
1205 -37, -40, -43, -47, -47, -47, -48, -39, -34, -36, -30, -27, -31, -27, -22, -16,
+
1206 -14, -11, -2, -3, -1, 6, 2, 1, 1, -8, -16, -18, -22, -26, -25, -26, -28, -36,
+
1207 -38, -40, -52, -49, -48, -55, -45, -36, -26, -5, 16, 28, 40, 51, 50, 51, 51, 50,
+
1208 48, 46, 46, 46, 47, 51, 50, 50, 46, 38, 30, 19, 8, 0 };
+
1209 
+
1210 #endif /* BLAHBLAH4B_H_ */
diff --git a/extras/doc/html/char2mozzi_8py.html b/extras/doc/html/char2mozzi_8py.html index 932cbc611..9b4acc95e 100644 --- a/extras/doc/html/char2mozzi_8py.html +++ b/extras/doc/html/char2mozzi_8py.html @@ -1,9 +1,9 @@ - + - + Mozzi: char2mozzi.py File Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -106,39 +102,28 @@
-

A script for converting raw 8 bit sound data files to wavetables for Mozzi.
+

A script for converting raw 8 bit sound data files to wavetables for Mozzi. More...

Go to the source code of this file.

Detailed Description

-
A script for converting raw 8 bit sound data files to wavetables for Mozzi.

Usage: >>>char2mozzi.py <infile outfile="" tablename="" samplerate>="">

+

A script for converting raw 8 bit sound data files to wavetables for Mozzi.

+

Usage: >>>char2mozzi.py <infile outfile tablename samplerate>

Parameters
- +
infileThe file to convert, RAW(headerless) Signed 8 bit PCM.
outfileThe file to save as output, a .h file containing a table for Mozzi.
tablenameThe name to give the table of converted data in the new file.
samplerateThe samplerate the sound was recorded at. Choose what make sense for you, if it's not a normal recorded sample.
@note Using Audacity to prepare raw sound files for converting:
-
-For generated waveforms like sine or sawtooth, set the project
-rate to the size of the wavetable you wish to create, which must
-be a power of two (eg. 8192), and set the selection format
-(beneath the editing window) to samples. Then you can generate
-and save 1 second of a waveform and it will fit your table
-length.
-
-For a recorded audio sample, set the project rate to the
-MOZZI_AUDIO_RATE (16384 in the current version). 
-Samples can be any length, as long as they fit in your Arduino.
-
-Save by exporting with the format set to "Other uncompressed formats",
-"Header: RAW(headerless)" and "Encoding: Signed 8 bit PCM".
-
-Now use the file you just exported, as the "infile" to convert.
-
-@author Tim Barrass 2010-12
samplerateThe samplerate the sound was recorded at. Choose what make sense for you, if it's not a normal recorded sample.
+
Note
Using Audacity to prepare raw sound files for converting:
+

For generated waveforms like sine or sawtooth, set the project rate to the size of the wavetable you wish to create, which must be a power of two (eg. 8192), and set the selection format (beneath the editing window) to samples. Then you can generate and save 1 second of a waveform and it will fit your table length.

+

For a recorded audio sample, set the project rate to the MOZZI_AUDIO_RATE (16384 in the current version). Samples can be any length, as long as they fit in your Arduino.

+

Save by exporting with the format set to "Other uncompressed formats", "Header: RAW(headerless)" and "Encoding: Signed 8 bit PCM".

+

Now use the file you just exported, as the "infile" to convert.

+
Author
Tim Barrass 2010-12

Definition in file char2mozzi.py.

@@ -154,9 +139,7 @@ diff --git a/extras/doc/html/char2mozzi_8py_source.html b/extras/doc/html/char2mozzi_8py_source.html index 8f9a44168..e59e0ef29 100644 --- a/extras/doc/html/char2mozzi_8py_source.html +++ b/extras/doc/html/char2mozzi_8py_source.html @@ -1,9 +1,9 @@ - + - +Mozzi: char2mozzi.py Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@ @@ -61,10 +57,10 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -103,16 +99,61 @@
char2mozzi.py
-Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 
35 
36 import sys, array, os, textwrap, random
37 
38 if len(sys.argv) != 5:
39  print ('Usage: char2mozzi.py <infile outfile tablename samplerate>')
40  sys.exit(1)
41 
42 [infile, outfile, tablename, samplerate] = sys.argv[1:]
43 
44 def char2mozzi(infile, outfile, tablename, samplerate):
45  fin = open(os.path.expanduser(infile), "rb")
46  print ("opened " + infile)
47  uint8_tstoread = os.path.getsize(os.path.expanduser(infile))
48 
49  valuesfromfile = array.array('b') # array of signed int8_t ints
50  try:
51  valuesfromfile.fromfile(fin, uint8_tstoread)
52  finally:
53  fin.close()
54 
55  values=valuesfromfile.tolist()
56  fout = open(os.path.expanduser(outfile), "w")
57  fout.write('#ifndef ' + tablename + '_H_' + '\n')
58  fout.write('#define ' + tablename + '_H_' + '\n \n')
59  fout.write('#include <Arduino.h>'+'\n')
60  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
61  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
62  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
63  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
64  try:
65  for i in range(len(values)):
66 
67  if (values[i] == 33) and (values[i+1] == 33) and (values[i+2] == 33):
68  values[i+2] = random.choice([32, 34])
69  outstring += str(values[i]) + ", "
70  finally:
71  outstring += "};"
72  outstring = textwrap.fill(outstring, 80)
73  fout.write(outstring)
74  fout.write('\n\n#endif /* ' + tablename + '_H_ */\n')
75  fout.close()
76  print ("wrote " + outfile)
77 
78 char2mozzi(infile, outfile, tablename, samplerate)
+Go to the documentation of this file.
1 #!/usr/bin/env python
+
2 
+
3 
+
35 
+
36 import sys, array, os, textwrap, random
+
37 
+
38 if len(sys.argv) != 5:
+
39  print ('Usage: char2mozzi.py <infile outfile tablename samplerate>')
+
40  sys.exit(1)
+
41 
+
42 [infile, outfile, tablename, samplerate] = sys.argv[1:]
+
43 
+
44 def char2mozzi(infile, outfile, tablename, samplerate):
+
45  fin = open(os.path.expanduser(infile), "rb")
+
46  print ("opened " + infile)
+
47  uint8_tstoread = os.path.getsize(os.path.expanduser(infile))
+
48 
+
49  valuesfromfile = array.array('b') # array of signed int8_t ints
+
50  try:
+
51  valuesfromfile.fromfile(fin, uint8_tstoread)
+
52  finally:
+
53  fin.close()
+
54 
+
55  values=valuesfromfile.tolist()
+
56  fout = open(os.path.expanduser(outfile), "w")
+
57  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
58  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
59  fout.write('#include <Arduino.h>'+'\n')
+
60  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
61  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
+
62  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
+
63  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
+
64  try:
+
65  for i in range(len(values)):
+
66 
+
67  if (values[i] == 33) and (values[i+1] == 33) and (values[i+2] == 33):
+
68  values[i+2] = random.choice([32, 34])
+
69  outstring += str(values[i]) + ", "
+
70  finally:
+
71  outstring += "};"
+
72  outstring = textwrap.fill(outstring, 80)
+
73  fout.write(outstring)
+
74  fout.write('\n\n#endif /* ' + tablename + '_H_ */\n')
+
75  fout.close()
+
76  print ("wrote " + outfile)
+
77 
+
78 char2mozzi(infile, outfile, tablename, samplerate)
+
diff --git a/extras/doc/html/chebyshev__int8_8py_source.html b/extras/doc/html/chebyshev__int8_8py_source.html index c6ec50977..26d77852f 100644 --- a/extras/doc/html/chebyshev__int8_8py_source.html +++ b/extras/doc/html/chebyshev__int8_8py_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: chebyshev_int8.py Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,81 @@
chebyshev_int8.py
-
1 
2 
3 import array,os,textwrap,math
4 
5 
6 def chebyTable(outfile, tablename, tablelength, curvenum):
7 
8  """
9  Generates chebyshev polynomial curve tables for WaveShaper.
10 
11  Args:
12  outfile: The file to save as output.
13  tablename: The name to give the table of converted data in the new file.
14  tablelength: Use a power of two.
15  curvenum: The chebyshev polynomial curve number to chebyTable.
16 
17  Examples:
18  chebyTable("~/Desktop/waveshaper_chebyshev_3rd_256_int8.h", "CHEBYSHEV_3RD_256", 256, 3)
19  chebyTable("~/Desktop/waveshaper_chebyshev_4th_256_int8.h", "CHEBYSHEV_4TH_256", 256, 4)
20  chebyTable("~/Desktop/waveshaper_chebyshev_5th_256_int8.h", "CHEBYSHEV_5TH_256", 256, 5)
21  chebyTable("~/Desktop/waveshaper_chebyshev_6th_256_int8.h", "CHEBYSHEV_6TH_256", 256, 6)
22 
23  Resources:
24  http://www.obiwannabe.co.uk/html/music/6SS/six-waveshaper.html
25  http://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html
26  The first few Chebyshev polynomials of the first kind are
27  T_0(x) = 1
28  T_1(x) = x
29  T_2(x) = 2x^2-1
30  T_3(x) = 4x^3-3x
31  T_4(x) = 8x^4-8x^2+1
32  T_5(x) = 16x^5-20x^3+5x
33  T_6(x) = 32x^6-48x^4+18x^2-1
34 
35  """
36 
37  fout = open(os.path.expanduser(outfile), "w")
38  fout.write('#ifndef ' + tablename + '_H_' + '\n')
39  fout.write('#define ' + tablename + '_H_' + '\n \n')
40  fout.write('#include <Arduino.h>'+'\n')
41  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
42  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength) +'\n')
43  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
44  try:
45  for num in range(tablelength):
46 
47  x = 2*(float(num-(tablelength/2)))/tablelength
48 
49  if curvenum == 3:
50  t_x = 4*pow(x,3)-3*x
51  elif curvenum == 4:
52  t_x = 8*pow(x,4)-8*pow(x,2)+1
53  elif curvenum == 5:
54  t_x = 16*pow(x,5)-20*pow(x,3)+5*x
55  elif curvenum == 6:
56  t_x = 32*pow(x,6)-48*pow(x,4)+18*pow(x,2)-1
57 
58  scaled = int16_t(math.floor(t_x*127.999))
59 
60  outstring += str(scaled) + ", "
61  finally:
62  outstring += "};"
63  outstring = textwrap.fill(outstring, 80)
64  fout.write(outstring)
65  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
66  fout.close()
67  print "wrote " + outfile
68 
+
1 
+
2 
+
3 import array,os,textwrap,math
+
4 
+
5 
+
6 def chebyTable(outfile, tablename, tablelength, curvenum):
+
7 
+
8  """
+
9  Generates chebyshev polynomial curve tables for WaveShaper.
+
10 
+
11  Args:
+
12  outfile: The file to save as output.
+
13  tablename: The name to give the table of converted data in the new file.
+
14  tablelength: Use a power of two.
+
15  curvenum: The chebyshev polynomial curve number to chebyTable.
+
16 
+
17  Examples:
+
18  chebyTable("~/Desktop/waveshaper_chebyshev_3rd_256_int8.h", "CHEBYSHEV_3RD_256", 256, 3)
+
19  chebyTable("~/Desktop/waveshaper_chebyshev_4th_256_int8.h", "CHEBYSHEV_4TH_256", 256, 4)
+
20  chebyTable("~/Desktop/waveshaper_chebyshev_5th_256_int8.h", "CHEBYSHEV_5TH_256", 256, 5)
+
21  chebyTable("~/Desktop/waveshaper_chebyshev_6th_256_int8.h", "CHEBYSHEV_6TH_256", 256, 6)
+
22 
+
23  Resources:
+
24  http://www.obiwannabe.co.uk/html/music/6SS/six-waveshaper.html
+
25  http://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html
+
26  The first few Chebyshev polynomials of the first kind are
+
27  T_0(x) = 1
+
28  T_1(x) = x
+
29  T_2(x) = 2x^2-1
+
30  T_3(x) = 4x^3-3x
+
31  T_4(x) = 8x^4-8x^2+1
+
32  T_5(x) = 16x^5-20x^3+5x
+
33  T_6(x) = 32x^6-48x^4+18x^2-1
+
34 
+
35  """
+
36 
+
37  fout = open(os.path.expanduser(outfile), "w")
+
38  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
39  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
40  fout.write('#include <Arduino.h>'+'\n')
+
41  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
42  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength) +'\n')
+
43  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
+
44  try:
+
45  for num in range(tablelength):
+
46 
+
47  x = 2*(float(num-(tablelength/2)))/tablelength
+
48 
+
49  if curvenum == 3:
+
50  t_x = 4*pow(x,3)-3*x
+
51  elif curvenum == 4:
+
52  t_x = 8*pow(x,4)-8*pow(x,2)+1
+
53  elif curvenum == 5:
+
54  t_x = 16*pow(x,5)-20*pow(x,3)+5*x
+
55  elif curvenum == 6:
+
56  t_x = 32*pow(x,6)-48*pow(x,4)+18*pow(x,2)-1
+
57 
+
58  scaled = int16_t(math.floor(t_x*127.999))
+
59 
+
60  outstring += str(scaled) + ", "
+
61  finally:
+
62  outstring += "};"
+
63  outstring = textwrap.fill(outstring, 80)
+
64  fout.write(outstring)
+
65  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
+
66  fout.close()
+
67  print "wrote " + outfile
+
68 
+
diff --git a/extras/doc/html/class_a_d_s_r-members.html b/extras/doc/html/class_a_d_s_r-members.html index 2d5ed2a47..aeb5efc06 100644 --- a/extras/doc/html/class_a_d_s_r-members.html +++ b/extras/doc/html/class_a_d_s_r-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -137,9 +133,7 @@ diff --git a/extras/doc/html/class_a_d_s_r.html b/extras/doc/html/class_a_d_s_r.html index d7c9ffa93..7dee4a42d 100644 --- a/extras/doc/html/class_a_d_s_r.html +++ b/extras/doc/html/class_a_d_s_r.html @@ -1,9 +1,9 @@ - + - + Mozzi: ADSR< CONTROL_UPDATE_RATE, LERP_RATE, T > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -109,7 +105,7 @@
-

A simple ADSR envelope generator. +

A simple ADSR envelope generator. More...

#include <ADSR.h>

@@ -117,11 +113,11 @@

template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
class ADSR< CONTROL_UPDATE_RATE, LERP_RATE, T >

-

A simple ADSR envelope generator.

-

This implementation has separate update() and next() methods, where next() interpolates values between each update(). The "normal" way to use this would be with update() in updateControl(), where it calculates a new internal state each control step, and then next() is in updateAudio(), called much more often, where it interpolates between the control values. This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update.

Template Parameters
+

A simple ADSR envelope generator.

+

This implementation has separate update() and next() methods, where next() interpolates values between each update(). The "normal" way to use this would be with update() in updateControl(), where it calculates a new internal state each control step, and then next() is in updateAudio(), called much more often, where it interpolates between the control values. This also allows the ADSR updates to be made even more sparsely if desired, eg. every 3rd control update.

Template Parameters
- - + +
CONTROL_UPDATE_RATEThe frequency of control updates. Ordinarily this will be MOZZI_CONTROL_RATE, but an alternative (amongst others) is to set this as well as the LERP_RATE parameter to MOZZI_AUDIO_RATE, and call both update() and next() in updateAudio(). Such a use would allow accurate envelopes with finer resolution of the control points than MOZZI_CONTROL_RATE.
LERP_RATESets how often next() will be called, to interpolate between updates set by CONTROL_UPDATE_RATE. This will produce the smoothest results if it's set to MOZZI_AUDIO_RATE, but if you need to save processor time and your envelope changes slowly or controls something like a filter where there may not be problems with glitchy or clicking transitions, LERP_RATE could be set to MOZZI_CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(), greatly reducing the amount of processing required compared to calling next() in updateAudio().
CONTROL_UPDATE_RATEThe frequency of control updates. Ordinarily this will be MOZZI_CONTROL_RATE, but an alternative (amongst others) is to set this as well as the LERP_RATE parameter to MOZZI_AUDIO_RATE, and call both update() and next() in updateAudio(). Such a use would allow accurate envelopes with finer resolution of the control points than MOZZI_CONTROL_RATE.
LERP_RATESets how often next() will be called, to interpolate between updates set by CONTROL_UPDATE_RATE. This will produce the smoothest results if it's set to MOZZI_AUDIO_RATE, but if you need to save processor time and your envelope changes slowly or controls something like a filter where there may not be problems with glitchy or clicking transitions, LERP_RATE could be set to MOZZI_CONTROL_RATE (for instance). Then update() and next() could both be called in updateControl(), greatly reducing the amount of processing required compared to calling next() in updateAudio().
@@ -135,76 +131,76 @@  Constructor.
  void update () - Updates the internal controls of the ADSR. More...
+ Updates the internal controls of the ADSR. More...
  unsigned char next () - Advances one audio step along the ADSR and returns the level. More...
+ Advances one audio step along the ADSR and returns the level. More...
  void noteOn (bool reset=false) - Start the attack phase of the ADSR. More...
+ Start the attack phase of the ADSR. More...
  void noteOff () - Start the release phase of the ADSR. More...
+ Start the release phase of the ADSR. More...
  void setAttackLevel (byte value) - Set the attack level of the ADSR. More...
+ Set the attack level of the ADSR. More...
  void setDecayLevel (byte value) - Set the decay level of the ADSR. More...
+ Set the decay level of the ADSR. More...
  void setSustainLevel (byte value) - Set the sustain level of the ADSR. More...
+ Set the sustain level of the ADSR. More...
  void setReleaseLevel (byte value) - Set the release level of the ADSR. More...
+ Set the release level of the ADSR. More...
  void setIdleLevel (byte value)   void setADLevels (byte attack, byte decay) - Set the attack and decay levels of the ADSR. More...
+ Set the attack and decay levels of the ADSR. More...
  void setLevels (byte attack, byte decay, byte sustain, byte release) - Set the attack, decay, sustain and release levels. More...
+ Set the attack, decay, sustain and release levels. More...
  void setAttackTime (unsigned int msec) - Set the attack time of the ADSR in milliseconds. More...
+ Set the attack time of the ADSR in milliseconds. More...
  void setDecayTime (unsigned int msec) - Set the decay time of the ADSR in milliseconds. More...
+ Set the decay time of the ADSR in milliseconds. More...
  void setSustainTime (unsigned int msec) - Set the sustain time of the ADSR in milliseconds. More...
+ Set the sustain time of the ADSR in milliseconds. More...
  void setReleaseTime (unsigned int msec) - Set the release time of the ADSR in milliseconds. More...
+ Set the release time of the ADSR in milliseconds. More...
  void setIdleTime (unsigned int msec)   void setTimes (unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms) - Set the attack, decay and release times of the ADSR in milliseconds. More...
+ Set the attack, decay and release times of the ADSR in milliseconds. More...
  void setAttackUpdateSteps (unsigned int steps) - Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the attack phase. More...
+ Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the attack phase. More...
  void setDecayUpdateSteps (unsigned int steps) - Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the decay phase. More...
+ Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the decay phase. More...
  void setSustainUpdateSteps (unsigned int steps) - Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the sustain phase. More...
+ Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the sustain phase. More...
  void setReleaseUpdateSteps (unsigned int steps) - Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the release phase. More...
+ Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the release phase. More...
  void setIdleUpdateSteps (unsigned int steps)   void setAllUpdateSteps (unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps) - Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() interpolation steps). More...
+ Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() interpolation steps). More...
  bool playing () - Tells if the envelope is currently playing. More...
+ Tells if the envelope is currently playing. More...
  - + + + + + + + + + + + + + + + + +

@@ -220,7 +216,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
@@ -61,10 +57,10 @@
@@ -239,8 +235,8 @@

-

Advances one audio step along the ADSR and returns the level.

-

Call this in updateAudio().

Returns
the next value, as an unsigned char.
+

Advances one audio step along the ADSR and returns the level.

+

Call this in updateAudio().

Returns
the next value, as an unsigned char.

Definition at line 161 of file ADSR.h.

@@ -252,7 +248,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
@@ -61,10 +57,10 @@
@@ -271,7 +267,7 @@

-

Start the release phase of the ADSR.

+

Start the release phase of the ADSR.

Definition at line 188 of file ADSR.h.

@@ -283,7 +279,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
@@ -61,10 +57,10 @@
@@ -303,8 +299,8 @@

-

Start the attack phase of the ADSR.

-

This will restart the ADSR no matter what phase it is up to.

Parameters
+

Start the attack phase of the ADSR.

+

This will restart the ADSR no matter what phase it is up to.

Parameters
resetIf true, the envelope will start from 0, even if it is still playing (often useful for effect envelopes). If false (default if omitted), the envelope will start rising from the current level, which could be non-zero, if it is still playing (most useful for note envelopes).
@@ -321,7 +317,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
@@ -61,10 +57,10 @@
@@ -353,7 +349,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
@@ -61,10 +57,10 @@
@@ -383,8 +379,8 @@

-

Set the attack and decay levels of the ADSR.

-

This assumes a conventional ADSR where the sustain continues at the same level as the decay, till the release ramps to 0.

Parameters
+

Set the attack and decay levels of the ADSR.

+

This assumes a conventional ADSR where the sustain continues at the same level as the decay, till the release ramps to 0.

Parameters
@@ -402,7 +398,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

attackthe new attack level.
decaythe new decay level.
@@ -61,10 +57,10 @@
@@ -444,7 +440,7 @@

-

Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() interpolation steps).

+

Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() interpolation steps).

Parameters
@@ -465,7 +461,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

attack_stepsthe number of update steps in the attack phase
@@ -61,10 +57,10 @@
@@ -485,7 +481,7 @@

-

Set the attack level of the ADSR.

+

Set the attack level of the ADSR.

Parameters
@@ -503,7 +499,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

valuethe attack level.
@@ -61,10 +57,10 @@
@@ -523,7 +519,7 @@

-

Set the attack time of the ADSR in milliseconds.

+

Set the attack time of the ADSR in milliseconds.

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.

Parameters
@@ -542,7 +538,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

msecthe unsigned int attack time in milliseconds.
@@ -61,10 +57,10 @@
@@ -562,10 +558,10 @@

-

Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the attack phase.

+

Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the attack phase.

Parameters
- +
stepsthe number of times ADSR::update() will be called in the attack phase.
stepsthe number of times ADSR::update() will be called in the attack phase.
@@ -580,7 +576,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
@@ -61,10 +57,10 @@
@@ -600,7 +596,7 @@

-

Set the decay level of the ADSR.

+

Set the decay level of the ADSR.

Parameters
@@ -618,7 +614,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

valuethe decay level.
@@ -61,10 +57,10 @@
@@ -638,7 +634,7 @@

-

Set the decay time of the ADSR in milliseconds.

+

Set the decay time of the ADSR in milliseconds.

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.

Parameters
@@ -657,7 +653,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

msecthe unsigned int decay time in milliseconds.
- + @@ -498,7 +494,7 @@

-

Set delay time expressed in samples.

+

Set delay time expressed in samples, fractional float for an interpolating delay.

Parameters

@@ -677,10 +673,10 @@

-

Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the decay phase.

+

Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the decay phase.

Parameters
- +
stepsthe number of times ADSR::update() will be called in the decay phase.
stepsthe number of times ADSR::update() will be called in the decay phase.
@@ -695,7 +691,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
- + +
@@ -758,7 +754,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
- - +
@@ -778,7 +774,7 @@

-

Set the release level of the ADSR.

+

Set the release level of the ADSR.

Normally you'd make this 0, but you have the option of some other value.

Parameters
@@ -796,7 +792,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

valuethe release level (usually 0).
- + @@ -389,21 +384,22 @@

-

Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input.

+

Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells, and add feedback from the output to the input.

Parameters

@@ -816,7 +812,7 @@

-

Set the release time of the ADSR in milliseconds.

+

Set the release time of the ADSR in milliseconds.

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE.

Parameters
@@ -835,7 +831,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

msecthe unsigned int release time in milliseconds.
- + @@ -339,22 +335,21 @@

-

Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells, and add feedback from the output to the input.

+

Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input.

Parameters

@@ -855,10 +851,10 @@

-

Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the release phase.

+

Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the release phase.

Parameters
- +
stepsthe number of times ADSR::update() will be called in the release phase.
stepsthe number of times ADSR::update() will be called in the release phase.
@@ -873,7 +869,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
- + - + - + - + - + - + - + - + - + - + - + - + - + - +
@@ -893,7 +889,7 @@

-

Set the sustain level of the ADSR.

+

Set the sustain level of the ADSR.

Parameters
@@ -911,7 +907,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

valuethe sustain level. Usually the same as the decay level, for a steady sustained note.
@@ -279,11 +263,12 @@

Parameters

@@ -931,8 +927,8 @@

-

Set the sustain time of the ADSR in milliseconds.

-

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE. The sustain phase will finish if the ADSR recieves a noteOff().

Parameters
+

Set the sustain time of the ADSR in milliseconds.

+

The actual time taken will be resolved within the resolution of MOZZI_CONTROL_RATE. The sustain phase will finish if the ADSR recieves a noteOff().

Parameters
msecthe unsigned int sustain time in milliseconds.
@@ -950,7 +946,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
- + - + - + - + - +
@@ -970,10 +966,10 @@

-

Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the sustain phase.

+

Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolation steps) in the sustain phase.

Parameters
- +
stepsthe number of times ADSR::update() will be called in the sustain phase.
stepsthe number of times ADSR::update() will be called in the sustain phase.
@@ -988,7 +984,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
@@ -61,10 +57,10 @@
@@ -1030,7 +1026,7 @@

-

Set the attack, decay and release times of the ADSR in milliseconds.

+

Set the attack, decay and release times of the ADSR in milliseconds.

The actual times will be resolved within the resolution of MOZZI_CONTROL_RATE.

Parameters
@@ -1052,7 +1048,7 @@

-template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>
+template<unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE, typename T = unsigned int>

attack_msthe new attack time in milliseconds.
@@ -61,10 +57,10 @@
@@ -1071,8 +1067,8 @@

-

Updates the internal controls of the ADSR.

-

Call this in updateControl().

+

Updates the internal controls of the ADSR.

+

Call this in updateControl().

Definition at line 128 of file ADSR.h.

@@ -1084,9 +1080,7 @@

    - +
diff --git a/extras/doc/html/class_audio_delay-members.html b/extras/doc/html/class_audio_delay-members.html index ea7859c90..e2c2bb3db 100644 --- a/extras/doc/html/class_audio_delay-members.html +++ b/extras/doc/html/class_audio_delay-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -117,9 +113,7 @@ diff --git a/extras/doc/html/class_audio_delay.html b/extras/doc/html/class_audio_delay.html index f3b9d0606..4c435a4ca 100644 --- a/extras/doc/html/class_audio_delay.html +++ b/extras/doc/html/class_audio_delay.html @@ -1,9 +1,9 @@ - + - + Mozzi: AudioDelay< NUM_BUFFER_SAMPLES, T > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -111,17 +107,6 @@ More...

#include <AudioDelay.h>

-
- + Inheritance diagram for AudioDelay< NUM_BUFFER_SAMPLES, T >:
-
-
-

Detailed Description

template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
class AudioDelay< NUM_BUFFER_SAMPLES, T >

@@ -129,7 +114,7 @@

Audio delay line for comb filter, flange, chorus and short echo effects.

Template Parameters
- +
NUM_BUFFER_SAMPLESis the length of the delay buffer in samples. This should be a power of two. The largest delay you'll fit in an atmega328 will be 512 cells, which at 16384 Hz sample rate is 31 milliseconds. More of a flanger or a doubler than an echo. The amount of memory available for delays on other chips will vary. AudioDelay() doesn't have feedback. If you want feedback, use AudioDelayFeedback().
NUM_BUFFER_SAMPLESis the length of the delay buffer in samples. This should be a power of two. The largest delay you'll fit in an atmega328 will be 512 cells, which at 16384 Hz sample rate is 31 milliseconds. More of a flanger or a doubler than an echo. The amount of memory available for delays on other chips will vary. AudioDelay() doesn't have feedback. If you want feedback, use AudioDelayFeedback().
thetype of numbers to use for the signal in the delay. The default is int8_t, but int could be useful when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
@@ -144,19 +129,19 @@

 Constructor.
 
 AudioDelay (unsigned int delaytime_cells)
 Constructor. More...
 Constructor. More...
 
next (T in_value, unsigned int delaytime_cells)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
next (T in_value)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
void set (unsigned int delaytime_cells)
 Set the delay time, measured in cells. More...
 Set the delay time, measured in cells. More...
 
read (unsigned int delaytime_cells)
 Retrieve the signal in the delay line at the position delaytime_cells. More...
 Retrieve the signal in the delay line at the position delaytime_cells. More...
 

Constructor & Destructor Documentation

@@ -166,7 +151,7 @@

-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
+template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
@@ -240,22 +215,21 @@

Parameters

@@ -189,8 +174,8 @@

Parameters
- +
delaytime_cellsdelay time expressed in cells.
-For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
delaytime_cellsdelay time expressed in cells.
+ For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
@@ -200,13 +185,13 @@

Member Function Documentation

- -

◆ next() [1/2]

+ +

◆ next() [1/2]

-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
+template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
- - - - - - - - - + - -
@@ -215,18 +200,8 @@

T AudioDelay< NUM_BUFFER_SAMPLES, T >::next

( in_value,
unsigned int delaytime_cells 
in_value) )

-
in_valuethe signal input.
delaytime_cellssets the delay time in terms of cells in the delay buffer.

-

Definition at line 59 of file AudioDelay.h.

+

Definition at line 77 of file AudioDelay.h.

- -

◆ next() [2/2]

+ +

◆ next() [2/2]

-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
+template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
- + + + + + + + + + + +
@@ -264,8 +238,18 @@

T AudioDelay< NUM_BUFFER_SAMPLES, T >::next

( in_value)in_value,
unsigned int delaytime_cells 
)

+
in_valuethe signal input.
delaytime_cellssets the delay time in terms of cells in the delay buffer.
-

Definition at line 77 of file AudioDelay.h.

+

Definition at line 59 of file AudioDelay.h.

@@ -293,7 +278,7 @@

-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
+template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
@@ -61,10 +57,10 @@
@@ -331,7 +316,7 @@

-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
+template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
@@ -61,10 +57,10 @@
@@ -369,9 +354,7 @@

    - +
diff --git a/extras/doc/html/class_audio_delay.js b/extras/doc/html/class_audio_delay.js index 2b6961974..2c5c69c12 100644 --- a/extras/doc/html/class_audio_delay.js +++ b/extras/doc/html/class_audio_delay.js @@ -2,8 +2,8 @@ var class_audio_delay = [ [ "AudioDelay", "class_audio_delay.html#a688f69088f96bf3976a8555d3026365f", null ], [ "AudioDelay", "class_audio_delay.html#a79be253fcb5709624c8fb708e54f069f", null ], - [ "next", "class_audio_delay.html#a19258636609d83a2bab11849e17b5294", null ], [ "next", "class_audio_delay.html#a41c09b5cc9e817d8eaf111b0f74c9a0b", null ], + [ "next", "class_audio_delay.html#a19258636609d83a2bab11849e17b5294", null ], [ "read", "class_audio_delay.html#a26b409fbfc322ae527ba23680c56e3a9", null ], [ "set", "class_audio_delay.html#a7bd0a07f7803afda1a71b50e3f66827b", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_audio_delay_feedback-members.html b/extras/doc/html/class_audio_delay_feedback-members.html index 173d8c647..e926fbad4 100644 --- a/extras/doc/html/class_audio_delay_feedback-members.html +++ b/extras/doc/html/class_audio_delay_feedback-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -126,9 +122,7 @@ diff --git a/extras/doc/html/class_audio_delay_feedback.html b/extras/doc/html/class_audio_delay_feedback.html index 91df0a4b1..cd40ff4c1 100644 --- a/extras/doc/html/class_audio_delay_feedback.html +++ b/extras/doc/html/class_audio_delay_feedback.html @@ -1,9 +1,9 @@ - + - + Mozzi: AudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -118,7 +114,7 @@

Audio delay line with feedback for comb filter, flange, chorus and short echo effects.

Template Parameters
- +
NUM_BUFFER_SAMPLESis the length of the delay buffer in samples, and should be a power of two. The maximum delay length which will fit in an atmega328 is half that of a plain AudioDelay object, in this case 256 cells, or about 15 milliseconds. AudioDelayFeedback uses int16_t sized cells to accomodate the higher amplitude of direct input to the delay as well as the feedback, without losing precision. Output is only the delay line signal. If you want to mix the delay with the input, do it in your sketch. AudioDelayFeedback uses more processing and memory than a plain AudioDelay, but allows for more dramatic effects with feedback.
NUM_BUFFER_SAMPLESis the length of the delay buffer in samples, and should be a power of two. The maximum delay length which will fit in an atmega328 is half that of a plain AudioDelay object, in this case 256 cells, or about 15 milliseconds. AudioDelayFeedback uses int16_t sized cells to accomodate the higher amplitude of direct input to the delay as well as the feedback, without losing precision. Output is only the delay line signal. If you want to mix the delay with the input, do it in your sketch. AudioDelayFeedback uses more processing and memory than a plain AudioDelay, but allows for more dramatic effects with feedback.
INTERP_TYPEa choice of LINEAR (default) or ALLPASS interpolation. LINEAR is better for sweeping delay times, ALLPASS may be better for reverb-like effects.
@@ -133,46 +129,46 @@

 Constructor.
 
 AudioDelayFeedback (uint16_t delaytime_cells)
 Constructor. More...
 Constructor. More...
 
 AudioDelayFeedback (uint16_t delaytime_cells, int8_t feedback_level)
 Constructor. More...
 Constructor. More...
 
int16_t next (int8_t input)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
int16_t next (int8_t input, uint16_t delaytime_cells)
 Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells, and add feedback from the output to the input. More...
 Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells, and add feedback from the output to the input. More...
 
int16_t next (int8_t input, Q16n16 delaytime_cells)
 Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input. More...
 Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input. More...
 
void write (int8_t input)
 Input a value to the delay but don't change the delay time or retrieve the output signal. More...
 Input a value to the delay but don't change the delay time or retrieve the output signal. More...
 
void writeFeedback (int8_t input)
 Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal. More...
 Input a value to the delay but don't advance the write position, change the delay time or retrieve the output signal. More...
 
void write (int8_t input, uint16_t offset)
 Input a value to the delay at an offset from the current write position. More...
 Input a value to the delay at an offset from the current write position. More...
 
int16_t read (Q16n16 delaytime_cells)
 Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells. More...
 Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells. More...
 
int16_t read ()
 Retrieve the signal in the delay line at the current stored delaytime_cells. More...
 Retrieve the signal in the delay line at the current stored delaytime_cells. More...
 
void setDelayTimeCells (uint16_t delaytime_cells)
 Set delay time expressed in samples. More...
 Set delay time expressed in samples. More...
 
void setDelayTimeCells (Q16n16 delaytime_cells)
 Set delay time expressed in samples, fractional Q16n16 for an interpolating delay. More...
 Set delay time expressed in samples, fractional Q16n16 for an interpolating delay. More...
 
void setDelayTimeCells (float delaytime_cells)
 Set delay time expressed in samples, fractional float for an interpolating delay. More...
 Set delay time expressed in samples, fractional float for an interpolating delay. More...
 
void setFeedbackLevel (int8_t feedback_level)
 Set the feedback gain. More...
 Set the feedback gain. More...
 

Constructor & Destructor Documentation

@@ -297,14 +293,14 @@

Note
slower than next(int8_t input, uint16_t delaytime_cells)
+
Note
slower than next(int8_t input, uint16_t delaytime_cells)

Definition at line 71 of file AudioDelayFeedback.h.

- -

◆ next() [2/3]

+ +

◆ next() [2/3]

@@ -323,7 +319,7 @@

uint16_t Q16n16  delaytime_cells 
- +
inputthe signal input.
delaytime_cellsindicates the delay time in terms of cells in the delay buffer. It doesn't change the stored internal value of _delaytime_cells.
delaytime_cellsis a fractional number to set the delay time in terms of cells or partial cells in the delay buffer. It doesn't change the stored internal value of _delaytime_cells.
-
Note
Timing: 4us
-

Definition at line 88 of file AudioDelayFeedback.h.

+

Definition at line 113 of file AudioDelayFeedback.h.

- -

◆ next() [3/3]

+ +

◆ next() [3/3]

@@ -373,7 +368,7 @@

Q16n16 uint16_t  delaytime_cells 
- +
inputthe signal input.
delaytime_cellsis a fractional number to set the delay time in terms of cells or partial cells in the delay buffer. It doesn't change the stored internal value of _delaytime_cells.
delaytime_cellsindicates the delay time in terms of cells in the delay buffer. It doesn't change the stored internal value of _delaytime_cells.
+
Note
Timing: 4us
-

Definition at line 113 of file AudioDelayFeedback.h.

+

Definition at line 88 of file AudioDelayFeedback.h.

- -

◆ read() [1/2]

+ +

◆ read() [1/2]

@@ -416,8 +412,7 @@

int16_t AudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >::read

(Q16n16 delaytime_cells))
@@ -428,20 +423,15 @@

-

Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.

-

It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.

Parameters
- - -
delaytime_cellsindicates the delay time in terms of cells in the delay buffer.
-
-
+

Retrieve the signal in the delay line at the current stored delaytime_cells.

+

It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.

-

Definition at line 182 of file AudioDelayFeedback.h.

+

Definition at line 192 of file AudioDelayFeedback.h.

- -

◆ read() [2/2]

+ +

◆ read() [2/2]

@@ -454,7 +444,8 @@

int16_t AudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >::read

()Q16n16 delaytime_cells)
@@ -465,15 +456,20 @@

-

Retrieve the signal in the delay line at the current stored delaytime_cells.

-

It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.

+

Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.

+

It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.

Parameters
+ + +
delaytime_cellsindicates the delay time in terms of cells in the delay buffer.
+
+
-

Definition at line 192 of file AudioDelayFeedback.h.

+

Definition at line 182 of file AudioDelayFeedback.h.

- -

◆ setDelayTimeCells() [1/3]

+ +

◆ setDelayTimeCells() [1/3]

@@ -486,7 +482,7 @@

void AudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >::setDelayTimeCells

(uint16_t float  delaytime_cells)
@@ -506,7 +502,7 @@

Definition at line 204 of file AudioDelayFeedback.h.

+

Definition at line 228 of file AudioDelayFeedback.h.

@@ -548,8 +544,8 @@

-

◆ setDelayTimeCells() [3/3]

+ +

◆ setDelayTimeCells() [3/3]

@@ -562,7 +558,7 @@

void AudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >::setDelayTimeCells

- + @@ -574,7 +570,7 @@

-

Set delay time expressed in samples, fractional float for an interpolating delay.

+

Set delay time expressed in samples.

Parameters

delaytime_cellsdelay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE. For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
(float uint16_t  delaytime_cells)
@@ -582,7 +578,7 @@

Definition at line 228 of file AudioDelayFeedback.h.

+

Definition at line 204 of file AudioDelayFeedback.h.

@@ -755,9 +751,7 @@

    - +
diff --git a/extras/doc/html/class_audio_delay_feedback.js b/extras/doc/html/class_audio_delay_feedback.js index 9e1fc1e7a..dbf60cc69 100644 --- a/extras/doc/html/class_audio_delay_feedback.js +++ b/extras/doc/html/class_audio_delay_feedback.js @@ -4,13 +4,13 @@ var class_audio_delay_feedback = [ "AudioDelayFeedback", "class_audio_delay_feedback.html#a7d038aff13126acbca484b74b1ee5620", null ], [ "AudioDelayFeedback", "class_audio_delay_feedback.html#a54d7f001d6a99bd3955fb7dab94fbfe8", null ], [ "next", "class_audio_delay_feedback.html#a5a702d1a0a9b104beb0b18c80422500e", null ], - [ "next", "class_audio_delay_feedback.html#a7c7745dd84f01dbdc9b6552a4c427f0b", null ], [ "next", "class_audio_delay_feedback.html#af9cc2cf135fa0f1a1f0d50ca7d9f89ea", null ], - [ "read", "class_audio_delay_feedback.html#a77508ec1d8da719edbc7c34173c9d7cb", null ], + [ "next", "class_audio_delay_feedback.html#a7c7745dd84f01dbdc9b6552a4c427f0b", null ], [ "read", "class_audio_delay_feedback.html#a8b6cefa45ecaa174320effe25b9ce6c5", null ], - [ "setDelayTimeCells", "class_audio_delay_feedback.html#abcf71a86083db5a48ef71c1397247886", null ], - [ "setDelayTimeCells", "class_audio_delay_feedback.html#a8e8344af6962ea061da8f70ed119b2bd", null ], + [ "read", "class_audio_delay_feedback.html#a77508ec1d8da719edbc7c34173c9d7cb", null ], [ "setDelayTimeCells", "class_audio_delay_feedback.html#a7c54b49ae9f25baaf8714528295c53e2", null ], + [ "setDelayTimeCells", "class_audio_delay_feedback.html#a8e8344af6962ea061da8f70ed119b2bd", null ], + [ "setDelayTimeCells", "class_audio_delay_feedback.html#abcf71a86083db5a48ef71c1397247886", null ], [ "setFeedbackLevel", "class_audio_delay_feedback.html#a2cd87a7dc91187ed439a8ec1d7e00d29", null ], [ "write", "class_audio_delay_feedback.html#aa3232fec9e7f90169e8d8eab85f39394", null ], [ "write", "class_audio_delay_feedback.html#aeeec669071403fc0a294724e775e3812", null ], diff --git a/extras/doc/html/class_cap_poll-members.html b/extras/doc/html/class_cap_poll-members.html index 0c3fe94de..8ef5cc108 100644 --- a/extras/doc/html/class_cap_poll-members.html +++ b/extras/doc/html/class_cap_poll-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

@@ -61,10 +57,10 @@
delaytime_cellsdelay time expressed in cells, with each cell played per tick of MOZZI_AUDIO_RATE. For example, 128 cells delay at MOZZI_AUDIO_RATE would produce a time delay of 128/16384 = 0.0078125 s = 7.8 ms Put another way, num_cells = delay_seconds * MOZZI_AUDIO_RATE.
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/class_cap_poll.html b/extras/doc/html/class_cap_poll.html index 0eaaeeaaf..9564d750c 100644 --- a/extras/doc/html/class_cap_poll.html +++ b/extras/doc/html/class_cap_poll.html @@ -1,9 +1,9 @@ - + - + Mozzi: CapPoll< SENSOR_PIN, SEND_PIN > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,8 +103,7 @@
-


-A class for reading voltage on a digital pin, derived from
http://arduino.cc/en/Tutorial/RCtime. +

A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime. More...

#include <CapPoll.h>

@@ -116,11 +111,10 @@

template<unsigned char SENSOR_PIN, unsigned char SEND_PIN>
class CapPoll< SENSOR_PIN, SEND_PIN >

-


-A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.

-

This is designed to be used in updateControl(). Each time it is called, it checks if a capacitor has charged, and returns an output reflecting how long it took for the most recent charge.

+

A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.

+

This is designed to be used in updateControl(). Each time it is called, it checks if a capacitor has charged, and returns an output reflecting how long it took for the most recent charge.

-

Definition at line 12 of file CapPoll.h.

+

Definition at line 23 of file CapPoll.h.

@@ -129,7 +123,7 @@ - +

Public Member Functions

 Constructor.
 
unsigned int next ()
 Checks whether the capacitor has charged, and returns how long it took for the most recent charge. More...
 Checks whether the capacitor has charged, and returns how long it took for the most recent charge. More...
 

Member Function Documentation

@@ -159,9 +153,9 @@

Checks whether the capacitor has charged, and returns how long it took for the most recent charge.

-

This would preferably be called in updateControl(), but if the resolution isn't fine enough or the pin charges too fast for updateControl() to catch, try it in updateAudio().

Returns
the sensor value, reflected in how many checking cycles it took to charge the capacitor.
+

This would preferably be called in updateControl(), but if the resolution isn't fine enough or the pin charges too fast for updateControl() to catch, try it in updateAudio().

Returns
the sensor value, reflected in how many checking cycles it took to charge the capacitor.
-

Definition at line 29 of file CapPoll.h.

+

Definition at line 40 of file CapPoll.h.

@@ -171,9 +165,7 @@

    - +
diff --git a/extras/doc/html/class_circular_buffer-members.html b/extras/doc/html/class_circular_buffer-members.html index 02245fffd..a0eb93666 100644 --- a/extras/doc/html/class_circular_buffer-members.html +++ b/extras/doc/html/class_circular_buffer-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -118,9 +114,7 @@ diff --git a/extras/doc/html/class_circular_buffer.html b/extras/doc/html/class_circular_buffer.html index 98c353159..4163bb4c1 100644 --- a/extras/doc/html/class_circular_buffer.html +++ b/extras/doc/html/class_circular_buffer.html @@ -1,9 +1,9 @@ - + - + Mozzi: CircularBuffer< ITEM_TYPE > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -123,7 +119,7 @@
-

Definition at line 16 of file CircularBuffer.h.

+

Definition at line 27 of file CircularBuffer.h.

@@ -156,9 +152,7 @@ diff --git a/extras/doc/html/class_circular_buffer.js b/extras/doc/html/class_circular_buffer.js index a32b7b4b6..5361889eb 100644 --- a/extras/doc/html/class_circular_buffer.js +++ b/extras/doc/html/class_circular_buffer.js @@ -1,6 +1,7 @@ var class_circular_buffer = [ [ "CircularBuffer", "class_circular_buffer.html#a6789c0d6d73594fdd412a39445b5cd67", null ], + [ "address", "class_circular_buffer.html#a508cea340f76cea1dc993f0b5124a522", null ], [ "count", "class_circular_buffer.html#a04c3ee378688439c72760034e314eed3", null ], [ "isEmpty", "class_circular_buffer.html#ad0fa3e6277c9ab56d8bfc190b4271d41", null ], [ "isFull", "class_circular_buffer.html#a023321c0416562f30532d5c4848c383b", null ], diff --git a/extras/doc/html/class_control_delay-members.html b/extras/doc/html/class_control_delay-members.html index 7c05adb64..27ab045d5 100644 --- a/extras/doc/html/class_control_delay-members.html +++ b/extras/doc/html/class_control_delay-members.html @@ -1,9 +1,9 @@ - + - +Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@ @@ -61,10 +57,10 @@

Public Member Functions

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -106,20 +102,18 @@

This is the complete list of members for ControlDelay< NUM_BUFFER_SAMPLES, T >, including all inherited members.

- - - - - - + + + + + +
AudioDelay()AudioDelay< NUM_BUFFER_SAMPLES, T >inline
AudioDelay(unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, T >inline
next(T in_value, unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, T >inline
next(T in_value)AudioDelay< NUM_BUFFER_SAMPLES, T >inline
read(unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, T >inline
set(unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, T >inline
AudioDelay()AudioDelay< NUM_BUFFER_SAMPLES, int >inline
AudioDelay(unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, int >inline
next(int in_value, unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, int >inline
next(int in_value)AudioDelay< NUM_BUFFER_SAMPLES, int >inline
read(unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, int >inline
set(unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, int >inline
diff --git a/extras/doc/html/class_control_delay.html b/extras/doc/html/class_control_delay.html index 682f17c48..228a64654 100644 --- a/extras/doc/html/class_control_delay.html +++ b/extras/doc/html/class_control_delay.html @@ -1,9 +1,9 @@ - + - + Mozzi: ControlDelay< NUM_BUFFER_SAMPLES, T > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,8 +103,7 @@
+AudioDelay< NUM_BUFFER_SAMPLES, int > + +

Detailed Description

template<unsigned int NUM_BUFFER_SAMPLES, class T = int>
class ControlDelay< NUM_BUFFER_SAMPLES, T >

-


-Control-rate delay line for delaying control signals.

-

For example, this could be used to produce echo-like effects using multiple instances of the same voice, when AudioDelay would be too short for an actual audio echo. This is in fact just a wrapper of the AudioDelay code.

Template Parameters
+

Control-rate delay line for delaying control signals.

+

For example, this could be used to produce echo-like effects using multiple instances of the same voice, when AudioDelay would be too short for an actual audio echo. This is in fact just a wrapper of the AudioDelay code.

Template Parameters
@@ -141,47 +135,35 @@
NUM_BUFFER_SAMPLESis the length of the delay buffer in samples. This should be a power of two.
thetype of numbers to use for the signal in the delay. The default is int8_t, but int could be useful when adding manual feedback. When using int, the input should be limited to 15 bits width, ie. -16384 to 16383.
- - + + - - + + - + - - + +

Public Member Functions

next (T in_value, unsigned int delaytime_cells)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
int next (int in_value, unsigned int delaytime_cells)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
next (T in_value)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
int next (int in_value)
 Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells. More...
 
void set (unsigned int delaytime_cells)
 Set the delay time, measured in cells. More...
 Set the delay time, measured in cells. More...
 
read (unsigned int delaytime_cells)
 Retrieve the signal in the delay line at the position delaytime_cells. More...
int read (unsigned int delaytime_cells)
 Retrieve the signal in the delay line at the position delaytime_cells. More...
 

Member Function Documentation

- -

◆ next() [1/2]

+ +

◆ next() [1/2]

-
-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
@@ -195,32 +177,39 @@

Parameters

- + - - - - - - - - - - + + - -
T AudioDelay< NUM_BUFFER_SAMPLES, T >::next int AudioDelay< NUM_BUFFER_SAMPLES, int >::next (in_value,
unsigned int delaytime_cells 
int in_value) )
-
in_valuethe signal input.
delaytime_cellssets the delay time in terms of cells in the delay buffer.
-

Definition at line 59 of file AudioDelay.h.

+

Definition at line 77 of file AudioDelay.h.

- -

◆ next() [2/2]

+ +

◆ next() [2/2]

-
-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
@@ -234,11 +223,12 @@

Parameters

- + - - + + + + + + + + + + + +
T AudioDelay< NUM_BUFFER_SAMPLES, T >::next int AudioDelay< NUM_BUFFER_SAMPLES, int >::next (in_value)int in_value,
unsigned int delaytime_cells 
)
+
in_valuethe signal input.
delaytime_cellssets the delay time in terms of cells in the delay buffer.
-

Definition at line 77 of file AudioDelay.h.

+

Definition at line 59 of file AudioDelay.h.

@@ -247,14 +237,12 @@

-
-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>
- + - +
- + @@ -285,14 +273,12 @@

-
-template<unsigned int NUM_BUFFER_SAMPLES, class T = int8_t>

T AudioDelay< NUM_BUFFER_SAMPLES, T >::read int AudioDelay< NUM_BUFFER_SAMPLES, int >::read ( unsigned int  delaytime_cells)
@@ -61,10 +57,10 @@
- + @@ -324,9 +310,7 @@

    - +
diff --git a/extras/doc/html/class_control_delay.js b/extras/doc/html/class_control_delay.js index e4383d3ff..0cbad6b7a 100644 --- a/extras/doc/html/class_control_delay.js +++ b/extras/doc/html/class_control_delay.js @@ -1,7 +1,7 @@ var class_control_delay = [ - [ "next", "class_control_delay.html#a19258636609d83a2bab11849e17b5294", null ], [ "next", "class_control_delay.html#a41c09b5cc9e817d8eaf111b0f74c9a0b", null ], + [ "next", "class_control_delay.html#a19258636609d83a2bab11849e17b5294", null ], [ "read", "class_control_delay.html#a26b409fbfc322ae527ba23680c56e3a9", null ], [ "set", "class_control_delay.html#a7bd0a07f7803afda1a71b50e3f66827b", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_control_delay.png b/extras/doc/html/class_control_delay.png index a83748c2f11b5085cdbbeeda9595f7564fb882d9..277da8db78fe7d41b15fe359350178ac440afb68 100644 GIT binary patch delta 970 zcmeCJ5_g9UxqWGjquGU$Zok`ny8I$#U zexBa7E;}ps`mG36O;Nj(E|X%A@v)SNDQ_*Ue5`X%8i|3ursxvhg4IWMLl&}0RGqXad#r3$4+gFuu{;xbOX2?$Vw9Q;u;&`Lu zgo=bs`ljFYQC;C@wY;0kUcdVM)J9Tt*Ms+oJ7-$0T%D|D+Hfjm3fpI!Oraxw-`HoI zS!Oy--Dj87@0@uzq%K!o5|K$y`kE5(t>$=s$|bjoxhHqbJCdDR^SV3~MKGG-%Ic*fEKdAXQI<8ibP9;)apaQayD~2T5}~Xr*}?F&Y5v4L4#e z08t5_Vhb6wea}BGTz%%UphL#()AgGltv_q^W~yNI@ekW~>d$tK67T>1bmw-1zMFgA zu<^_=xm*9-r|0PQ-3#wun;SU$N4WfVfu^U&u6VXMKj#*{z2ogsw;K826W3!`&KCT~ zxG?vb{V|oc4=Tb6ThwRDIOdpb@5s(CmN~TG#FCaf#y73+r3GDEu{&^|y3Zp&p1u#l zJ~roq)$UzXahzeAX0%FuV||eSp@VN`_`LG;KYIE!uTNRLcm2m((a{aJ*RDQ4{qvH$ z>B-@`=E1qwB5f@X?47Ruc0t7^`vWOvYd6{?esb=8`}v62&xxM*Q{9zj$WO7o|519T z$?=~;lLKv6Zr>iOWIAusf`d9tu)2?vDwiEk{`!l1 znLliMw}thC;@=0)*81qpbiP&g{?jXczuk|X%>_j~!<<+5HZyB(>i_@% literal 1038 zcmeAS@N?(olHy`uVBq!ia0y~yU=#+j12~vLB4-l+04a$8pAgso|NjG-cb}XHjMbe0 zWP$O40|%TYH7o~mIZA^3f*F8{K;Y`B5F-W#=DD6Ojv*C{Z|A-)`mDv{I(>WkuYdhD zpRSr^6c;`^HZ$|Q#^F3JMn$nnKThvjmz@=R{Z@pkrl{RXmq{_mSa-7Pq^-vtWTXGp zo=f|_tnceVzx?%QZm_rAzgY5en(wK!iz!FCMC+svd-B|GI&y16dzc!xCvpe*??uUO+#_YBIhKBX=$x51A#AhD4oLlxi z_tDEe@^zVgcZ_ec-%AVnwqoD3{laP=)z~z3R&Go8`8E0b-xEig7wFA1ki0tC!fvIy zqM^0gy#&}&DA%wT&?~wQgXkw zqUGb=#$CDfOJ;dpeUddNQJvHBmFczl2L&ewbT;uHzV02Ab2eJX)BZ{cx92b0s)J{5 z&xmo_boX9rmwimx)w8>2{F$gRamn&s`sFGw|1V5Y@?3|E*(aCAUJv=h@Q1IKaY@6i zNt_KYUu!R9xCUZ0sw`yKs4CnL=E-tkst-fVNh(ucyJzT}-n3*|>dIbL1<}PSGZ|(8 zt<|2%umeOH{9L!AVQboxi+8m?m#_)k`u2E#=*Qb(vfobi)F%A6yJz}YwYA;H-!Hu% zEiwP*o;PYdGfWOY_vtyheRtxWZ*v1@{|MjxTd?Wru`4Gz+s}!sl@;FRm;PAmrx>5V zG|ue@KS!?de?zs89QsC#PSq1n7IvI{R`$s1))MC#A~UBbfA{&;xP9gn+gG_$pz;5Q zN!b3mrm%cQlfoJ)V~p4@VxD~WdeEM4*Tf!tdzJOSXwH`JId4`yOI&FqtQTI#g0ntxV~y!y72!D@deEOjxk*Ql<0Y;Kf!>8H@-K--n;x7#XxwNZ6& zE;?48E^_;yhiT31Dxvfno=$yLy}XyzeVkOe?0DkWU);_7VcWYctREC@3qOacP4~&& zUS9cKUT^oKXLEi2c}!uL^XlFm#vi}E)EL&KFg<`$RR)pMQaz8JuNRQA^hvVJIR?zU N44$rjF6*2UngEr*>e2uJ diff --git a/extras/doc/html/class_d_cfilter-members.html b/extras/doc/html/class_d_cfilter-members.html index 737945292..2738114ec 100644 --- a/extras/doc/html/class_d_cfilter-members.html +++ b/extras/doc/html/class_d_cfilter-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

@@ -61,10 +57,10 @@
void AudioDelay< NUM_BUFFER_SAMPLES, T >::set void AudioDelay< NUM_BUFFER_SAMPLES, int >::set ( unsigned int  delaytime_cells)
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/class_d_cfilter.html b/extras/doc/html/class_d_cfilter.html index 4784010eb..213680575 100644 --- a/extras/doc/html/class_d_cfilter.html +++ b/extras/doc/html/class_d_cfilter.html @@ -1,9 +1,9 @@ - + - + Mozzi: DCfilter Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,14 +103,12 @@
-


-A DC-blocking filter useful for highlighting changes in control signals. +

A DC-blocking filter useful for highlighting changes in control signals. More...

#include <DCfilter.h>

Detailed Description

-


-A DC-blocking filter useful for highlighting changes in control signals.

+

A DC-blocking filter useful for highlighting changes in control signals.

The output of the filter settles to 0 if the incoming signal stays constant. If the input changes, the filter output swings to track the change and eventually settles back to 0.

Definition at line 32 of file DCfilter.h.

@@ -122,12 +116,10 @@

Public Member Functions

 DCfilter (float pole)
 
-Instantiate a DC-blocking filter. More...
 Instantiate a DC-blocking filter. More...
 
int next (int x)
 
-Filter the incoming value and return the result. More...
 Filter the incoming value and return the result. More...
 

Constructor & Destructor Documentation

@@ -155,8 +147,7 @@

-


-Instantiate a DC-blocking filter.

+

Instantiate a DC-blocking filter.

Parameters
@@ -193,8 +184,7 @@

-


-Filter the incoming value and return the result.

+

Filter the incoming value and return the result.

Parameters

polesets the responsiveness of the filter, how long it takes to settle to 0 if the input signal levels out at a constant value.
@@ -213,9 +203,7 @@

    - +
diff --git a/extras/doc/html/class_ead-members.html b/extras/doc/html/class_ead-members.html index 41ba444af..fff87a854 100644 --- a/extras/doc/html/class_ead-members.html +++ b/extras/doc/html/class_ead-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

@@ -61,10 +57,10 @@
xthe value to filter
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +

- + @@ -80,7 +76,7 @@
@@ -118,9 +114,7 @@ diff --git a/extras/doc/html/class_ead.html b/extras/doc/html/class_ead.html index 9601a3ec8..101a9ea49 100644 --- a/extras/doc/html/class_ead.html +++ b/extras/doc/html/class_ead.html @@ -1,9 +1,9 @@ - + - + Mozzi: Ead Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -113,32 +109,32 @@

#include <Ead.h>

Detailed Description

Exponential attack decay envelope.

-

This produces a natural sounding envelope. It calculates a new value each time next() is called, which can be mapped to other parameters to change the amplitude or timbre of a sound.

Note
Currently doesn't work at audio rate... may need larger number types for Q8n8attack and Q8n8decay ?
+

This produces a natural sounding envelope. It calculates a new value each time next() is called, which can be mapped to other parameters to change the amplitude or timbre of a sound.

Note
Currently doesn't work at audio rate... may need larger number types for Q8n8attack and Q8n8decay ?
-

Definition at line 29 of file Ead.h.

+

Definition at line 30 of file Ead.h.

- + - + - + - + - + - + - +

Public Member Functions

 Ead (unsigned int update_rate)
 Constructor. More...
 Constructor. More...
 
void setAttack (unsigned int attack_ms)
 Set the attack time in milliseconds. More...
 Set the attack time in milliseconds. More...
 
void setDecay (unsigned int decay_ms)
 Set the decay time in milliseconds. More...
 Set the decay time in milliseconds. More...
 
void set (unsigned int attack_ms, unsigned int decay_ms)
 Set attack and decay times in milliseconds. More...
 Set attack and decay times in milliseconds. More...
 
void start ()
 Start the envelope from the beginning. More...
 Start the envelope from the beginning. More...
 
void start (unsigned int attack_ms, unsigned int decay_ms)
 Set attack and decay times in milliseconds, and start the envelope from the beginning. More...
 Set attack and decay times in milliseconds, and start the envelope from the beginning. More...
 
uint8_t next ()
 Calculate and return the next envelope value, in the range -128 to 127. More...
 Calculate and return the next envelope value, in the range -128 to 127. More...
 

Constructor & Destructor Documentation

@@ -169,12 +165,12 @@

Parameters
- +
update_rateUsually this will be MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE, unless you design another scheme for updating. One such alternative scheme could take turns for various control changes in a rotating schedule to spread out calculations made in successive updateControl() routines.
update_rateUsually this will be MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE, unless you design another scheme for updating. One such alternative scheme could take turns for various control changes in a rotating schedule to spread out calculations made in successive updateControl() routines.

-

Definition at line 41 of file Ead.h.

+

Definition at line 42 of file Ead.h.

@@ -205,7 +201,7 @@

Note
Timing: 5us
-

Definition at line 114 of file Ead.h.

+

Definition at line 115 of file Ead.h.

@@ -246,13 +242,13 @@

Parameters
- - + +
attack_msThe time taken for values returned by successive calls of the next() method to change from 0 to 255.
decay_msThe time taken for values returned by successive calls of the next() method to change from 255 to 0.
attack_msThe time taken for values returned by successive calls of the next() method to change from 0 to 255.
decay_msThe time taken for values returned by successive calls of the next() method to change from 255 to 0.
-

Definition at line 75 of file Ead.h.

+

Definition at line 76 of file Ead.h.

@@ -283,12 +279,12 @@

Parameters
- +
attack_msThe time taken for values returned by successive calls of the next() method to change from 0 to 255.
attack_msThe time taken for values returned by successive calls of the next() method to change from 0 to 255.
-

Definition at line 51 of file Ead.h.

+

Definition at line 52 of file Ead.h.

@@ -319,12 +315,12 @@

Parameters
- +
decay_msThe time taken for values returned by successive calls of the next() method to change from 255 to 0.
decay_msThe time taken for values returned by successive calls of the next() method to change from 255 to 0.
-

Definition at line 62 of file Ead.h.

+

Definition at line 63 of file Ead.h.

@@ -354,7 +350,7 @@

Definition at line 86 of file Ead.h.

+

Definition at line 87 of file Ead.h.

@@ -395,13 +391,13 @@

Parameters
- - + +
attack_msThe time taken for values returned by successive calls of the next() method to change from 0 to 255.
decay_msThe time taken for values returned by successive calls of the next() method to change from 255 to 0.
attack_msThe time taken for values returned by successive calls of the next() method to change from 0 to 255.
decay_msThe time taken for values returned by successive calls of the next() method to change from 255 to 0.
-

Definition at line 101 of file Ead.h.

+

Definition at line 102 of file Ead.h.

@@ -411,9 +407,7 @@

    - +
diff --git a/extras/doc/html/class_event_delay-members.html b/extras/doc/html/class_event_delay-members.html index 16b97fb5f..4bd301d1d 100644 --- a/extras/doc/html/class_event_delay-members.html +++ b/extras/doc/html/class_event_delay-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -118,9 +114,7 @@ diff --git a/extras/doc/html/class_event_delay.html b/extras/doc/html/class_event_delay.html index 73899d5ab..a691e002c 100644 --- a/extras/doc/html/class_event_delay.html +++ b/extras/doc/html/class_event_delay.html @@ -1,9 +1,9 @@ - + - + Mozzi: EventDelay Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -120,32 +116,32 @@
-Metronome - -
+Metronome + +

Detailed Description

A non-blocking replacement for Arduino's delay() function.

-

EventDelay can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
-Alternatively, start(milliseconds) will call set() and start() together.

+

EventDelay can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
+ Alternatively, start(milliseconds) will call set() and start() together.

Definition at line 20 of file EventDelay.h.

- + - + - + - + - +

Public Member Functions

 EventDelay (unsigned int delay_milliseconds=0)
 Constructor. More...
 Constructor. More...
 
void set (unsigned int delay_milliseconds)
 Set the delay time. More...
 Set the delay time. More...
 
void start ()
 Start the delay. More...
 Start the delay. More...
 
void start (unsigned int delay_milliseconds)
 Set the delay time and start the delay. More...
 Set the delay time and start the delay. More...
 
bool ready ()
 Call this in updateControl() or updateAudio() to check if the delay time is up. More...
 Call this in updateControl() or updateAudio() to check if the delay time is up. More...
 
@@ -61,10 +57,10 @@

@@ -183,9 +179,9 @@

Constructor.

-

Declare an EventDelay object.

Parameters
+

Declare an EventDelay object.

Parameters
- +
delay_millisecondshow long until ready() returns true, after calling start(). Defaults to 0 if no parameter is supplied.
delay_millisecondshow long until ready() returns true, after calling start(). Defaults to 0 if no parameter is supplied.
@@ -218,7 +214,7 @@

-

Call this in updateControl() or updateAudio() to check if the delay time is up.

+

Call this in updateControl() or updateAudio() to check if the delay time is up.

Returns
true if the time is up.
Note
timing: 1us.
@@ -251,7 +247,7 @@

Set the delay time.

-

This setting is persistent, until you change it by using set() again.

Parameters
+

This setting is persistent, until you change it by using set() again.

Parameters
delay_millisecondsdelay time in milliseconds.
@@ -334,9 +330,7 @@

    - +
diff --git a/extras/doc/html/class_int_map-members.html b/extras/doc/html/class_int_map-members.html index 7b3d242f7..ef1271fd3 100644 --- a/extras/doc/html/class_int_map-members.html +++ b/extras/doc/html/class_int_map-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/class_int_map.html b/extras/doc/html/class_int_map.html index 50b7d34ae..2c642e029 100644 --- a/extras/doc/html/class_int_map.html +++ b/extras/doc/html/class_int_map.html @@ -1,9 +1,9 @@ - + - + Mozzi: IntMap Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -115,15 +111,15 @@ - + - +

Public Member Functions

 IntMap (int in_min, int in_max, int out_min, int out_max)
 Constructor. More...
 Constructor. More...
 
int operator() (int n) const
 Process the next input value. More...
 Process the next input value. More...
 

Constructor & Destructor Documentation

@@ -184,7 +180,7 @@

Definition at line 27 of file IntMap.h.

+

Definition at line 28 of file IntMap.h.

@@ -222,7 +218,7 @@

Returns
the input integer mapped to the output range.

-

Definition at line 38 of file IntMap.h.

+

Definition at line 39 of file IntMap.h.

@@ -232,9 +228,7 @@

    - +
diff --git a/extras/doc/html/class_line-members.html b/extras/doc/html/class_line-members.html index 4c4817bdb..c810eb96e 100644 --- a/extras/doc/html/class_line-members.html +++ b/extras/doc/html/class_line-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_line.html b/extras/doc/html/class_line.html index 1491c9c6a..226caef98 100644 --- a/extras/doc/html/class_line.html +++ b/extras/doc/html/class_line.html @@ -1,9 +1,9 @@ - + - + Mozzi: Line< T > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -116,32 +112,32 @@ class Line< T >

For linear changes with a minimum of calculation at each step.

-

For instance, you can use Line to make an oscillator glide from one frequency to another, pre-calculating the required phase increments for each end and then letting your Line change the phase increment with only a simple addition at each step.

Template Parameters
+

For instance, you can use Line to make an oscillator glide from one frequency to another, pre-calculating the required phase increments for each end and then letting your Line change the phase increment with only a simple addition at each step.

Template Parameters
- +
Tthe type of numbers to use. For example, Line <int> myline; makes a Line which uses ints.
Tthe type of numbers to use. For example, Line <int> myline; makes a Line which uses ints.
-
Note
Watch out for underflows in the internal calcualtion of Line() if you're not using floats (but on the other hand try to avoid lots of floats, they're too slow!). If it seems like the Line() is not working, there's a good chance you need to scale up the numbers you're using, so internal calculations don't get truncated away. Use Mozzi's fixed-point number types in mozzi_fixmath.h, which enable you to represent fractional numbers. Google "fixed point arithmetic" if this is new to you.
+
Note
Watch out for underflows in the internal calcualtion of Line() if you're not using floats (but on the other hand try to avoid lots of floats, they're too slow!). If it seems like the Line() is not working, there's a good chance you need to scale up the numbers you're using, so internal calculations don't get truncated away. Use Mozzi's fixed-point number types in mozzi_fixmath.h, which enable you to represent fractional numbers. Google "fixed point arithmetic" if this is new to you.
-

Definition at line 33 of file Line.h.

+

Definition at line 39 of file Line.h.

- + - + - + - + - +

Public Member Functions

 Line ()
 Constructor. More...
 Constructor. More...
 
next ()
 Increments one step along the line. More...
 Increments one step along the line. More...
 
void set (T value)
 Set the current value of the line. More...
 Set the current value of the line. More...
 
void set (T targetvalue, T num_steps)
 Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. More...
 Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. More...
 
void set (T startvalue, T targetvalue, T num_steps)
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 

Constructor & Destructor Documentation

@@ -151,7 +147,7 @@

-template<class T>
+template<class T >
@@ -61,10 +57,10 @@
@@ -171,9 +167,9 @@

Constructor.

-

Use the template parameter to set the type of numbers you want to use. For example, Line <int> myline; makes a Line which uses ints.

+

Use the template parameter to set the type of numbers you want to use. For example, Line <int> myline; makes a Line which uses ints.

-

Definition at line 43 of file Line.h.

+

Definition at line 49 of file Line.h.

@@ -184,7 +180,7 @@

-template<class T>
+template<class T >
@@ -236,15 +248,17 @@

-

Set the current value of the line.

-

The Line will continue incrementing from this value using any previously calculated step size.

Parameters
+

Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.

+
Parameters

@@ -206,17 +202,17 @@

Returns
the next value.
-

Definition at line 54 of file Line.h.

+

Definition at line 60 of file Line.h.

- -

◆ set() [1/3]

+ +

◆ set() [1/3]

-template<class T>
+template<class T >
- + + + + + + + + + + + + + + + + +
@@ -225,8 +221,24 @@

void Line< T >::set

( value)startvalue,
targetvalue,
num_steps 
)

- + + +
valuethe number to set the Line's current_value to.
startvaluethe number to set the Line's current_value to.
targetvaluethe value to move towards.
num_stepshow many steps to take to reach the target.
-

Definition at line 69 of file Line.h.

+

Definition at line 104 of file Line.h.

@@ -254,7 +268,7 @@

-template<class T>
+template<class T >
@@ -339,17 +337,15 @@

-

Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.

-
Parameters
+

Set the current value of the line.

+

The Line will continue incrementing from this value using any previously calculated step size.

Parameters

@@ -293,17 +307,17 @@

Definition at line 81 of file Line.h.

+

Definition at line 87 of file Line.h.

- -

◆ set() [3/3]

+ +

◆ set() [3/3]

-template<class T>
+template<class T >
- - - - - - - - - - - - - - - + - -
@@ -312,24 +326,8 @@

void Line< T >::set

( startvalue,
targetvalue,
num_steps 
value) )

- - - +
startvaluethe number to set the Line's current_value to.
targetvaluethe value to move towards.
num_stepshow many steps to take to reach the target.
valuethe number to set the Line's current_value to.
-

Definition at line 98 of file Line.h.

+

Definition at line 75 of file Line.h.

@@ -359,9 +355,7 @@

    - +
diff --git a/extras/doc/html/class_line.js b/extras/doc/html/class_line.js index abc36c496..b94afce48 100644 --- a/extras/doc/html/class_line.js +++ b/extras/doc/html/class_line.js @@ -2,7 +2,7 @@ var class_line = [ [ "Line", "class_line.html#aa6a80df90da15782ca88889ef9c8dd51", null ], [ "next", "class_line.html#a413f620b2824c6996b3346ee54351849", null ], - [ "set", "class_line.html#a6bad32d527e0d931c99e9b72c2a75c80", null ], + [ "set", "class_line.html#a24ad85c17562e97b6823a010a5ba04c6", null ], [ "set", "class_line.html#a7378d526cf07c42c0792868c749dee6e", null ], - [ "set", "class_line.html#a24ad85c17562e97b6823a010a5ba04c6", null ] + [ "set", "class_line.html#a6bad32d527e0d931c99e9b72c2a75c80", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_line_3_01unsigned_01char_01_4-members.html b/extras/doc/html/class_line_3_01unsigned_01char_01_4-members.html index 67da67838..67e079060 100644 --- a/extras/doc/html/class_line_3_01unsigned_01char_01_4-members.html +++ b/extras/doc/html/class_line_3_01unsigned_01char_01_4-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_line_3_01unsigned_01char_01_4.html b/extras/doc/html/class_line_3_01unsigned_01char_01_4.html index a55eb6eda..a72d89c0c 100644 --- a/extras/doc/html/class_line_3_01unsigned_01char_01_4.html +++ b/extras/doc/html/class_line_3_01unsigned_01char_01_4.html @@ -1,11 +1,11 @@ - + - + -Mozzi: Line< unsigned char > Class Template Reference +Mozzi: Line< unsigned char > Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
-
Line< unsigned char > Class Template Reference
+
Line< unsigned char > Class Reference

Detailed Description

-

template<>
-class Line< unsigned char >

- - -

Definition at line 108 of file Line.h.

+
+

Definition at line 114 of file Line.h.

- + - + - + - + - +

Public Member Functions

 Line ()
 Constructor. More...
 Constructor. More...
 
unsigned char next ()
 Increments one step along the line. More...
 Increments one step along the line. More...
 
void set (unsigned char value)
 Set the current value of the line. More...
 Set the current value of the line. More...
 
void set (unsigned char targetvalue, unsigned char num_steps)
 Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. More...
 Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. More...
 
void set (unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 

Constructor & Destructor Documentation

@@ -156,9 +149,9 @@

Constructor.

-

Use the template parameter to set the type of numbers you want to use. For example, Line <int> myline; makes a Line which uses ints.

+

Use the template parameter to set the type of numbers you want to use. For example, Line <int> myline; makes a Line which uses ints.

-

Definition at line 118 of file Line.h.

+

Definition at line 124 of file Line.h.

@@ -189,12 +182,12 @@

Returns
the next value.
-

Definition at line 129 of file Line.h.

+

Definition at line 135 of file Line.h.

- -

◆ set() [1/3]

+ +

◆ set() [1/3]

@@ -206,8 +199,24 @@

void Line< unsigned char >::set

( unsigned char value)startvalue,
unsigned char targetvalue,
unsigned char num_steps 
)
@@ -217,15 +226,17 @@

-

Set the current value of the line.

-

The Line will continue incrementing from this value using any previously calculated step size.

Parameters
+

Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.

+
Parameters
- + + +
valuethe number to set the Line's current_value to.
startvaluethe number to set the Line's current_value to.
targetvaluethe value to move towards.
num_stepshow many steps to take to reach the target.
-

Definition at line 143 of file Line.h.

+

Definition at line 172 of file Line.h.

@@ -272,12 +283,12 @@

Definition at line 155 of file Line.h.

+

Definition at line 161 of file Line.h.

- -

◆ set() [3/3]

+ +

◆ set() [3/3]

@@ -289,24 +300,8 @@

void Line< unsigned char >::set ( unsigned char  - startvalue, - - - - - unsigned char  - targetvalue, - - - + value) - unsigned char  - num_steps  - - - - ) - @@ -316,17 +311,15 @@

-

Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.

-
Parameters
+

Set the current value of the line.

+

The Line will continue incrementing from this value using any previously calculated step size.

Parameters
- - - +
startvaluethe number to set the Line's current_value to.
targetvaluethe value to move towards.
num_stepshow many steps to take to reach the target.
valuethe number to set the Line's current_value to.
-

Definition at line 166 of file Line.h.

+

Definition at line 149 of file Line.h.

@@ -336,9 +329,7 @@

    - +
diff --git a/extras/doc/html/class_line_3_01unsigned_01char_01_4.js b/extras/doc/html/class_line_3_01unsigned_01char_01_4.js index 82d0645f8..87e6204a4 100644 --- a/extras/doc/html/class_line_3_01unsigned_01char_01_4.js +++ b/extras/doc/html/class_line_3_01unsigned_01char_01_4.js @@ -2,7 +2,7 @@ var class_line_3_01unsigned_01char_01_4 = [ [ "Line", "class_line_3_01unsigned_01char_01_4.html#a151189139ee6ed39bacec86ea2364124", null ], [ "next", "class_line_3_01unsigned_01char_01_4.html#ad33f421ca975cb6b175a1c1f3ba0b68a", null ], - [ "set", "class_line_3_01unsigned_01char_01_4.html#a6129febcfd57d32a5c771c8f730b6b7a", null ], + [ "set", "class_line_3_01unsigned_01char_01_4.html#ad14e98651035d75c89270c6f0d5e5c46", null ], [ "set", "class_line_3_01unsigned_01char_01_4.html#a2b90896c1357a45daca74498f17b4909", null ], - [ "set", "class_line_3_01unsigned_01char_01_4.html#ad14e98651035d75c89270c6f0d5e5c46", null ] + [ "set", "class_line_3_01unsigned_01char_01_4.html#a6129febcfd57d32a5c771c8f730b6b7a", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_line_3_01unsigned_01int_01_4-members.html b/extras/doc/html/class_line_3_01unsigned_01int_01_4-members.html index 5be1d822a..16928d742 100644 --- a/extras/doc/html/class_line_3_01unsigned_01int_01_4-members.html +++ b/extras/doc/html/class_line_3_01unsigned_01int_01_4-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_line_3_01unsigned_01int_01_4.html b/extras/doc/html/class_line_3_01unsigned_01int_01_4.html index b9e318e9e..53caf079e 100644 --- a/extras/doc/html/class_line_3_01unsigned_01int_01_4.html +++ b/extras/doc/html/class_line_3_01unsigned_01int_01_4.html @@ -1,11 +1,11 @@ - + - + -Mozzi: Line< unsigned int > Class Template Reference +Mozzi: Line< unsigned int > Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
-
Line< unsigned int > Class Template Reference
+
Line< unsigned int > Class Reference

Detailed Description

-

template<>
-class Line< unsigned int >

- - -

Definition at line 177 of file Line.h.

+
+

Definition at line 183 of file Line.h.

- + - + - + - + - +

Public Member Functions

 Line ()
 Constructor. More...
 Constructor. More...
 
unsigned int next ()
 Increments one step along the line. More...
 Increments one step along the line. More...
 
void set (unsigned int value)
 Set the current value of the line. More...
 Set the current value of the line. More...
 
void set (unsigned int targetvalue, unsigned int num_steps)
 Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. More...
 Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. More...
 
void set (unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 

Constructor & Destructor Documentation

@@ -156,9 +149,9 @@

Constructor.

-

Use the template parameter to set the type of numbers you want to use. For example, Line <int> myline; makes a Line which uses ints.

+

Use the template parameter to set the type of numbers you want to use. For example, Line <int> myline; makes a Line which uses ints.

-

Definition at line 187 of file Line.h.

+

Definition at line 193 of file Line.h.

@@ -189,12 +182,12 @@

Returns
the next value.
-

Definition at line 198 of file Line.h.

+

Definition at line 204 of file Line.h.

- -

◆ set() [1/3]

+ +

◆ set() [1/3]

@@ -206,8 +199,24 @@

void Line< unsigned int >::set ( unsigned int  - value) + startvalue, + + + + unsigned int  + targetvalue, + + + + + unsigned int  + num_steps  + + + + ) + @@ -217,15 +226,17 @@

-

Set the current value of the line.

-

The Line will continue incrementing from this value using any previously calculated step size.

Parameters
+

Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.

+
Parameters
- + + +
valuethe number to set the Line's current_value to.
startvaluethe number to set the Line's current_value to.
targetvaluethe value to move towards.
num_stepshow many steps to take to reach the target.
-

Definition at line 212 of file Line.h.

+

Definition at line 242 of file Line.h.

@@ -272,12 +283,12 @@

Definition at line 224 of file Line.h.

+

Definition at line 230 of file Line.h.

- -

◆ set() [3/3]

+ +

◆ set() [3/3]

@@ -289,24 +300,8 @@

void Line< unsigned int >::set ( unsigned int  - startvalue, - - - - - unsigned int  - targetvalue, - - - + value) - unsigned int  - num_steps  - - - - ) - @@ -316,17 +311,15 @@

-

Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.

-
Parameters
+

Set the current value of the line.

+

The Line will continue incrementing from this value using any previously calculated step size.

Parameters
- - - +
startvaluethe number to set the Line's current_value to.
targetvaluethe value to move towards.
num_stepshow many steps to take to reach the target.
valuethe number to set the Line's current_value to.
-

Definition at line 236 of file Line.h.

+

Definition at line 218 of file Line.h.

@@ -336,9 +329,7 @@

    - +
diff --git a/extras/doc/html/class_line_3_01unsigned_01int_01_4.js b/extras/doc/html/class_line_3_01unsigned_01int_01_4.js index 711e102a2..eb135fa69 100644 --- a/extras/doc/html/class_line_3_01unsigned_01int_01_4.js +++ b/extras/doc/html/class_line_3_01unsigned_01int_01_4.js @@ -2,7 +2,7 @@ var class_line_3_01unsigned_01int_01_4 = [ [ "Line", "class_line_3_01unsigned_01int_01_4.html#a32c77e9442a640df179ec4573e8fea6d", null ], [ "next", "class_line_3_01unsigned_01int_01_4.html#a4bf1b56d036097ecc3e28d52ef129ade", null ], - [ "set", "class_line_3_01unsigned_01int_01_4.html#a157b1887464b81ed8388a8f73173338d", null ], + [ "set", "class_line_3_01unsigned_01int_01_4.html#a1677277eb5f3eb56e47a6e7dde0c1558", null ], [ "set", "class_line_3_01unsigned_01int_01_4.html#a002bf2ae8e48467fd2d45072b8328e65", null ], - [ "set", "class_line_3_01unsigned_01int_01_4.html#a1677277eb5f3eb56e47a6e7dde0c1558", null ] + [ "set", "class_line_3_01unsigned_01int_01_4.html#a157b1887464b81ed8388a8f73173338d", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_line_3_01unsigned_01long_01_4-members.html b/extras/doc/html/class_line_3_01unsigned_01long_01_4-members.html index a65c6b434..a858e2509 100644 --- a/extras/doc/html/class_line_3_01unsigned_01long_01_4-members.html +++ b/extras/doc/html/class_line_3_01unsigned_01long_01_4-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_line_3_01unsigned_01long_01_4.html b/extras/doc/html/class_line_3_01unsigned_01long_01_4.html index 6b53e3cd6..6e9cbb569 100644 --- a/extras/doc/html/class_line_3_01unsigned_01long_01_4.html +++ b/extras/doc/html/class_line_3_01unsigned_01long_01_4.html @@ -1,11 +1,11 @@ - + - + -Mozzi: Line< unsigned long > Class Template Reference +Mozzi: Line< unsigned long > Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
-
Line< unsigned long > Class Template Reference
+
Line< unsigned long > Class Reference

Detailed Description

-

template<>
-class Line< unsigned long >

- - -

Definition at line 249 of file Line.h.

+
+

Definition at line 255 of file Line.h.

- + - + - + - + - +

Public Member Functions

 Line ()
 Constructor. More...
 Constructor. More...
 
unsigned long next ()
 Increments one step along the line. More...
 Increments one step along the line. More...
 
void set (unsigned long value)
 Set the current value of the line. More...
 Set the current value of the line. More...
 
void set (unsigned long targetvalue, unsigned long num_steps)
 Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. More...
 Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value. More...
 
void set (unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there. More...
 

Constructor & Destructor Documentation

@@ -156,9 +149,9 @@

Constructor.

-

Use the template parameter to set the type of numbers you want to use. For example, Line <int> myline; makes a Line which uses ints.

+

Use the template parameter to set the type of numbers you want to use. For example, Line <int> myline; makes a Line which uses ints.

-

Definition at line 259 of file Line.h.

+

Definition at line 265 of file Line.h.

@@ -189,12 +182,12 @@

Returns
the next value.
-

Definition at line 270 of file Line.h.

+

Definition at line 276 of file Line.h.

- -

◆ set() [1/3]

+ +

◆ set() [1/3]

@@ -206,8 +199,24 @@

void Line< unsigned long >::set ( unsigned long  - value) + startvalue, + + + + unsigned long  + targetvalue, + + + + + unsigned long  + num_steps  + + + + ) + @@ -217,15 +226,17 @@

-

Set the current value of the line.

-

The Line will continue incrementing from this value using any previously calculated step size.

Parameters
+

Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.

+
Parameters
- + + +
valuethe number to set the Line's current_value to.
startvaluethe number to set the Line's current_value to.
targetvaluethe value to move towards.
num_stepshow many steps to take to reach the target.
-

Definition at line 284 of file Line.h.

+

Definition at line 313 of file Line.h.

@@ -272,12 +283,12 @@

Definition at line 296 of file Line.h.

+

Definition at line 302 of file Line.h.

- -

◆ set() [3/3]

+ +

◆ set() [3/3]

@@ -289,24 +300,8 @@

void Line< unsigned long >::set ( unsigned long  - startvalue, - - - - - unsigned long  - targetvalue, - - - + value) - unsigned long  - num_steps  - - - - ) - @@ -316,17 +311,15 @@

-

Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.

-
Parameters
+

Set the current value of the line.

+

The Line will continue incrementing from this value using any previously calculated step size.

Parameters
- - - +
startvaluethe number to set the Line's current_value to.
targetvaluethe value to move towards.
num_stepshow many steps to take to reach the target.
valuethe number to set the Line's current_value to.
-

Definition at line 307 of file Line.h.

+

Definition at line 290 of file Line.h.

@@ -336,9 +329,7 @@

    - +
diff --git a/extras/doc/html/class_line_3_01unsigned_01long_01_4.js b/extras/doc/html/class_line_3_01unsigned_01long_01_4.js index c5bb35617..a8e98ed7c 100644 --- a/extras/doc/html/class_line_3_01unsigned_01long_01_4.js +++ b/extras/doc/html/class_line_3_01unsigned_01long_01_4.js @@ -2,7 +2,7 @@ var class_line_3_01unsigned_01long_01_4 = [ [ "Line", "class_line_3_01unsigned_01long_01_4.html#a797b2ebfe450971b6e75c26b1e6c88da", null ], [ "next", "class_line_3_01unsigned_01long_01_4.html#a69f39cf62a30d001d50daf82f45f191b", null ], - [ "set", "class_line_3_01unsigned_01long_01_4.html#abb246fabacbefbd6d88ddce719f74b0e", null ], + [ "set", "class_line_3_01unsigned_01long_01_4.html#a199dd187d87c9941515b21aea0c52a0f", null ], [ "set", "class_line_3_01unsigned_01long_01_4.html#abb89855ea745a453262cd2aeb31e2ec7", null ], - [ "set", "class_line_3_01unsigned_01long_01_4.html#a199dd187d87c9941515b21aea0c52a0f", null ] + [ "set", "class_line_3_01unsigned_01long_01_4.html#abb246fabacbefbd6d88ddce719f74b0e", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_meta_oscil-members.html b/extras/doc/html/class_meta_oscil-members.html index 760f7bdf7..65acc41dd 100644 --- a/extras/doc/html/class_meta_oscil-members.html +++ b/extras/doc/html/class_meta_oscil-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -131,9 +127,7 @@ diff --git a/extras/doc/html/class_meta_oscil.html b/extras/doc/html/class_meta_oscil.html index 56a7213e6..3e729fa99 100644 --- a/extras/doc/html/class_meta_oscil.html +++ b/extras/doc/html/class_meta_oscil.html @@ -1,9 +1,9 @@ - + - + Mozzi: MetaOscil< NUM_TABLE_CELLS, UPDATE_RATE, N_OSCIL > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -107,7 +103,7 @@
-

MetaOscil is a wrapper for several Oscil. +

MetaOscil is a wrapper for several Oscil. More...

#include <MetaOscil.h>

@@ -115,72 +111,72 @@

template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE, byte N_OSCIL>
class MetaOscil< NUM_TABLE_CELLS, UPDATE_RATE, N_OSCIL >

-

MetaOscil is a wrapper for several Oscil.

-

Once constructed it will behave exactly as an Oscil except that it will automatically switch between Oscil depending on the asked frequency. This allows to produce non-aliased sounds by switching between tables with less and less harmonics as the frequency increases.

+

MetaOscil is a wrapper for several Oscil.

+

Once constructed it will behave exactly as an Oscil except that it will automatically switch between Oscil depending on the asked frequency. This allows to produce non-aliased sounds by switching between tables with less and less harmonics as the frequency increases.

-

Definition at line 25 of file MetaOscil.h.

+

Definition at line 31 of file MetaOscil.h.

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +

Public Member Functions

template<class... T>
 MetaOscil (Oscil< NUM_TABLE_CELLS, UPDATE_RATE > *first, T *... elements)
 Constructor Declare a MetaOscil containing any number of Oscil pointers. More...
 Constructor Declare a MetaOscil containing any number of Oscil pointers. More...
 
template<typename ... T>
void setOscils (Oscil< NUM_TABLE_CELLS, UPDATE_RATE > *first, T... elements)
 Set all Oscil of a MetaOscil. More...
 Set all Oscil of a MetaOscil. More...
 
void setOscils ()
 
template<typename ... T>
void setCutoffFreqs (int first, T... elements)
 Set all the cutoff frequencies for changing between Oscil. More...
 Set all the cutoff frequencies for changing between Oscil. More...
 
void setCutoffFreqs ()
 
void setCutoffFreq (int freq, byte rank)
 Set or change the cutoff frequency of one Oscil. More...
 Set or change the cutoff frequency of one Oscil. More...
 
int8_t next ()
 Updates the phase according to the current frequency and returns the sample at the new phase position. More...
 Updates the phase according to the current frequency and returns the sample at the new phase position. More...
 
void setTable (const int8_t *TABLE_NAME, byte rank)
 Change the sound table which will be played by the Oscil of rank. More...
 Change the sound table which will be played by the Oscil of rank. More...
 
void setPhase (unsigned int phase)
 Set the phase of the currently playing Oscil. More...
 Set the phase of the currently playing Oscil. More...
 
void setPhaseFractional (unsigned long phase)
 Set the phase of the currently playing Oscil in fractional format. More...
 Set the phase of the currently playing Oscil in fractional format. More...
 
unsigned long getPhaseFractional ()
 Get the phase of the currently playin Oscil in fractional format. More...
 Get the phase of the currently playin Oscil in fractional format. More...
 
int8_t phMod (Q15n16 phmod_proportion)
 Returns the next sample given a phase modulation value. More...
 Returns the next sample given a phase modulation value. More...
 
void setFreq (int frequency, bool apply=true)
 Set the MetaOsc frequency with an unsigned int. More...
 Set the MetaOsc frequency with an unsigned int. More...
 
void setFreq (float frequency)
 Set the MetaOsc frequency with a float. More...
 Set the MetaOsc frequency with a float. More...
 
void setFreq_Q24n8 (Q24n8 frequency)
 Set the MetaOsc frequency with a Q24n8 fixed-point number format. More...
 Set the MetaOsc frequency with a Q24n8 fixed-point number format. More...
 
void setFreq_Q16n16 (Q16n16 frequency)
 Set the MetaOsc frequency with a Q16n16 fixed-point number format. More...
 Set the MetaOsc frequency with a Q16n16 fixed-point number format. More...
 
int8_t atIndex (unsigned int index)
 Returns the sample at the given table index of the current Oscil. More...
 Returns the sample at the given table index of the current Oscil. More...
 
unsigned long phaseIncFromFreq (int frequency)
 phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
 phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
 
void setPhaseInc (unsigned long phaseinc_fractional)
 Set a specific phase increment. More...
 Set a specific phase increment. More...
 

Constructor & Destructor Documentation

@@ -222,15 +218,15 @@

-

Constructor Declare a MetaOscil containing any number of Oscil pointers.

-

Every Oscil should have the same TABLE_NUM_CELLS and UPDATE_RATE which are also passed in the MetaOscil constructor.

Parameters
+

Constructor Declare a MetaOscil containing any number of Oscil pointers.

+

Every Oscil should have the same TABLE_NUM_CELLS and UPDATE_RATE which are also passed in the MetaOscil constructor.

Parameters
- +
N_OSCILis the number of Oscil contained in the MetaOscil. This cannot be changed after construction.
N_OSCILis the number of Oscil contained in the MetaOscil. This cannot be changed after construction.
-

Definition at line 32 of file MetaOscil.h.

+

Definition at line 38 of file MetaOscil.h.

@@ -261,7 +257,7 @@

-

Returns the sample at the given table index of the current Oscil.

+

Returns the sample at the given table index of the current Oscil.

Parameters
@@ -270,7 +266,7 @@

Returns
the sample at the given table index.
-

Definition at line 197 of file MetaOscil.h.

+

Definition at line 203 of file MetaOscil.h.

@@ -299,10 +295,10 @@

-

Get the phase of the currently playin Oscil in fractional format.

+

Get the phase of the currently playin Oscil in fractional format.

Returns
position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
-

Definition at line 108 of file MetaOscil.h.

+

Definition at line 114 of file MetaOscil.h.

@@ -334,7 +330,7 @@

Returns
the next sample.
-

Definition at line 87 of file MetaOscil.h.

+

Definition at line 93 of file MetaOscil.h.

@@ -364,7 +360,7 @@

-

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

+

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

Parameters

indexbetween 0 and the table size.The index rolls back around to 0 if it's larger than the table size.
@@ -373,7 +369,7 @@

Returns
the phase increment value which will produce a given frequency.
-

Definition at line 204 of file MetaOscil.h.

+

Definition at line 210 of file MetaOscil.h.

@@ -412,7 +408,7 @@

Returns
a sample from the table.
-

Definition at line 119 of file MetaOscil.h.

+

Definition at line 125 of file MetaOscil.h.

@@ -452,16 +448,16 @@

-

Set or change the cutoff frequency of one Oscil.

+

Set or change the cutoff frequency of one Oscil.

Parameters

frequencyfor which you want to calculate a phase increment value.
- +
rankis the rank of the Oscil.
rankis the rank of the Oscil.
freqis the cutoff frequency.
-

Definition at line 78 of file MetaOscil.h.

+

Definition at line 84 of file MetaOscil.h.

@@ -503,20 +499,20 @@

-

Set all the cutoff frequencies for changing between Oscil.

-

They have to be sorted in increasing values and contain at least N_OSCIL-1 values. Note that the last Oscil will be used by default for frequencies higher than the higher cutoff, hence the last value can be discarded.

Parameters
+

Set all the cutoff frequencies for changing between Oscil.

+

They have to be sorted in increasing values and contain at least N_OSCIL-1 values. Note that the last Oscil will be used by default for frequencies higher than the higher cutoff, hence the last value can be discarded.

Parameters
first,elements...a set of int cutoff frequencies.
-

Definition at line 65 of file MetaOscil.h.

+

Definition at line 71 of file MetaOscil.h.

- -

◆ setFreq() [1/2]

+ +

◆ setFreq() [1/2]

@@ -753,7 +749,7 @@

-

Set the phase of the currently playing Oscil.

+

Set the phase of the currently playing Oscil.

Parameters
@@ -761,7 +757,7 @@

Definition at line 97 of file MetaOscil.h.

+

Definition at line 103 of file MetaOscil.h.

@@ -791,7 +787,7 @@

-

Set the phase of the currently playing Oscil in fractional format.

+

Set the phase of the currently playing Oscil in fractional format.

Parameters

phasea position in the wavetable.
@@ -799,7 +795,7 @@

Definition at line 102 of file MetaOscil.h.

+

Definition at line 108 of file MetaOscil.h.

@@ -832,12 +828,12 @@

Parameters

phasea position in the wavetable.
- +
phaseinc_fractionala phase increment value as calculated by phaseIncFromFreq().
phaseinc_fractionala phase increment value as calculated by phaseIncFromFreq().
-

Definition at line 210 of file MetaOscil.h.

+

Definition at line 216 of file MetaOscil.h.

@@ -877,16 +873,16 @@

-

Change the sound table which will be played by the Oscil of rank.

+

Change the sound table which will be played by the Oscil of rank.

Parameters
- +
TABLE_NAMEis the name of the array in the table ".h" file you're using.
rankis the Oscil.
rankis the Oscil.
-

Definition at line 92 of file MetaOscil.h.

+

Definition at line 98 of file MetaOscil.h.

@@ -896,9 +892,7 @@

    - +
diff --git a/extras/doc/html/class_meta_oscil.js b/extras/doc/html/class_meta_oscil.js index 572ce7d89..94cb25741 100644 --- a/extras/doc/html/class_meta_oscil.js +++ b/extras/doc/html/class_meta_oscil.js @@ -8,14 +8,14 @@ var class_meta_oscil = [ "phaseIncFromFreq", "class_meta_oscil.html#af5f9994295116d5684e2ab4980f14511", null ], [ "phMod", "class_meta_oscil.html#abb81b942124212b2f7a99b9ce2bd2a39", null ], [ "setCutoffFreq", "class_meta_oscil.html#aceb617c02ea3a693a8ec48b32247a355", null ], - [ "setCutoffFreqs", "class_meta_oscil.html#a7567da1ff25347c8d44fad66efe28af1", null ], [ "setCutoffFreqs", "class_meta_oscil.html#a9309def78e90d419d569b0acd9a80bf3", null ], - [ "setFreq", "class_meta_oscil.html#a1960b7c4012424058876085c76d1dfd9", null ], + [ "setCutoffFreqs", "class_meta_oscil.html#a7567da1ff25347c8d44fad66efe28af1", null ], [ "setFreq", "class_meta_oscil.html#a3a1bf4af017c5c39d736f78d3c3e1bee", null ], + [ "setFreq", "class_meta_oscil.html#a1960b7c4012424058876085c76d1dfd9", null ], [ "setFreq_Q16n16", "class_meta_oscil.html#a98794f84684b257079e79bd9f92d0892", null ], [ "setFreq_Q24n8", "class_meta_oscil.html#adcadf4935c390cd8d2eea9623365bf70", null ], - [ "setOscils", "class_meta_oscil.html#a3390f39fbaa06276398624bd14a639ad", null ], [ "setOscils", "class_meta_oscil.html#afb893462be24c907f87bc6ee05595475", null ], + [ "setOscils", "class_meta_oscil.html#a3390f39fbaa06276398624bd14a639ad", null ], [ "setPhase", "class_meta_oscil.html#a889ea6de8595838ef735f8237a0abc51", null ], [ "setPhaseFractional", "class_meta_oscil.html#ab3c61548e9b48714d1e0900532e99408", null ], [ "setPhaseInc", "class_meta_oscil.html#a3bed37fc800a93ff95af445d25eaf57d", null ], diff --git a/extras/doc/html/class_metronome-members.html b/extras/doc/html/class_metronome-members.html index 7f1908783..27f09c20f 100644 --- a/extras/doc/html/class_metronome-members.html +++ b/extras/doc/html/class_metronome-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -121,9 +117,7 @@ diff --git a/extras/doc/html/class_metronome.html b/extras/doc/html/class_metronome.html index 41e14cd7a..5b411fc67 100644 --- a/extras/doc/html/class_metronome.html +++ b/extras/doc/html/class_metronome.html @@ -1,9 +1,9 @@ - + - + Mozzi: Metronome Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -108,7 +104,7 @@
-

A metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat. +

A metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat. More...

#include <Metronome.h>

@@ -120,38 +116,38 @@
-EventDelay - -
+EventDelay + +

Detailed Description

-

A metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat.

-

Metronome can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
-Alternatively, start(milliseconds) will call set() and start() together. This is called Metronome to avoid conflict with the Arduino Metro library.

+

A metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat.

+

Metronome can be set() to a number of milliseconds, then after calling start(), ready() will return true when the time is up.
+ Alternatively, start(milliseconds) will call set() and start() together. This is called Metronome to avoid conflict with the Arduino Metro library.

-

Definition at line 22 of file Metronome.h.

+

Definition at line 23 of file Metronome.h.

- + - + - + - + - + - +

Public Member Functions

 Metronome (unsigned int delay_milliseconds=0)
 Constructor. More...
 Constructor. More...
 
void start ()
 Start the metronome. More...
 Start the metronome. More...
 
void start (unsigned int delay_milliseconds)
 Set the time between beats and start the metronome. More...
 Set the time between beats and start the metronome. More...
 
void setBPM (float bpm)
 Set the beats per minute. More...
 Set the beats per minute. More...
 
bool ready ()
 Call this in updateControl() or updateAudio() to check if it is time for a beat. More...
 Call this in updateControl() or updateAudio() to check if it is time for a beat. More...
 
void stop ()
 
void set (unsigned int delay_milliseconds)
 Set the delay time. More...
 Set the delay time. More...
 
@@ -61,10 +57,10 @@

@@ -189,14 +185,14 @@

Constructor.

-

Declare a Metronome object.

Parameters
+

Declare a Metronome object.

Parameters
- +
delay_millisecondshow long between each occasion when ready() returns true.
delay_millisecondshow long between each occasion when ready() returns true.
-

Definition at line 31 of file Metronome.h.

+

Definition at line 32 of file Metronome.h.

@@ -224,10 +220,10 @@

-

Call this in updateControl() or updateAudio() to check if it is time for a beat.

+

Call this in updateControl() or updateAudio() to check if it is time for a beat.

Returns
true if the time for one is up.
-

Definition at line 75 of file Metronome.h.

+

Definition at line 76 of file Metronome.h.

@@ -256,7 +252,7 @@

Set the delay time.

-

This setting is persistent, until you change it by using set() again.

Parameters
+

This setting is persistent, until you change it by using set() again.

Parameters
delay_millisecondsdelay time in milliseconds.
@@ -300,7 +296,7 @@

Definition at line 63 of file Metronome.h.

+

Definition at line 64 of file Metronome.h.

@@ -329,7 +325,7 @@

Definition at line 40 of file Metronome.h.

+

Definition at line 41 of file Metronome.h.

@@ -365,7 +361,7 @@

Definition at line 51 of file Metronome.h.

+

Definition at line 52 of file Metronome.h.

@@ -375,9 +371,7 @@

    - +
diff --git a/extras/doc/html/class_midi_to_freq_private-members.html b/extras/doc/html/class_midi_to_freq_private-members.html index 7caac6932..32bffda5f 100644 --- a/extras/doc/html/class_midi_to_freq_private-members.html +++ b/extras/doc/html/class_midi_to_freq_private-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -108,15 +104,15 @@ + +
mtof(uint8_t)MidiToFreqPrivatefriend
mtof(int)MidiToFreqPrivatefriend
mtof(UFix< NI, 0, RANGE >)MidiToFreqPrivatefriend
mtof(SFix< NI, 0, RANGE >)MidiToFreqPrivatefriend
Q16n16_mtof(Q16n16)MidiToFreqPrivatefriend
diff --git a/extras/doc/html/class_midi_to_freq_private.html b/extras/doc/html/class_midi_to_freq_private.html index 1d205e315..27b7ab674 100644 --- a/extras/doc/html/class_midi_to_freq_private.html +++ b/extras/doc/html/class_midi_to_freq_private.html @@ -1,9 +1,9 @@ - + - + Mozzi: MidiToFreqPrivate Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -108,23 +104,33 @@

Detailed Description

-

Definition at line 11 of file mozzi_midi.h.

+

Definition at line 22 of file mozzi_midi.h.

- + - + - + + + + + + + + +

Friends

int mtof (uint8_t)
 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important. More...
 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important. More...
 
int mtof (int)
 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important. More...
 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important. More...
 
Q16n16 Q16n16_mtof (Q16n16)
 Converts midi note number to frequency with speed and accuracy. More...
 Converts midi note number to frequency with speed and accuracy. More...
 
+template<int8_t NI, uint64_t RANGE>
UFix< 16, 16 > mtof (UFix< NI, 0, RANGE >)
 Converts whole midi note number with speed and accuracy (more accurate that mtof(uint8_t))
 
+template<int8_t NI, uint64_t RANGE>
UFix< 16, 16 > mtof (SFix< NI, 0, RANGE >)
 Converts whole midi note number with speed and accuracy (more accurate that mtof(uint8_t))
 

Friends And Related Function Documentation

- -

◆ mtof [1/2]

+ +

◆ mtof [1/2]

-

Definition at line 71 of file mozzi_midi.h.

+

Definition at line 97 of file mozzi_midi.h.

- -

◆ mtof [2/2]

+ +

◆ mtof [2/2]

@@ -222,7 +228,7 @@

Converts midi note number to frequency with speed and accuracy.

-

Q16n16_mtofLookup() is a fast alternative to (float) mtof(), and more accurate than (uint8_t) mtof(), using Q16n16 fixed-point format instead of floats or uint8_t values. Q16n16_mtof() uses cheap linear interpolation between whole midi-note frequency equivalents stored in a lookup table, so is less accurate than the float version, mtof(), for non-whole midi values.

Note
Timing: ~8 us.
+

Q16n16_mtofLookup() is a fast alternative to (float) mtof(), and more accurate than (uint8_t) mtof(), using Q16n16 fixed-point format instead of floats or uint8_t values. Q16n16_mtof() uses cheap linear interpolation between whole midi-note frequency equivalents stored in a lookup table, so is less accurate than the float version, mtof(), for non-whole midi values.

Note
Timing: ~8 us.
Parameters
@@ -231,7 +237,7 @@

Returns
the frequency represented by the input midi note number, in Q16n16 fixed point fractional integer format, where the lower word is a fractional value.
-

Definition at line 97 of file mozzi_midi.h.

+

Definition at line 114 of file mozzi_midi.h.

@@ -241,9 +247,7 @@

    - +
diff --git a/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private-members.html b/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private-members.html index 1a1ba1c74..b99a4938f 100644 --- a/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private-members.html +++ b/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

@@ -61,10 +57,10 @@
midival_fractionala midi note number in Q16n16 format, for fractional values.
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private.html b/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private.html index c0dbef91d..d11855f82 100644 --- a/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private.html +++ b/extras/doc/html/class_mozzi_private_1_1_mozzi_rand_private.html @@ -1,9 +1,9 @@ - + - + Mozzi: MozziPrivate::MozziRandPrivate Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -109,7 +105,7 @@

Detailed Description

-

Definition at line 6 of file mozzi_rand_p.h.

+

Definition at line 17 of file mozzi_rand_p.h.

@@ -123,13 +119,13 @@ - + - + - +

Static Public Member Functions

Friends

void randSeed ()
 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function. More...
 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function. More...
 
void randSeed (uint32_t)
 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function. More...
 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function. More...
 
uint32_t xorshift96 ()
 Random number generator. More...
 Random number generator. More...
 

Friends And Related Function Documentation

@@ -156,11 +152,11 @@

-

Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function.

-

This can be useful if you want random sequences to be different on each run of a sketch, by seeding with a fairly random input. randSeed() called without a parameter uses noise from reading the Arduino's internal temperature as the seed, a technique discussed at http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there by Rob Tillaart.

+

Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function.

+

This can be useful if you want random sequences to be different on each run of a sketch, by seeding with a fairly random input. randSeed() called without a parameter uses noise from reading the Arduino's internal temperature as the seed, a technique discussed at http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there by Rob Tillaart.

Note
Intialization of the random seed is done differently on different MCUs, but is nowhere near perfect for most (and for some it is not even implemented at all). Many implementations (e.g. on AVR, STM32) simply rely on reading a (hopefully noisy) internal temperature sensor. You will often get better results by calling analogRead() - not mozziAnalogRead(0), in this case! - on one or two floating (non-connected) analog pins.
-

Definition at line 43 of file mozzi_rand.h.

+

Definition at line 54 of file mozzi_rand.h.

@@ -188,7 +184,7 @@

-

Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function.

+

Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function.

This can be useful if you want random sequences to be different on each run of a sketch, by seeding with fairly random input, such as analogRead() on an unconnected pin (as explained in the Arduino documentation for randomSeed(). randSeed is the same as xorshift96Seed(), but easier to remember.

Parameters
@@ -196,7 +192,7 @@

Definition at line 32 of file mozzi_rand_p.h.

+

Definition at line 43 of file mozzi_rand_p.h.

@@ -226,7 +222,7 @@

http://www.jstatsoft.org/v08/i14/xorshift.pdf

Returns
a random 32 bit integer.
-

Definition at line 14 of file mozzi_rand.h.

+

Definition at line 25 of file mozzi_rand.h.

@@ -236,9 +232,7 @@

diff --git a/extras/doc/html/class_multi_resonant_filter-members.html b/extras/doc/html/class_multi_resonant_filter-members.html index f2f21ebc2..aba2d3d5d 100644 --- a/extras/doc/html/class_multi_resonant_filter-members.html +++ b/extras/doc/html/class_multi_resonant_filter-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

@@ -61,10 +57,10 @@
seeda number to use as a seed.
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -106,39 +102,37 @@

This is the complete list of members for MultiResonantFilter< su >, including all inherited members.

- + - - - - - - - - - - - + + + + + + + + + + + - + - - - - - - - + + + + + + +
advanceBuffers(AudioOutputStorage_t in) (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >inlineprotected
advanceBuffers(AudioOutputStorage_t in) (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >inlineprotected
band()MultiResonantFilter< su >inline
buf0 (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >protected
buf1 (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >protected
current(AudioOutputStorage_t in, Int2Type< LOWPASS >) (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >inlineprotected
current(AudioOutputStorage_t in, Int2Type< HIGHPASS >) (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >inlineprotected
current(AudioOutputStorage_t in, Int2Type< BANDPASS >) (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >inlineprotected
current(AudioOutputStorage_t in, Int2Type< NOTCH >) (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >inlineprotected
f (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >protected
fb (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >protected
FX_SHIFT (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >protected
FX_SHIFT_M_1 (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >protected
fxmul(typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type b) (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >inlineprotected
buf0 (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >protected
buf1 (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >protected
current(AudioOutputStorage_t in, Int2Type< LOWPASS >) (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >inlineprotected
current(AudioOutputStorage_t in, Int2Type< HIGHPASS >) (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >inlineprotected
current(AudioOutputStorage_t in, Int2Type< BANDPASS >) (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >inlineprotected
current(AudioOutputStorage_t in, Int2Type< NOTCH >) (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >inlineprotected
f (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >protected
fb (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >protected
FX_SHIFT (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >protected
FX_SHIFT_M_1 (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >protected
fxmul(typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(uint8_t) -1 >::signed_type b) (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >inlineprotected
high()MultiResonantFilter< su >inline
ifxmul(typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type a, su b) (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >inlineprotected
ifxmul(typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(uint8_t) -1 >::signed_type a, uint8_t b) (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >inlineprotected
low()MultiResonantFilter< su >inline
next(AudioOutputStorage_t in)MultiResonantFilter< su >inline
notch()MultiResonantFilter< su >inline
q (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >protected
ResonantFilter()ResonantFilter< LOWPASS, su >inline
setCutoffFreq(su cutoff)ResonantFilter< LOWPASS, su >inline
setCutoffFreqAndResonance(su cutoff, su resonance)ResonantFilter< LOWPASS, su >inline
setResonance(su resonance)ResonantFilter< LOWPASS, su >inline
SHIFTED_1 (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >protected
ucfxmul(su a, typename IntegerType< sizeof(su)+sizeof(su)>::unsigned_type b) (defined in ResonantFilter< LOWPASS, su >)ResonantFilter< LOWPASS, su >inlineprotected
q (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >protected
ResonantFilter()ResonantFilter< LOWPASS, uint8_t >inline
setCutoffFreq(uint8_t cutoff)ResonantFilter< LOWPASS, uint8_t >inline
setCutoffFreqAndResonance(uint8_t cutoff, uint8_t resonance)ResonantFilter< LOWPASS, uint8_t >inline
setResonance(uint8_t resonance)ResonantFilter< LOWPASS, uint8_t >inline
SHIFTED_1 (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >protected
ucfxmul(uint8_t a, typename IntegerType< sizeof(uint8_t)+sizeof(uint8_t)>::unsigned_type b) (defined in ResonantFilter< LOWPASS, uint8_t >)ResonantFilter< LOWPASS, uint8_t >inlineprotected
diff --git a/extras/doc/html/class_multi_resonant_filter.html b/extras/doc/html/class_multi_resonant_filter.html index 64dd5cfb8..a02ac23e0 100644 --- a/extras/doc/html/class_multi_resonant_filter.html +++ b/extras/doc/html/class_multi_resonant_filter.html @@ -1,9 +1,9 @@ - + - + Mozzi: MultiResonantFilter< su > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -121,44 +117,43 @@
-ResonantFilter< LOWPASS, su > - -
+ResonantFilter< LOWPASS, uint8_t > + +

Detailed Description

template<typename su = uint8_t>
class MultiResonantFilter< su >

A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime.

-

Behaves like ResonantFilter for setting the resonance and cutoff frequency. Like ResonantFilter, it can be used on different sample sizes: MultiResonantFilter<uint8_t> and MultiResonantFilter<uint16_t> have been tested. For the former, both cutoff and resonance are uint8_t, hence between 0-255. For the later, both cutoff and resonance are uint16_t, hence between 0-65535.

+

Behaves like ResonantFilter for setting the resonance and cutoff frequency. Like ResonantFilter, it can be used on different sample sizes: MultiResonantFilter<uint8_t> and MultiResonantFilter<uint16_t> have been tested. For the former, both cutoff and resonance are uint8_t, hence between 0-255. For the later, both cutoff and resonance are uint16_t, hence between 0-65535.

-

Definition at line 185 of file ResonantFilter.h.

+

Definition at line 184 of file ResonantFilter.h.

- + - + - + - + - + - - + + - - + + - - + +

Public Member Functions

void next (AudioOutputStorage_t in)
 Compute the filters, given an input signal. More...
 Compute the filters, given an input signal. More...
 
AudioOutputStorage_t low ()
 Return the input filtered with a lowpass filter. More...
 Return the input filtered with a lowpass filter. More...
 
AudioOutputStorage_t high ()
 Return the input filtered with a highpass filter. More...
 Return the input filtered with a highpass filter. More...
 
AudioOutputStorage_t band ()
 Return the input filtered with a bandpass filter. More...
 Return the input filtered with a bandpass filter. More...
 
AudioOutputStorage_t notch ()
 Return the input filtered with a notch filter. More...
 Return the input filtered with a notch filter. More...
 
void setCutoffFreq (su cutoff)
 deprecated. More...
void setCutoffFreq (uint8_t cutoff)
 deprecated. More...
 
void setResonance (su resonance)
 deprecated. More...
void setResonance (uint8_t resonance)
 deprecated. More...
 
void setCutoffFreqAndResonance (su cutoff, su resonance)
 
-Set the cut off frequency and resonance. More...
void setCutoffFreqAndResonance (uint8_t cutoff, uint8_t resonance)
 Set the cut off frequency and resonance. More...
 
+IntegerType< sizeof(uint8_t)+sizeof(uint8_t)>::unsigned_type  +IntegerType< sizeof(AudioOutputStorage_t)+sizeof(uint8_t) -1 >::signed_type  +IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type 

@@ -179,25 +174,25 @@ AudioOutputStorage_t 

current (AudioOutputStorage_t in, Int2Type< NOTCH >)
 
-IntegerType< sizeof(su)+sizeof(su)>::unsigned_type ucfxmul (su a, typename IntegerType< sizeof(su)+sizeof(su)>::unsigned_type b)
ucfxmul (uint8_t a, typename IntegerType< sizeof(uint8_t)+sizeof(uint8_t)>::unsigned_type b)
 
-IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type ifxmul (typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type a, su b)
ifxmul (typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(uint8_t) -1 >::signed_type a, uint8_t b)
 
-IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type fxmul (typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(su) -1 >::signed_type b)
fxmul (typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(AudioOutputStorage_t)>::signed_type a, typename IntegerType< sizeof(AudioOutputStorage_t)+sizeof(uint8_t) -1 >::signed_type b)
 
+uint8_t  +uint8_t  +IntegerType< sizeof(uint8_t)+sizeof(uint8_t)>::unsigned_type  @@ -212,7 +207,7 @@ const uint8_t  +const uint8_t 

Protected Attributes

-su q
q
 
-su f
f
 
-IntegerType< sizeof(su)+sizeof(su)>::unsigned_type fb
fb
 
AudioOutputStorage_t buf0
FX_SHIFT_M_1
 
-const su SHIFTED_1
SHIFTED_1
 

Member Function Documentation

@@ -244,7 +239,7 @@

Returns
the filtered signal output.

-

Definition at line 207 of file ResonantFilter.h.

+

Definition at line 206 of file ResonantFilter.h.

@@ -276,7 +271,7 @@

Returns
the filtered signal output.

-

Definition at line 203 of file ResonantFilter.h.

+

Definition at line 202 of file ResonantFilter.h.

@@ -308,7 +303,7 @@

Returns
the filtered signal output.
-

Definition at line 199 of file ResonantFilter.h.

+

Definition at line 198 of file ResonantFilter.h.

@@ -346,7 +341,7 @@

Definition at line 191 of file ResonantFilter.h.

+

Definition at line 190 of file ResonantFilter.h.

@@ -378,7 +373,7 @@

Returns
the filtered signal output.
-

Definition at line 211 of file ResonantFilter.h.

+

Definition at line 210 of file ResonantFilter.h.

@@ -392,9 +387,9 @@

- + - + @@ -410,12 +405,12 @@

Parameters

void ResonantFilter< FILTER_TYPE, su >::setCutoffFreq void ResonantFilter< FILTER_TYPE, uint8_t >::setCutoffFreq (su uint8_t  cutoff)
- +
cutoffuse the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2. Be careful of distortion at the lower end, especially with high resonance.
cutoffuse the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2. Be careful of distortion at the lower end, especially with high resonance.
-

Definition at line 92 of file ResonantFilter.h.

+

Definition at line 91 of file ResonantFilter.h.

@@ -429,15 +424,15 @@

- + - + - + @@ -453,17 +448,16 @@

-


-Set the cut off frequency and resonance.

-

Replaces setCutoffFreq() and setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)

Parameters
+

Set the cut off frequency and resonance.

+

Replaces setCutoffFreq() and setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)

Parameters

void ResonantFilter< FILTER_TYPE, su >::setCutoffFreqAndResonance void ResonantFilter< FILTER_TYPE, uint8_t >::setCutoffFreqAndResonance (su uint8_t  cutoff,
su uint8_t  resonance 
- - + +
cutoffrange 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16 Be careful of distortion at the lower end, especially with high resonance.
resonancerange 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
cutoffrange 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16 Be careful of distortion at the lower end, especially with high resonance.
resonancerange 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
-

Definition at line 115 of file ResonantFilter.h.

+

Definition at line 114 of file ResonantFilter.h.

@@ -477,9 +471,9 @@

- + - + @@ -495,13 +489,13 @@

Parameters

void ResonantFilter< FILTER_TYPE, su >::setResonance void ResonantFilter< FILTER_TYPE, uint8_t >::setResonance (su uint8_t  resonance)
- +
resonancein the range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, with 255/65535 being most resonant
resonancein the range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, with 255/65535 being most resonant
Note
Remember to call setCuttoffFreq() after resonance is changed!
-

Definition at line 106 of file ResonantFilter.h.

+

Definition at line 105 of file ResonantFilter.h.

@@ -511,9 +505,7 @@

    - +
diff --git a/extras/doc/html/class_multi_resonant_filter.js b/extras/doc/html/class_multi_resonant_filter.js index d6b0bdd9e..4772ec605 100644 --- a/extras/doc/html/class_multi_resonant_filter.js +++ b/extras/doc/html/class_multi_resonant_filter.js @@ -2,9 +2,9 @@ var class_multi_resonant_filter = [ [ "advanceBuffers", "class_multi_resonant_filter.html#abff68aae1ffc1bd9894e8f824365e84a", null ], [ "band", "class_multi_resonant_filter.html#a93c35829c63addc2f54f42ca3b30b37e", null ], - [ "current", "class_multi_resonant_filter.html#adbf4efd639c951276ee5e8612b6818ee", null ], - [ "current", "class_multi_resonant_filter.html#a0dc200c213651f770768cffff90bcf26", null ], [ "current", "class_multi_resonant_filter.html#a319f11e6f6a9cfb3570a335bf1dc0866", null ], + [ "current", "class_multi_resonant_filter.html#a0dc200c213651f770768cffff90bcf26", null ], + [ "current", "class_multi_resonant_filter.html#adbf4efd639c951276ee5e8612b6818ee", null ], [ "current", "class_multi_resonant_filter.html#a496a19cd2b4ce184374ce78bd83bbbee", null ], [ "fxmul", "class_multi_resonant_filter.html#a8d6056a34164a1ed81732f1f09c75268", null ], [ "high", "class_multi_resonant_filter.html#a1a624bcfa3ad251c2e4af27a6a453006", null ], diff --git a/extras/doc/html/class_multi_resonant_filter.png b/extras/doc/html/class_multi_resonant_filter.png index 4cd858137be447b55e63ef033af2565372424ad7..519c62bcafa2eb52786b68dbdc402f588a23f18e 100644 GIT binary patch delta 739 zcmV<90v!G61&{_IiBL{Q4GJ0x0000DNk~Le0002s0000`2m=5B05>^_rja2#f1gQ2 zK~#7F?VZtftRM_Ux5u^S|3CTG5g|av(cZSJp|lXG^ zKuLbr=L&X?Gra)5m>@~6YNTs` zEnGHBH~ag7M`=<`EXiIyV19k+e9HTE5G-Vyk7^{%&(%F&02SjoiX=P)I96Xpnb2l)4hFje0soU7Y}g%H)qi9 z;v#l0<|IY4WfeiYUrT$8wX4?=G{n}oQ$SmQO2^65JAl~%H$|Obxs98me`T?=2-ewI zT5~A7BJ=+de0c`%06Ll0SJBS`Hr3!2pnC>St7sX@dDT|YT-clfSk77X&GP}f@1RLy zr}$Mx=A?>B(l6DWud^go3IKS4@0lS^_<}@Gl0K~oC`pku0VOH2{sQ2-uIs=8_)$Fo zM%L(nkH_GIqXT~MjZHW_f8ea50I@Xz0U~Px0z}pX1c{Y1ExS8_kCX9vtOsYe@-@TJxYe3d<%C{ zGxeWm%Si^$&iC VE?yP$2*S delta 700 zcmbQh_L5bxGr-TCmrII^fq{Y7)59eQNS^@W01jp#nZ5Z`(?mt<`U+1M$B+ufw{u@l zTB5+?#=mjZ{r?loa|DGJ>^<}Cnwyq!omSCl#p(Y}Z_+u-xTvRi}fb-}l#EknPs$xEbK`#O2zTYz1AHnbY!r{axm2 z>tWefqj8%rHoG?b+gkbh&)2hpxP#=ED>%39`75xVdFAQV$J(bc8h*>QRW-7jkhbSz z(9COWVaCV%UKF{^pPW~+eC46t?3rbfjXD3d+`s5KizEkkC)q5zp1bnfzHbg|-9=_@ zdnn){-gHai=yiiFpXMZH@bcCFkZ22weRD$DY}J`cdDUv+sQEUZ4Bg)~@YE|USs%5Z zDX`D})WpN9LU()FYzbX`Ws_s*%F2W~<6{bU-*<5BtFd1drKIFn`f~ddMuqEj!t);p z3Qi1W?da%G2NP#mfPrJw$nbAx9D{L&*o5oZLX#pL>MWiq%w$tpCDx$N%F&>X9oJ)% zI1svY$|W8pMw@s>rU#xNd|aVAUiS0nY3s|EGVEAU>le%TAlr)Zrq$G=M;pHX?bE&X z8&j|64~VkH@QDbCk;+N@VzAzO9up;N`3JmjL*hJXFOVf9O{nVdAn)`Zu6m9_%B!j1`pUXO@geCx? CA}~Jy diff --git a/extras/doc/html/class_oscil-members.html b/extras/doc/html/class_oscil-members.html index f2b69b3d7..f040c653e 100644 --- a/extras/doc/html/class_oscil-members.html +++ b/extras/doc/html/class_oscil-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -113,14 +109,14 @@ Oscil()Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline phaseIncFromFreq(int frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline phMod(Q15n16 phmod_proportion)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline - phMod(SFix< NI, NF > phmod_proportion)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline + phMod(SFix< NI, NF, RANGE > phmod_proportion)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline phMod(SFix< 15, 16 > phmod_proportion)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline setFreq(int frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline setFreq(float frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline - setFreq(UFix< NI, NF > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline - setFreq(UFix< 24, 8 > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline - setFreq(UFix< 16, 16 > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline - setFreq(SFix< NI, NF > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline + setFreq(UFix< NI, NF, RANGE > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline + setFreq(UFix< 24, 8, RANGE > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline + setFreq(UFix< 16, 16, RANGE > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline + setFreq(SFix< NI, NF, RANGE > frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline setFreq_Q16n16(Q16n16 frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline setFreq_Q24n8(Q24n8 frequency)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline setPhase(unsigned int phase)Oscil< NUM_TABLE_CELLS, UPDATE_RATE >inline @@ -132,9 +128,7 @@ diff --git a/extras/doc/html/class_oscil.html b/extras/doc/html/class_oscil.html index e698c9131..78553dd60 100644 --- a/extras/doc/html/class_oscil.html +++ b/extras/doc/html/class_oscil.html @@ -1,9 +1,9 @@ - + - + Mozzi: Oscil< NUM_TABLE_CELLS, UPDATE_RATE > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -107,8 +103,7 @@
-


-Oscil plays a wavetable, cycling through the table to generate an audio or control signal. +

Oscil plays a wavetable, cycling through the table to generate an audio or control signal. More...

#include <Oscil.h>

@@ -116,89 +111,90 @@

template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
class Oscil< NUM_TABLE_CELLS, UPDATE_RATE >

-


-Oscil plays a wavetable, cycling through the table to generate an audio or control signal.

-

The frequency of the signal can be set or changed with setFreq(), and the output of an Oscil can be produced with next() for a simple cycling oscillator, or atIndex() for a particular sample in the table.

Template Parameters
+

Oscil plays a wavetable, cycling through the table to generate an audio or control signal.

+

The frequency of the signal can be set or changed with setFreq(), and the output of an Oscil can be produced with next() for a simple cycling oscillator, or atIndex() for a particular sample in the table.

Template Parameters
- - + +
NUM_TABLE_CELLSThis is defined in the table ".h" file the Oscil will be using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Oscil to run fast enough.
UPDATE_RATEThis will be MOZZI_AUDIO_RATE if the Oscil is updated in updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load.
NUM_TABLE_CELLSThis is defined in the table ".h" file the Oscil will be using. It's important that it's a power of 2, and either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Oscil to run fast enough.
UPDATE_RATEThis will be MOZZI_AUDIO_RATE if the Oscil is updated in updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load.
Note
If you #define OSCIL_DITHER_PHASE before you #include <Oscil.h>, the phase increments will be dithered, which reduces spurious frequency spurs in the audio output, at the cost of some extra processing and memory.

int8_t2mozzi

-

Converting soundfiles for Mozzi There is a python script called char2mozzi.py in the Mozzi/python folder. The usage is: char2mozzi.py infilename outfilename tablename samplerate

+

Converting soundfiles for Mozzi There is a python script called char2mozzi.py in the Mozzi/python folder. The usage is: char2mozzi.py infilename outfilename tablename samplerate

-

Definition at line 59 of file Oscil.h.

+

Definition at line 61 of file Oscil.h.

- + - + - + - + - + - + - + - + - - - - + + + + - + - + - + - - - - + + + + - + - - - + + + + - + - - - - - - - + + + + + + + + - + - + - +

Public Member Functions

 Oscil (const int8_t *TABLE_NAME)
 Constructor. More...
 Constructor. More...
 
 Oscil ()
 Constructor. More...
 Constructor. More...
 
int8_t next ()
 Updates the phase according to the current frequency and returns the sample at the new phase position. More...
 Updates the phase according to the current frequency and returns the sample at the new phase position. More...
 
void setTable (const int8_t *TABLE_NAME)
 Change the sound table which will be played by the Oscil. More...
 Change the sound table which will be played by the Oscil. More...
 
void setPhase (unsigned int phase)
 Set the phase of the Oscil. More...
 Set the phase of the Oscil. More...
 
void setPhaseFractional (uint32_t phase)
 Set the phase of the Oscil. More...
 Set the phase of the Oscil. More...
 
uint32_t getPhaseFractional ()
 Get the phase of the Oscil in fractional format. More...
 Get the phase of the Oscil in fractional format. More...
 
int8_t phMod (Q15n16 phmod_proportion)
 Returns the next sample given a phase modulation value. More...
 Returns the next sample given a phase modulation value. More...
 
template<byte NI, byte NF>
int8_t phMod (SFix< NI, NF > phmod_proportion)
 Returns the next sample given a phase modulation value. More...
 
template<int8_t NI, int8_t NF, uint8_t RANGE>
int8_t phMod (SFix< NI, NF, RANGE > phmod_proportion)
 Returns the next sample given a phase modulation value. More...
 
int8_t phMod (SFix< 15, 16 > phmod_proportion)
 Returns the next sample given a phase modulation value. More...
 Returns the next sample given a phase modulation value. More...
 
void setFreq (int frequency)
 Set the oscillator frequency with an unsigned int. More...
 Set the oscillator frequency with an unsigned int. More...
 
void setFreq (float frequency)
 Set the oscillator frequency with a float. More...
 Set the oscillator frequency with a float. More...
 
template<int8_t NI, int8_t NF>
void setFreq (UFix< NI, NF > frequency)
 Set the frequency using UFix<NI,NF> fixed-point number format. More...
 
template<int8_t NI, int8_t NF, uint64_t RANGE>
void setFreq (UFix< NI, NF, RANGE > frequency)
 Set the frequency using UFix<NI,NF> fixed-point number format. More...
 
void setFreq_Q24n8 (Q24n8 frequency)
 Set the frequency using Q24n8 fixed-point number format. More...
 Set the frequency using Q24n8 fixed-point number format. More...
 
void setFreq (UFix< 24, 8 > frequency)
 Set the frequency using UFix<24,8> fixed-point number format. More...
 
template<uint64_t RANGE>
void setFreq (UFix< 24, 8, RANGE > frequency)
 Set the frequency using UFix<24,8> fixed-point number format. More...
 
void setFreq_Q16n16 (Q16n16 frequency)
 Set the frequency using Q16n16 fixed-point number format. More...
 Set the frequency using Q16n16 fixed-point number format. More...
 
void setFreq (UFix< 16, 16 > frequency)
 Set the frequency using UFix<16,16> fixed-point number format. More...
 
template<byte NI, byte NF>
void setFreq (SFix< NI, NF > frequency)
 Set the frequency using SFix<NI,NF> fixed-point number format. More...
 
template<uint64_t RANGE>
void setFreq (UFix< 16, 16, RANGE > frequency)
 Set the frequency using UFix<16,16> fixed-point number format. More...
 
template<int8_t NI, int8_t NF, uint64_t RANGE>
void setFreq (SFix< NI, NF, RANGE > frequency)
 Set the frequency using SFix<NI,NF> fixed-point number format. More...
 
int8_t atIndex (unsigned int index)
 Returns the sample at the given table index. More...
 Returns the sample at the given table index. More...
 
uint32_t phaseIncFromFreq (int frequency)
 phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
 phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
 
void setPhaseInc (uint32_t phaseinc_fractional)
 Set a specific phase increment. More...
 Set a specific phase increment. More...
 

Constructor & Destructor Documentation

@@ -231,12 +227,12 @@

Parameters
- +
TABLE_NAMEthe name of the array the Oscil will be using. This can be found in the table ".h" file if you are using a table made for Mozzi by the int8_t2mozzi.py python script in Mozzi's python folder.
TABLE_NAMEthe name of the array the Oscil will be using. This can be found in the table ".h" file if you are using a table made for Mozzi by the int8_t2mozzi.py python script in Mozzi's python folder.
-

Definition at line 69 of file Oscil.h.

+

Definition at line 71 of file Oscil.h.

@@ -266,9 +262,9 @@

Constructor.

-

Declare an Oscil with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play. The table can be set or changed on the fly with setTable(). Any tables used by the Oscil must be the same size.

+

Declare an Oscil with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play. The table can be set or changed on the fly with setTable(). Any tables used by the Oscil must be the same size.

-

Definition at line 79 of file Oscil.h.

+

Definition at line 81 of file Oscil.h.

@@ -308,7 +304,7 @@

Returns
the sample at the given table index.
-

Definition at line 329 of file Oscil.h.

+

Definition at line 333 of file Oscil.h.

@@ -337,10 +333,10 @@

-

Get the phase of the Oscil in fractional format.

+

Get the phase of the Oscil in fractional format.

Returns
position in the wavetable, shifted left by OSCIL_F_BITS (which is 16 when this was written).
-

Definition at line 129 of file Oscil.h.

+

Definition at line 131 of file Oscil.h.

@@ -372,7 +368,7 @@

Returns
the next sample.
-

Definition at line 87 of file Oscil.h.

+

Definition at line 89 of file Oscil.h.

@@ -402,8 +398,8 @@

-

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

-

Instead of recalculating the phase increment for each frequency in between, you can just calculate the phase increment for each end frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and use setPhaseInc() to set the phase increment at each step. (Note: I should really profile this with the oscilloscope to see if it's worth the extra confusion!)

Parameters
+

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

+

Instead of recalculating the phase increment for each frequency in between, you can just calculate the phase increment for each end frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and use setPhaseInc() to set the phase increment at each step. (Note: I should really profile this with the oscilloscope to see if it's worth the extra confusion!)

Parameters
frequencyfor which you want to calculate a phase increment value.
@@ -411,7 +407,7 @@

Returns
the phase increment value which will produce a given frequency.

-

Definition at line 346 of file Oscil.h.

+

Definition at line 350 of file Oscil.h.

@@ -450,19 +446,17 @@

Returns
a sample from the table.

-

Definition at line 147 of file Oscil.h.

+

Definition at line 149 of file Oscil.h.

- -

◆ phMod() [2/3]

+ +

◆ phMod() [2/3]

template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
-
-template<byte NI, byte NF>
- + @@ -485,23 +479,25 @@

Parameters

@@ -470,7 +464,7 @@

int8_t Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::phMod

(SFix< NI, NF > SFix< 15, 16 >  phmod_proportion)
- +
phmod_proportiona phase modulation value given as a proportion of the wave. The phmod_proportion parameter is a SFix<NI,NF> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in each direction. This fixed point math number is interpreted as a SFix<15,16> internally.
phmod_proportiona phase modulation value given as a proportion of the wave. The phmod_proportion parameter is a SFix<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in each direction.
Returns
a sample from the table.
-

Definition at line 162 of file Oscil.h.

+

Definition at line 178 of file Oscil.h.

- -

◆ phMod() [3/3]

+ +

◆ phMod() [3/3]

template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<int8_t NI, int8_t NF, uint8_t RANGE>
- + @@ -524,18 +520,18 @@

Parameters

@@ -509,7 +505,7 @@

int8_t Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::phMod

(SFix< 15, 16 > SFix< NI, NF, RANGE >  phmod_proportion)
- +
phmod_proportiona phase modulation value given as a proportion of the wave. The phmod_proportion parameter is a SFix<15,16> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in each direction.
phmod_proportiona phase modulation value given as a proportion of the wave. The phmod_proportion parameter is a SFix<NI,NF> fixed-point number where the fractional part represents almost -1 to almost 1, modulating the phase by one whole table length in each direction. This fixed point math number is interpreted as a SFix<15,16> internally.
Returns
a sample from the table.
-

Definition at line 176 of file Oscil.h.

+

Definition at line 164 of file Oscil.h.

- -

◆ setFreq() [1/6]

+ +

◆ setFreq() [1/6]

@@ -548,7 +544,7 @@

void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq ( - int  + float  frequency) @@ -560,20 +556,20 @@

-

Set the oscillator frequency with an unsigned int.

-

This is faster than using a float, so it's useful when processor time is tight, but it can be tricky with low and high frequencies, depending on the size of the wavetable being used. If you're not getting the results you expect, try explicitly using a float, or try setFreq_Q24n8() or or setFreq_Q16n16().

Parameters
+

Set the oscillator frequency with a float.

+

Using a float is the most reliable way to set frequencies, -Might- be slower than using an int but you need either this, setFreq_Q24n8() or setFreq_Q16n16() for fractional frequencies.

Parameters
frequencyto play the wave table.
-

Definition at line 190 of file Oscil.h.

+

Definition at line 207 of file Oscil.h.

- -

◆ setFreq() [2/6]

+ +

◆ setFreq() [2/6]

@@ -586,7 +582,7 @@

void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq ( - float  + int  frequency) @@ -598,27 +594,27 @@

-

Set the oscillator frequency with a float.

-

Using a float is the most reliable way to set frequencies, -Might- be slower than using an int but you need either this, setFreq_Q24n8() or setFreq_Q16n16() for fractional frequencies.

Parameters
+

Set the oscillator frequency with an unsigned int.

+

This is faster than using a float, so it's useful when processor time is tight, but it can be tricky with low and high frequencies, depending on the size of the wavetable being used. If you're not getting the results you expect, try explicitly using a float, or try setFreq_Q24n8() or or setFreq_Q16n16().

Parameters
frequencyto play the wave table.
-

Definition at line 205 of file Oscil.h.

+

Definition at line 192 of file Oscil.h.

- -

◆ setFreq() [3/6]

+ +

◆ setFreq() [3/6]

- -

◆ setFreq() [4/6]

+ +

◆ setFreq() [4/6]

- -

◆ setFreq() [5/6]

+ +

◆ setFreq() [5/6]

template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<uint64_t RANGE>
- + @@ -717,30 +720,27 @@

-

Set the frequency using UFix<16,16> fixed-point number format.

-

This is useful in combination with Q16n16_mtof(), a fast alternative to mtof(), using UFix<16,16> fixed-point format instead of fractional numbers.

Note
This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
-
-This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
-
Parameters
+

Set the frequency using UFix<24,8> fixed-point number format.

+

This might be faster than the float version for setting low frequencies such as 1.5 Hz, or other values which may not work well with your table size. A UFix<24,8> representation of 1.5 is 384 (ie. 1.5 * 256). Can't be used with UPDATE_RATE less than 64 Hz.

Parameters

@@ -705,7 +708,7 @@

void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq

(UFix< 16, 16 > UFix< 24, 8, RANGE >  frequency)
- +
frequencyin UFix<16,16> fixed-point number format.
frequencyin UFix<24,8> fixed-point number format.
-

Definition at line 297 of file Oscil.h.

+

Definition at line 261 of file Oscil.h.

- -

◆ setFreq() [6/6]

+ +

◆ setFreq() [6/6]

@@ -802,7 +802,7 @@

Set the frequency using Q16n16 fixed-point number format.

-

This is useful in combination with Q16n16_mtof(), a fast alternative to mtof(), using Q16n16 fixed-point format instead of floats.

Note
This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
+

This is useful in combination with Q16n16_mtof(), a fast alternative to mtof(), using Q16n16 fixed-point format instead of floats.

Note
This should work OK with tables 2048 cells or smaller and frequencies up to 4096 Hz. Can't be used with UPDATE_RATE less than 64 Hz.
This didn't run faster than float last time it was tested, after 2014 code changes. Need to see if 2014 changes improved or worsened performance.
Parameters
@@ -812,7 +812,7 @@

Definition at line 273 of file Oscil.h.

+

Definition at line 276 of file Oscil.h.

@@ -850,7 +850,7 @@

Definition at line 234 of file Oscil.h.

+

Definition at line 236 of file Oscil.h.

@@ -880,7 +880,7 @@

-

Set the phase of the Oscil.

+

Set the phase of the Oscil.

This does the same thing as Sample::start(offset). Just different ways of thinking about oscillators and samples.

Parameters
@@ -888,7 +888,7 @@

Definition at line 109 of file Oscil.h.

+

Definition at line 111 of file Oscil.h.

@@ -918,15 +918,15 @@

-

Set the phase of the Oscil.

-

Might be useful with getPhaseFractional().

Parameters
+

Set the phase of the Oscil.

+

Might be useful with getPhaseFractional().

Parameters

phasea position in the wavetable.
phasea position in the wavetable.
-

Definition at line 120 of file Oscil.h.

+

Definition at line 122 of file Oscil.h.

@@ -957,14 +957,14 @@

Set a specific phase increment.

-

See phaseIncFromFreq().

Parameters
+

See phaseIncFromFreq().

Parameters
- +
phaseinc_fractionala phase increment value as calculated by phaseIncFromFreq().
phaseinc_fractionala phase increment value as calculated by phaseIncFromFreq().
-

Definition at line 359 of file Oscil.h.

+

Definition at line 363 of file Oscil.h.

@@ -994,7 +994,7 @@

-

Change the sound table which will be played by the Oscil.

+

Change the sound table which will be played by the Oscil.

Parameters
@@ -1002,7 +1002,7 @@

Definition at line 97 of file Oscil.h.

+

Definition at line 99 of file Oscil.h.

@@ -1012,9 +1012,7 @@

    - +
diff --git a/extras/doc/html/class_oscil.js b/extras/doc/html/class_oscil.js index 543969c53..1d73e8e1d 100644 --- a/extras/doc/html/class_oscil.js +++ b/extras/doc/html/class_oscil.js @@ -3,16 +3,22 @@ var class_oscil = [ "Oscil", "class_oscil.html#afe6a75646d2dd822a654bcd85242e800", null ], [ "Oscil", "class_oscil.html#ab7dc5f97742d841fff6a4dca6d7242f3", null ], [ "atIndex", "class_oscil.html#a97f2c0f28751641417202fee2a0776d3", null ], - [ "getPhaseFractional", "class_oscil.html#aa774ef68b06f9652e6ac23d4e9332554", null ], + [ "getPhaseFractional", "class_oscil.html#aefafa92dd2065243a164c1d824f292d7", null ], [ "next", "class_oscil.html#a655de04690650b27182e3b4d07768d46", null ], - [ "phaseIncFromFreq", "class_oscil.html#a184110cb1901d2742a6016b46cbea027", null ], + [ "phaseIncFromFreq", "class_oscil.html#a48ad51d7fbac24263008a9931f537baf", null ], [ "phMod", "class_oscil.html#a4c6de90bc2d4183a5146eb2ae5e3dd2c", null ], - [ "setFreq", "class_oscil.html#a23121f22ea447918088a79c7f9748b3d", null ], + [ "phMod", "class_oscil.html#ae12f5e34705bb92394c4941aebe5a8ea", null ], + [ "phMod", "class_oscil.html#a90aeeb558d2d06efceaf9b81566f4d3d", null ], [ "setFreq", "class_oscil.html#aa342e74f8e73edda0b0f042770e3fba4", null ], + [ "setFreq", "class_oscil.html#a23121f22ea447918088a79c7f9748b3d", null ], + [ "setFreq", "class_oscil.html#a47bd8774216331e1c3ab62b8c9f92e8a", null ], + [ "setFreq", "class_oscil.html#a5161b31eea29b634f530d37c8f552685", null ], + [ "setFreq", "class_oscil.html#a7dbb7386be70efdda01bda5c280b15ee", null ], + [ "setFreq", "class_oscil.html#a078e9b56769b96a2e9a6a645b3c49596", null ], [ "setFreq_Q16n16", "class_oscil.html#a73b52741178ed490463d9ff471cebef3", null ], [ "setFreq_Q24n8", "class_oscil.html#abc8a4ee236f7fd45dda9dece7292b6e7", null ], [ "setPhase", "class_oscil.html#ab7b740eec56740426a47508562ed4dd5", null ], - [ "setPhaseFractional", "class_oscil.html#afc77bfc5a1ad5926ad8df37725d480d7", null ], - [ "setPhaseInc", "class_oscil.html#a2ff9bfcc57e07bf0df2ed7db186ecff7", null ], + [ "setPhaseFractional", "class_oscil.html#a9befaff8a21a4915b647636e821435f9", null ], + [ "setPhaseInc", "class_oscil.html#aced127a46f0e45c259f1a788b6c31074", null ], [ "setTable", "class_oscil.html#a0b22d79fb2d6c7fb50b19c00f249ed84", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_p_d_resonant-members.html b/extras/doc/html/class_p_d_resonant-members.html index 085fa952a..02bc5adf0 100644 --- a/extras/doc/html/class_p_d_resonant-members.html +++ b/extras/doc/html/class_p_d_resonant-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

@@ -61,10 +57,10 @@
TABLE_NAMEis the name of the array in the table ".h" file you're using.
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -117,9 +113,7 @@ diff --git a/extras/doc/html/class_p_d_resonant.html b/extras/doc/html/class_p_d_resonant.html index 1ef522f02..e8c3876cf 100644 --- a/extras/doc/html/class_p_d_resonant.html +++ b/extras/doc/html/class_p_d_resonant.html @@ -1,9 +1,9 @@ - + - + Mozzi: PDResonant Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -107,15 +103,15 @@
-

PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on https://en.wikipedia.org/wiki/Phase_distortion_synthesis. +

PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on https://en.wikipedia.org/wiki/Phase_distortion_synthesis. More...

#include <PDResonant.h>

Detailed Description

-

PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on https://en.wikipedia.org/wiki/Phase_distortion_synthesis.

-

The class shows how the Mozzi Phasor class can be used to generate an index into a wavetable, and an ADSR is used to modulate the effect by modifying the Phasor frequency and sync. More complex phase distortion effects could be developed by using precalculated tables, or calcuating tables on the fly using a double buffer, or a line-breakpoint model, a sort of hybridPhasor-Line object.

+

PDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on https://en.wikipedia.org/wiki/Phase_distortion_synthesis.

+

The class shows how the Mozzi Phasor class can be used to generate an index into a wavetable, and an ADSR is used to modulate the effect by modifying the Phasor frequency and sync. More complex phase distortion effects could be developed by using precalculated tables, or calcuating tables on the fly using a double buffer, or a line-breakpoint model, a sort of hybridPhasor-Line object.

-

Definition at line 33 of file PDResonant.h.

+

Definition at line 31 of file PDResonant.h.

@@ -124,19 +120,19 @@ - + - + - + - + - +

Public Member Functions

 Constructor.
 
void noteOn (byte channel, byte pitch, byte velocity)
 Play a note in response to midi input. More...
 Play a note in response to midi input. More...
 
void noteOff (byte channel, byte pitch, byte velocity)
 Stop a note in response to midi input. More...
 Stop a note in response to midi input. More...
 
void setPDEnv (int attack, int decay)
 Set the resonant filter sweep parameters. More...
 Set the resonant filter sweep parameters. More...
 
void update ()
 Update the filter sweep. More...
 Update the filter sweep. More...
 
int next ()
 Produce the audio output. More...
 Produce the audio output. More...
 

Member Function Documentation

@@ -164,9 +160,9 @@

Produce the audio output.

-

This goes in updateAudio().

+

This goes in updateAudio().

-

Definition at line 104 of file PDResonant.h.

+

Definition at line 102 of file PDResonant.h.

@@ -220,7 +216,7 @@

Definition at line 69 of file PDResonant.h.

+

Definition at line 67 of file PDResonant.h.

@@ -274,7 +270,7 @@

Definition at line 54 of file PDResonant.h.

+

Definition at line 52 of file PDResonant.h.

@@ -315,13 +311,13 @@

Parameters
- - + +
attackADSR attack
decayADSR decay
attackADSR attack
decayADSR decay

-

Definition at line 80 of file PDResonant.h.

+

Definition at line 78 of file PDResonant.h.

@@ -349,9 +345,9 @@

Update the filter sweep.

-

Use this in updateControl().

+

Use this in updateControl().

-

Definition at line 93 of file PDResonant.h.

+

Definition at line 91 of file PDResonant.h.

@@ -361,9 +357,7 @@

    - +
diff --git a/extras/doc/html/class_phasor-members.html b/extras/doc/html/class_phasor-members.html index 3eb60ec2a..55fc0b281 100644 --- a/extras/doc/html/class_phasor-members.html +++ b/extras/doc/html/class_phasor-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -118,9 +114,7 @@ diff --git a/extras/doc/html/class_phasor.html b/extras/doc/html/class_phasor.html index 3d9ee610f..57a2ff862 100644 --- a/extras/doc/html/class_phasor.html +++ b/extras/doc/html/class_phasor.html @@ -1,9 +1,9 @@ - + - + Mozzi: Phasor< UPDATE_RATE > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -107,7 +103,7 @@
-

Phasor repeatedly generates a high resolution ramp at a variable frequency. +

Phasor repeatedly generates a high resolution ramp at a variable frequency. More...

#include <Phasor.h>

@@ -115,10 +111,10 @@

template<unsigned int UPDATE_RATE>
class Phasor< UPDATE_RATE >

-

Phasor repeatedly generates a high resolution ramp at a variable frequency.

-

The output of Phasor.next() is an unsigned number between 0 and 4294967295, the maximum that can be expressed by an unsigned 32 bit integer.

Template Parameters
+

Phasor repeatedly generates a high resolution ramp at a variable frequency.

+

The output of Phasor.next() is an unsigned number between 0 and 4294967295, the maximum that can be expressed by an unsigned 32 bit integer.

Template Parameters
- +
UPDATE_RATEthe rate at which the Phasor will be updated, usually MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE.
UPDATE_RATEthe rate at which the Phasor will be updated, usually MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE.
@@ -128,25 +124,25 @@

Public Member Functions

 Phasor () - Constructor. More...
+ Constructor. More...
  uint32_t next () - Increments one step along the phase. More...
+ Increments one step along the phase. More...
  void set (uint32_t value) - Set the current value of the phasor. More...
+ Set the current value of the phasor. More...
  void setFreq (int frequency) - Set the Phasor frequency with an unsigned int. More...
+ Set the Phasor frequency with an unsigned int. More...
  void setFreq (float frequency) - Set the Phasor frequency with a float. More...
+ Set the Phasor frequency with a float. More...
  uint32_t phaseIncFromFreq (int frequency) - phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
  void setPhaseInc (uint32_t stepsize) - Set a specific phase increment. More...
+ Set a specific phase increment. More...
 

Constructor & Destructor Documentation

@@ -176,7 +172,7 @@

Constructor.

-

"Phasor <MOZZI_AUDIO_RATE> myphasor;" makes a Phasor which updates at MOZZI_AUDIO_RATE.

+

"Phasor <MOZZI_AUDIO_RATE> myphasor;" makes a Phasor which updates at MOZZI_AUDIO_RATE.

Definition at line 38 of file Phasor.h.

@@ -241,8 +237,8 @@

-

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

-

Instead of recalculating the phase increment for each frequency in between, you can just calculate the phase increment for each end frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and use setPhaseInc() to set the phase increment at each step. (Note: I should really profile this with the oscilloscope to see if it's worth the extra confusion!)

Parameters
+

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

+

Instead of recalculating the phase increment for each frequency in between, you can just calculate the phase increment for each end frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and use setPhaseInc() to set the phase increment at each step. (Note: I should really profile this with the oscilloscope to see if it's worth the extra confusion!)

Parameters
frequencyfor which you want to calculate a phase increment value.
@@ -281,14 +277,14 @@

Set the current value of the phasor.

-

The Phasor will continue incrementing from this value using any previously calculated step size.

+

The Phasor will continue incrementing from this value using any previously calculated step size.

Definition at line 56 of file Phasor.h.

- -

◆ setFreq() [1/2]

+ +

◆ setFreq() [1/2]

@@ -301,7 +297,7 @@

void Phasor< UPDATE_RATE >::setFreq ( - int  + float  frequency) @@ -313,21 +309,20 @@

-

Set the Phasor frequency with an unsigned int.

+

Set the Phasor frequency with a float.

Parameters
frequencyis how many times per second to count from 0 to the maximum uint32_t value 4294967295.
-
Note
Timing 8us
-

Definition at line 68 of file Phasor.h.

+

Definition at line 79 of file Phasor.h.

- -

◆ setFreq() [2/2]

+ +

◆ setFreq() [2/2]

@@ -340,7 +335,7 @@

void Phasor< UPDATE_RATE >::setFreq ( - float  + int  frequency) @@ -352,15 +347,16 @@

-

Set the Phasor frequency with a float.

+

Set the Phasor frequency with an unsigned int.

Parameters
frequencyis how many times per second to count from 0 to the maximum uint32_t value 4294967295.
+
Note
Timing 8us
-

Definition at line 79 of file Phasor.h.

+

Definition at line 68 of file Phasor.h.

@@ -391,9 +387,9 @@

Set a specific phase increment.

-

See phaseIncFromFreq().

Parameters
+

See phaseIncFromFreq().

Parameters
- +
stepsizea phase increment value as calculated by phaseIncFromFreq().
stepsizea phase increment value as calculated by phaseIncFromFreq().
@@ -408,9 +404,7 @@

    - +
diff --git a/extras/doc/html/class_phasor.js b/extras/doc/html/class_phasor.js index 6167a65c0..f81a478af 100644 --- a/extras/doc/html/class_phasor.js +++ b/extras/doc/html/class_phasor.js @@ -4,7 +4,7 @@ var class_phasor = [ "next", "class_phasor.html#a696198206182acaed5cf27fef226118d", null ], [ "phaseIncFromFreq", "class_phasor.html#a6e7656824ae72aea09ce851c7b340eaf", null ], [ "set", "class_phasor.html#ad9e0eceb175bca6b2b79130fd9c4f4ef", null ], - [ "setFreq", "class_phasor.html#afc6106c648bddb5f2f084b8f34216b0f", null ], [ "setFreq", "class_phasor.html#a81f1976ebb4a91f66f26674efca52072", null ], + [ "setFreq", "class_phasor.html#afc6106c648bddb5f2f084b8f34216b0f", null ], [ "setPhaseInc", "class_phasor.html#adf134d4e4ce960e4c773830fd8467e4b", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_portamento-members.html b/extras/doc/html/class_portamento-members.html index d8c973eae..32363bbbf 100644 --- a/extras/doc/html/class_portamento-members.html +++ b/extras/doc/html/class_portamento-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_portamento.html b/extras/doc/html/class_portamento.html index d60c5da7f..0fa201465 100644 --- a/extras/doc/html/class_portamento.html +++ b/extras/doc/html/class_portamento.html @@ -1,9 +1,9 @@ - + - + Mozzi: Portamento< CONTROL_UPDATE_RATE > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -126,16 +122,16 @@  Constructor.
  void setTime (unsigned int milliseconds) - Set how long it will take to slide from note to note, in milliseconds. More...
+ Set how long it will take to slide from note to note, in milliseconds. More...
  void start (uint8_t note) - Call this at note-on, it initialises the portamento. More...
+ Call this at note-on, it initialises the portamento. More...
  void start (Q16n16 note) - Call this at note-on, it initialises the portamento. More...
+ Call this at note-on, it initialises the portamento. More...
  Q16n16 next () - Use this in updateControl() to provide a frequency to the oscillator it's controlling. More...
+ Use this in updateControl() to provide a frequency to the oscillator it's controlling. More...
 

Member Function Documentation

@@ -164,7 +160,7 @@

-

Use this in updateControl() to provide a frequency to the oscillator it's controlling.

+

Use this in updateControl() to provide a frequency to the oscillator it's controlling.

For example: myOscil.setFreq_Q16n16(myPortamento.next());

Returns
a Q16n16 fractional frequency value, progressing smoothly between successive notes.

Definition at line 72 of file Portamento.h.

@@ -209,8 +205,8 @@

-

◆ start() [1/2]

+ +

◆ start() [1/2]

-

Definition at line 47 of file Portamento.h.

+

Definition at line 58 of file Portamento.h.

- -

◆ start() [2/2]

+ +

◆ start() [2/2]

-

Definition at line 58 of file Portamento.h.

+

Definition at line 47 of file Portamento.h.

@@ -291,9 +287,7 @@

    - +
diff --git a/extras/doc/html/class_portamento.js b/extras/doc/html/class_portamento.js index 72b64161f..4ee685c65 100644 --- a/extras/doc/html/class_portamento.js +++ b/extras/doc/html/class_portamento.js @@ -3,6 +3,6 @@ var class_portamento = [ "Portamento", "class_portamento.html#adc910a47d3fe8eff848d6de42d7280df", null ], [ "next", "class_portamento.html#ad39101f5275c433713df7699214638bc", null ], [ "setTime", "class_portamento.html#af19c3b3c189e111079f54211ff5a4ebe", null ], - [ "start", "class_portamento.html#aae67a74be47cb2e8a6ffbb90786221af", null ], - [ "start", "class_portamento.html#af70701abfdd9f3d788f3b313e38017d0", null ] + [ "start", "class_portamento.html#af70701abfdd9f3d788f3b313e38017d0", null ], + [ "start", "class_portamento.html#aae67a74be47cb2e8a6ffbb90786221af", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/class_r_cpoll-members.html b/extras/doc/html/class_r_cpoll-members.html index 04a00f289..66706c894 100644 --- a/extras/doc/html/class_r_cpoll-members.html +++ b/extras/doc/html/class_r_cpoll-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/class_r_cpoll.html b/extras/doc/html/class_r_cpoll.html index 37b73155c..730749151 100644 --- a/extras/doc/html/class_r_cpoll.html +++ b/extras/doc/html/class_r_cpoll.html @@ -1,9 +1,9 @@ - + - + Mozzi: RCpoll< SENSOR_PIN > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -107,8 +103,7 @@
-


-A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime. +

A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime. More...

#include <RCpoll.h>

@@ -116,11 +111,10 @@

template<unsigned char SENSOR_PIN>
class RCpoll< SENSOR_PIN >

-


-A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.

-

This is designed to be used in updateControl(). Each time it is called, it checks if a capacitor has charged, and returns an output reflecting how long it took for the most recent charge.

+

A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime.

+

This is designed to be used in updateControl(). Each time it is called, it checks if a capacitor has charged, and returns an output reflecting how long it took for the most recent charge.

-

Definition at line 12 of file RCpoll.h.

+

Definition at line 23 of file RCpoll.h.

@@ -129,7 +123,7 @@ - +

Public Member Functions

 Constructor.
 
unsigned int next ()
 Checks whether the capacitor has charged, and returns how long it took for the most recent charge. More...
 Checks whether the capacitor has charged, and returns how long it took for the most recent charge. More...
 

Member Function Documentation

@@ -159,9 +153,9 @@

Checks whether the capacitor has charged, and returns how long it took for the most recent charge.

-

This would preferably be called in updateControl(), but if the resolution isn't fine enough or the pin charges too fast for updateControl() to catch, try it in updateAudio().

Returns
the sensor value, reflected in how many checking cycles it took to charge the capacitor.
+

This would preferably be called in updateControl(), but if the resolution isn't fine enough or the pin charges too fast for updateControl() to catch, try it in updateAudio().

Returns
the sensor value, reflected in how many checking cycles it took to charge the capacitor.
-

Definition at line 29 of file RCpoll.h.

+

Definition at line 40 of file RCpoll.h.

@@ -171,9 +165,7 @@

    - +
diff --git a/extras/doc/html/class_resonant_filter-members.html b/extras/doc/html/class_resonant_filter-members.html index 1e4a86efc..f5ee5e923 100644 --- a/extras/doc/html/class_resonant_filter-members.html +++ b/extras/doc/html/class_resonant_filter-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -132,9 +128,7 @@ diff --git a/extras/doc/html/class_resonant_filter.html b/extras/doc/html/class_resonant_filter.html index ec43e4816..717d7f205 100644 --- a/extras/doc/html/class_resonant_filter.html +++ b/extras/doc/html/class_resonant_filter.html @@ -1,9 +1,9 @@ - + - + Mozzi: ResonantFilter< FILTER_TYPE, su > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -119,7 +115,7 @@

A generic resonant filter for audio signals.

-

Definition at line 76 of file ResonantFilter.h.

+

Definition at line 75 of file ResonantFilter.h.

@@ -128,17 +124,16 @@ - + - + - + - +

Public Member Functions

 Constructor.
 
void setCutoffFreq (su cutoff)
 deprecated. More...
 deprecated. More...
 
void setResonance (su resonance)
 deprecated. More...
 deprecated. More...
 
void setCutoffFreqAndResonance (su cutoff, su resonance)
 
-Set the cut off frequency and resonance. More...
 Set the cut off frequency and resonance. More...
 
AudioOutputStorage_t next (AudioOutputStorage_t in)
 Calculate the next sample, given an input signal. More...
 Calculate the next sample, given an input signal. More...
 
@@ -61,10 +57,10 @@

@@ -202,7 +197,7 @@

-template<int8_t FILTER_TYPE, typename su = uint8_t>
+template<int8_t FILTER_TYPE, typename su = uint8_t>
@@ -61,10 +57,10 @@
@@ -232,7 +227,7 @@

Returns
the signal output.
Note
Timing: about 11us.
-

Definition at line 129 of file ResonantFilter.h.

+

Definition at line 128 of file ResonantFilter.h.

@@ -242,7 +237,7 @@

-template<int8_t FILTER_TYPE, typename su = uint8_t>
+template<int8_t FILTER_TYPE, typename su = uint8_t>
- + - + - + - + - +
@@ -266,12 +261,12 @@

Parameters
- +
cutoffuse the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2. Be careful of distortion at the lower end, especially with high resonance.
cutoffuse the range 0-255 to represent 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, cutoff use the range 0-65535 to represent 0-MOZZI_AUDIO_RATE/2. Be careful of distortion at the lower end, especially with high resonance.
-

Definition at line 92 of file ResonantFilter.h.

+

Definition at line 91 of file ResonantFilter.h.

@@ -281,7 +276,7 @@

-template<int8_t FILTER_TYPE, typename su = uint8_t>
+template<int8_t FILTER_TYPE, typename su = uint8_t>
@@ -61,10 +57,10 @@
@@ -311,17 +306,16 @@

-


-Set the cut off frequency and resonance.

-

Replaces setCutoffFreq() and setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)

Parameters
+

Set the cut off frequency and resonance.

+

Replaces setCutoffFreq() and setResonance(). (Because the internal calculations need to be done whenever either parameter changes.)

Parameters
- - + +
cutoffrange 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16 Be careful of distortion at the lower end, especially with high resonance.
resonancerange 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
cutoffrange 0-255 represents 0-8191 Hz (MOZZI_AUDIO_RATE/2) for ResonantFilter, range 0-65535 for ResonantFilter16 Be careful of distortion at the lower end, especially with high resonance.
resonancerange 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, 255/65535 is most resonant.
-

Definition at line 115 of file ResonantFilter.h.

+

Definition at line 114 of file ResonantFilter.h.

@@ -331,7 +325,7 @@

-template<int8_t FILTER_TYPE, typename su = uint8_t>
+template<int8_t FILTER_TYPE, typename su = uint8_t>
@@ -61,10 +57,10 @@
@@ -355,13 +349,13 @@

Parameters
- +
resonancein the range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, with 255/65535 being most resonant
resonancein the range 0-255 for ResonantFilter, 0-65535 for ResonantFilter<FILTER_TYPE, uint16_t>, with 255/65535 being most resonant
Note
Remember to call setCuttoffFreq() after resonance is changed!
-

Definition at line 106 of file ResonantFilter.h.

+

Definition at line 105 of file ResonantFilter.h.

@@ -371,9 +365,7 @@

    - +
diff --git a/extras/doc/html/class_resonant_filter.js b/extras/doc/html/class_resonant_filter.js index 0c577beb1..f026c7913 100644 --- a/extras/doc/html/class_resonant_filter.js +++ b/extras/doc/html/class_resonant_filter.js @@ -2,9 +2,9 @@ var class_resonant_filter = [ [ "ResonantFilter", "class_resonant_filter.html#acd29c5e737fe80e0dc5c408113c3c282", null ], [ "advanceBuffers", "class_resonant_filter.html#abff68aae1ffc1bd9894e8f824365e84a", null ], - [ "current", "class_resonant_filter.html#adbf4efd639c951276ee5e8612b6818ee", null ], - [ "current", "class_resonant_filter.html#a0dc200c213651f770768cffff90bcf26", null ], [ "current", "class_resonant_filter.html#a319f11e6f6a9cfb3570a335bf1dc0866", null ], + [ "current", "class_resonant_filter.html#a0dc200c213651f770768cffff90bcf26", null ], + [ "current", "class_resonant_filter.html#adbf4efd639c951276ee5e8612b6818ee", null ], [ "current", "class_resonant_filter.html#a496a19cd2b4ce184374ce78bd83bbbee", null ], [ "fxmul", "class_resonant_filter.html#a8d6056a34164a1ed81732f1f09c75268", null ], [ "ifxmul", "class_resonant_filter.html#a98aafa9b6a65c3a9940c5c3b9394d135", null ], diff --git a/extras/doc/html/class_reverb_tank-members.html b/extras/doc/html/class_reverb_tank-members.html index e2275f61b..54e1c4358 100644 --- a/extras/doc/html/class_reverb_tank-members.html +++ b/extras/doc/html/class_reverb_tank-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_reverb_tank.html b/extras/doc/html/class_reverb_tank.html index 1b89215b0..d7cc88bcb 100644 --- a/extras/doc/html/class_reverb_tank.html +++ b/extras/doc/html/class_reverb_tank.html @@ -1,9 +1,9 @@ - + - + Mozzi: ReverbTank Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,15 +103,13 @@
-


-A reverb which sounds like the inside of a tin can. +

A reverb which sounds like the inside of a tin can. More...

#include <ReverbTank.h>

Detailed Description

-


-A reverb which sounds like the inside of a tin can.

-

ReverbTank is small enough to fit on the Arduino Nano, which for some reason wasn't able to fit a larger version which did fit on other 328 based boards. For simplicity, ReverbTank has hardcoded maximum delay sizes but also has default delay times which can be changed in the constructor or by setting during run time to allow live tweaking. This is a highly simplified design drawing on and probably misinterpreting Miller Puckette's G08.reverb recirculating reverb example for Pure Data.

+

A reverb which sounds like the inside of a tin can.

+

ReverbTank is small enough to fit on the Arduino Nano, which for some reason wasn't able to fit a larger version which did fit on other 328 based boards. For simplicity, ReverbTank has hardcoded maximum delay sizes but also has default delay times which can be changed in the constructor or by setting during run time to allow live tweaking. This is a highly simplified design drawing on and probably misinterpreting Miller Puckette's G08.reverb recirculating reverb example for Pure Data.

The room size according to the maximum delay lengths corresponds to:

early reflections and recirculating delay 1: 128/16384 seconds * 340.29 m/s speed of sound = 3.5 metres recirculating delay 2: 7 metres It looks bigger on paper than it sounds.

@@ -124,19 +118,19 @@

Public Member Functions

 ReverbTank (int8_t early_reflection1=37, int8_t early_reflection2=77, int8_t early_reflection3=127, int8_t loop1_delay=117, uint8_t loop2_delay=255, int8_t feedback_level=85)
 Constructor. More...
 Constructor. More...
 
int next (int input)
 Process the next audio sample and return the reverbed signal. More...
 Process the next audio sample and return the reverbed signal. More...
 
void setEarlyReflections (int8_t early_reflection1, int8_t early_reflection2, int8_t early_reflection3)
 Set the early reflection times in terms of delay cells. More...
 Set the early reflection times in terms of delay cells. More...
 
void setLoopDelays (int8_t loop1_delay, uint8_t loop2_delay)
 Set the loop delay times in terms of delay cells. More...
 Set the loop delay times in terms of delay cells. More...
 
void setFeebackLevel (int8_t feedback_level)
 Set the feedback level for the recirculating delays. More...
 Set the feedback level for the recirculating delays. More...
 

Constructor & Destructor Documentation

@@ -396,9 +390,7 @@

    - +
diff --git a/extras/doc/html/class_sample-members.html b/extras/doc/html/class_sample-members.html index b976f4495..3adf152e7 100644 --- a/extras/doc/html/class_sample-members.html +++ b/extras/doc/html/class_sample-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -129,9 +125,7 @@ diff --git a/extras/doc/html/class_sample.html b/extras/doc/html/class_sample.html index f6fd61faf..6efec21cd 100644 --- a/extras/doc/html/class_sample.html +++ b/extras/doc/html/class_sample.html @@ -1,9 +1,9 @@ - + - + Mozzi: Sample< NUM_TABLE_CELLS, UPDATE_RATE, INTERP > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,7 +103,7 @@
-

Sample is like Oscil, it plays a wavetable. +

Sample is like Oscil, it plays a wavetable. More...

#include <Sample.h>

@@ -115,11 +111,11 @@

template<unsigned int NUM_TABLE_CELLS, unsigned int UPDATE_RATE, uint8_t INTERP = INTERP_NONE>
class Sample< NUM_TABLE_CELLS, UPDATE_RATE, INTERP >

-

Sample is like Oscil, it plays a wavetable.

-

However, Sample can be set to play once through only, with variable start and end points, or can loop, also with variable start and end points. It defaults to playing once through the whole sound table, from start to finish.

Template Parameters
+

Sample is like Oscil, it plays a wavetable.

+

However, Sample can be set to play once through only, with variable start and end points, or can loop, also with variable start and end points. It defaults to playing once through the whole sound table, from start to finish.

Template Parameters
- - + +
NUM_TABLE_CELLSThis is defined in the table ".h" file the Sample will be using. The sound table can be arbitrary length for Sample. It's important that NUM_TABLE_CELLS is either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Sample to run fast enough.
UPDATE_RATEThis will be MOZZI_AUDIO_RATE if the Sample is updated in updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load.
NUM_TABLE_CELLSThis is defined in the table ".h" file the Sample will be using. The sound table can be arbitrary length for Sample. It's important that NUM_TABLE_CELLS is either a literal number (eg. "8192") or a defined macro, rather than a const or int, for the Sample to run fast enough.
UPDATE_RATEThis will be MOZZI_AUDIO_RATE if the Sample is updated in updateAudio(), or MOZZI_CONTROL_RATE if it's updated each time updateControl() is called. It could also be a fraction of MOZZI_CONTROL_RATE if you are doing some kind of cyclic updating in updateControl(), for example, to spread out the processor load.
@@ -132,26 +128,26 @@

Public Member Functions

 Sample (const int8_t *TABLE_NAME) - Constructor. More...
+ Constructor. More...
   Sample () - Constructor. More...
+ Constructor. More...
  void setTable (const int8_t *TABLE_NAME) - Change the sound table which will be played by the Sample. More...
+ Change the sound table which will be played by the Sample. More...
  void setStart (unsigned int startpos) - Sets the starting position in samples. More...
+ Sets the starting position in samples. More...
  void start () - Resets the phase (the playhead) to the start position, which will be 0 unless set to another value with setStart();.
+ Resets the phase (the playhead) to the start position, which will be 0 unless set to another value with setStart();.
  void start (unsigned int startpos) - Sets a new start position plays the sample from that position. More...
+ Sets a new start position plays the sample from that position. More...
  void setEnd (unsigned int end) - Sets the end position in samples from the beginning of the sound. More...
+ Sets the end position in samples from the beginning of the sound. More...
  void rangeWholeSample () @@ -166,29 +162,28 @@

 Turns looping off.
  int8_t next () - 
-Returns the sample at the current phase position, or 0 if looping is off and the phase overshoots the end of the sample. More...
+ Returns the sample at the current phase position, or 0 if looping is off and the phase overshoots the end of the sample. More...
  boolean isPlaying () - Checks if the sample is playing by seeing if the phase is within the limits of its end position. More...
+ Checks if the sample is playing by seeing if the phase is within the limits of its end position. More...
  void setFreq (int frequency) - Set the oscillator frequency with an unsigned int. More...
+ Set the oscillator frequency with an unsigned int. More...
  void setFreq (float frequency) - Set the sample frequency with a float. More...
+ Set the sample frequency with a float. More...
  void setFreq_Q24n8 (Q24n8 frequency) - Set the frequency using Q24n8 fixed-point number format. More...
+ Set the frequency using Q24n8 fixed-point number format. More...
  int8_t atIndex (unsigned int index) - Returns the sample at the given table index. More...
+ Returns the sample at the given table index. More...
  unsigned long phaseIncFromFreq (unsigned int frequency) - phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies. More...
  void setPhaseInc (unsigned long phaseinc_fractional) - Set a specific phase increment. More...
+ Set a specific phase increment. More...
 

Constructor & Destructor Documentation

@@ -221,7 +216,7 @@

Parameters
- +
TABLE_NAMEthe name of the array the Sample will be using. This can be found in the table ".h" file if you are using a table made for Mozzi by the int8_t2mozzi.py python script in Mozzi's python folder. Sound tables can be of arbitrary lengths for Sample().
TABLE_NAMEthe name of the array the Sample will be using. This can be found in the table ".h" file if you are using a table made for Mozzi by the int8_t2mozzi.py python script in Mozzi's python folder. Sound tables can be of arbitrary lengths for Sample().

@@ -256,7 +251,7 @@

Constructor.

-

Declare a Sample with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play. The table can be set or changed on the fly with setTable().

+

Declare a Sample with template TABLE_NUM_CELLS and UPDATE_RATE parameters, without specifying a particular wave table for it to play. The table can be set or changed on the fly with setTable().

Definition at line 71 of file Sample.h.

@@ -359,8 +354,7 @@

-


-Returns the sample at the current phase position, or 0 if looping is off and the phase overshoots the end of the sample.

+

Returns the sample at the current phase position, or 0 if looping is off and the phase overshoots the end of the sample.

Updates the phase according to the current frequency.

Returns
the next sample value from the table, or 0 if it's finished playing.

Definition at line 165 of file Sample.h.

@@ -393,8 +387,8 @@

-

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

-

Instead of recalculating the phase increment for each frequency in between, you can just calculate the phase increment for each end frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and use setPhaseInc() to set the phase increment at each step. (Note: I should really profile this with the oscilloscope to see if it's worth the extra confusion!)

Parameters
+

phaseIncFromFreq() and setPhaseInc() are for saving processor time when sliding between frequencies.

+

Instead of recalculating the phase increment for each frequency in between, you can just calculate the phase increment for each end frequency with phaseIncFromFreq(), then use a Line to interpolate on the fly and use setPhaseInc() to set the phase increment at each step. (Note: I should really profile this with the oscilloscope to see if it's worth the extra confusion!)

Parameters
frequencyfor which you want to calculate a phase increment value.
@@ -444,8 +438,8 @@

-

◆ setFreq() [1/2]

+ +

◆ setFreq() [1/2]

- -

◆ setFreq() [2/2]

+ +

◆ setFreq() [2/2]

@@ -585,9 +579,9 @@

Set a specific phase increment.

-

See phaseIncFromFreq().

Parameters
+

See phaseIncFromFreq().

Parameters
- +
phaseinc_fractionala phase increment value as calculated by phaseIncFromFreq().
phaseinc_fractionala phase increment value as calculated by phaseIncFromFreq().
@@ -660,7 +654,7 @@

-

Change the sound table which will be played by the Sample.

+

Change the sound table which will be played by the Sample.

Parameters
@@ -716,9 +710,7 @@

    - +
diff --git a/extras/doc/html/class_sample.js b/extras/doc/html/class_sample.js index ac6b1a98a..01369187e 100644 --- a/extras/doc/html/class_sample.js +++ b/extras/doc/html/class_sample.js @@ -8,8 +8,8 @@ var class_sample = [ "phaseIncFromFreq", "class_sample.html#a18e72ecdb7bac8d41038b785d6deba58", null ], [ "rangeWholeSample", "class_sample.html#a8a012ae52ee028222118f6bba5c7fb33", null ], [ "setEnd", "class_sample.html#a9713e2d38b94e629c06916a7543ef48f", null ], - [ "setFreq", "class_sample.html#aa0c37457f99def5c7036c6b6d9ee43fc", null ], [ "setFreq", "class_sample.html#a4d5840157e98024537ae10cd27ff9f9e", null ], + [ "setFreq", "class_sample.html#aa0c37457f99def5c7036c6b6d9ee43fc", null ], [ "setFreq_Q24n8", "class_sample.html#a903c2d634b10ac531c3c9f6a35fcb046", null ], [ "setLoopingOff", "class_sample.html#accfdc762cd47425824179bff4cd2a78f", null ], [ "setLoopingOn", "class_sample.html#a40e76011d841b84d2d54bf2cec6c4d5f", null ], diff --git a/extras/doc/html/class_sample_huffman-members.html b/extras/doc/html/class_sample_huffman-members.html index af44d509a..b23dbc7e4 100644 --- a/extras/doc/html/class_sample_huffman-members.html +++ b/extras/doc/html/class_sample_huffman-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

@@ -61,10 +57,10 @@
TABLE_NAMEis the name of the array in the table ".h" file you're using.
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +

- +
@@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_sample_huffman.html b/extras/doc/html/class_sample_huffman.html index c442d62a0..3e5ca403d 100644 --- a/extras/doc/html/class_sample_huffman.html +++ b/extras/doc/html/class_sample_huffman.html @@ -1,9 +1,9 @@ - + - + Mozzi: SampleHuffman Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -115,22 +111,22 @@

A sample player for samples encoded with Huffman compression.

This class and the audio2huff.py script are adapted from "audioout", an Arduino sketch by Thomas Grill, 2011 http//grrrr.org

Huffman decoding is used on sample differentials, saving 50-70% of space for 8 bit data, depending on the sample rate.

-

This implementation just plays back one sample each time next() is called, with no speed or other adjustments. It's slow, so it's likely you will only be able to play one sound at a time.

+

This implementation just plays back one sample each time next() is called, with no speed or other adjustments. It's slow, so it's likely you will only be able to play one sound at a time.

Audio data, Huffman decoder table, sample rate and bit depth are defined in a sounddata.h header file. This file can be generated for a sound file with the accompanying Python script audio2huff.py, in Mozzi/extras/python/

Invoke with: python audio2huff.py –sndfile=arduinosnd.wav –hdrfile=sounddata.h –bits=8 –name=soundtablename

You can resample and dither your audio file with SOX, e.g. to 8 bits depth @ Mozzi's 16384 Hz sample rate: sox fullglory.wav -b 8 -r 16384 arduinosnd.wav

Alternatively you can export a sound from Audacity, which seems to have less noticeable or no dithering, using Project Rate 16384 Hz and these output options: Other uncompressed files, Header: WAV(Microsoft), Encoding: Unsigned 8 bit PCM

The header file contains two lengthy arrays: One is "SOUNDDATA" which must fit into Flash RAM (available in total: 32k for ATMega328) The other is "HUFFMAN" which must also fit into Flash RAM

-

Definition at line 49 of file SampleHuffman.h.

+

Definition at line 50 of file SampleHuffman.h.

- + - + @@ -196,7 +192,7 @@

Definition at line 59 of file SampleHuffman.h.

+

Definition at line 60 of file SampleHuffman.h.

@@ -228,7 +224,7 @@

Returns
the next audio sample
Note
timing: about 5 to 40 us, varies continuously depending on data
-

Definition at line 70 of file SampleHuffman.h.

+

Definition at line 71 of file SampleHuffman.h.

@@ -238,9 +234,7 @@

    - +
diff --git a/extras/doc/html/class_smooth-members.html b/extras/doc/html/class_smooth-members.html index 8cfd16894..4f150a862 100644 --- a/extras/doc/html/class_smooth-members.html +++ b/extras/doc/html/class_smooth-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@

@@ -61,10 +57,10 @@

Public Member Functions

 SampleHuffman (uint8_t const *SOUNDDATA, int16_t const *HUFFMAN_DATA, uint32_t const SOUNDDATA_BITS)
 Constructor. More...
 Constructor. More...
 
int16_t next ()
 Update and return the next audio sample. More...
 Update and return the next audio sample. More...
 
void setLoopingOn ()
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_smooth.html b/extras/doc/html/class_smooth.html index b382d649c..4d5224724 100644 --- a/extras/doc/html/class_smooth.html +++ b/extras/doc/html/class_smooth.html @@ -1,9 +1,9 @@ - + - + Mozzi: Smooth< T > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -129,19 +125,19 @@

Public Member Functions

 Smooth (float smoothness) - Constructor. More...
+ Constructor. More...
   Smooth () - Constructor. More...
+ Constructor. More...
  T next (T in) - Filters the input and returns the filtered value. More...
+ Filters the input and returns the filtered value. More...
  T operator() (T n) - Filters the input and returns the filtered value. More...
+ Filters the input and returns the filtered value. More...
  void setSmoothness (float smoothness) - Sets how much smoothing the filter will apply to its input. More...
+ Sets how much smoothing the filter will apply to its input. More...
 

Constructor & Destructor Documentation

@@ -209,7 +205,7 @@

Constructor.

-

This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition. You need to call setSmoothness(float) for your object before using Smooth.

Note
there's probably a better way to do this...
+

This constructor which doesn't take a smoothness parameter is useful when you incorporate Smooth into another class definition. You need to call setSmoothness(float) for your object before using Smooth.

Note
there's probably a better way to do this...

Definition at line 57 of file Smooth.h.

@@ -338,9 +334,7 @@

    - +

diff --git a/extras/doc/html/class_stack-members.html b/extras/doc/html/class_stack-members.html index 5277ad73e..55c6979e2 100644 --- a/extras/doc/html/class_stack-members.html +++ b/extras/doc/html/class_stack-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -114,9 +110,7 @@ diff --git a/extras/doc/html/class_stack.html b/extras/doc/html/class_stack.html index ca3880a1c..020bd6d81 100644 --- a/extras/doc/html/class_stack.html +++ b/extras/doc/html/class_stack.html @@ -1,9 +1,9 @@ - + - + Mozzi: Stack< T, NUM_ITEMS > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -133,10 +129,10 @@  Constructor.
  void push (T item) - Put an item on the stack. More...
+ Put an item on the stack. More...
  T pop () - Get the item on top of the stack. More...
+ Get the item on top of the stack. More...
 

Member Function Documentation

@@ -216,9 +212,7 @@

    - +

diff --git a/extras/doc/html/class_state_variable-members.html b/extras/doc/html/class_state_variable-members.html index 96f8e0c25..ca17334bf 100644 --- a/extras/doc/html/class_state_variable-members.html +++ b/extras/doc/html/class_state_variable-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -115,9 +111,7 @@ diff --git a/extras/doc/html/class_state_variable.html b/extras/doc/html/class_state_variable.html index 7c613fd09..94c7e03ab 100644 --- a/extras/doc/html/class_state_variable.html +++ b/extras/doc/html/class_state_variable.html @@ -1,9 +1,9 @@ - + - + Mozzi: StateVariable< FILTER_TYPE > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -107,9 +103,7 @@
-


-
-State Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and http://www.musicdsp.org/showone.php?id=142. +

State Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and. More...

#include <StateVariable.h>

@@ -117,10 +111,8 @@

template<int8_t FILTER_TYPE>
class StateVariable< FILTER_TYPE >

-


-
-State Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and http://www.musicdsp.org/showone.php?id=142.

-

Here's the original:

+

State Variable Filter (approximation of Chamberlin version) Informed by pseudocode at http://www.musicdsp.org/showone.php?id=23 and.

+

http://www.musicdsp.org/showone.php?id=142. Here's the original:

cutoff = cutoff freq in Hz fs = sampling frequency //(e.g. 44100Hz) f = 2 sin (pi * cutoff / fs) //[approximately] q = resonance/bandwidth [0 < q <= 1] most res: q=1, less: q=0 low = lowpass output high = highpass output band = bandpass output notch = notch output

scale = q

low=high=band=0;

@@ -133,7 +125,7 @@

Here's the original:

Note
To save processing time, this version of the filter does not saturate internally, so any resonant peaks are unceremoniously truncated. It may be worth adding code to constrain the internal variables to enable resonant saturating effects.
-

Definition at line 66 of file StateVariable.h.

+

Definition at line 65 of file StateVariable.h.

@@ -142,13 +134,13 @@

Here's the original:

- + - + - +

Public Member Functions

 Constructor.
 
void setResonance (Q0n8 resonance)
 Set how resonant the filter will be. More...
 Set how resonant the filter will be. More...
 
void setCentreFreq (unsigned int centre_freq)
 Set the centre or corner frequency of the filter. More...
 Set the centre or corner frequency of the filter. More...
 
int next (int input)
 Calculate the next sample, given an input signal. More...
 Calculate the next sample, given an input signal. More...
 

Member Function Documentation

@@ -188,7 +180,7 @@

Returns
the signal output.

Note
Timing: 16 - 20 us
-

Definition at line 113 of file StateVariable.h.

+

Definition at line 112 of file StateVariable.h.

@@ -229,7 +221,7 @@

-

Definition at line 95 of file StateVariable.h.

+

Definition at line 94 of file StateVariable.h.

@@ -268,7 +260,7 @@

Note
Timing < 500 ns
-

Definition at line 80 of file StateVariable.h.

+

Definition at line 79 of file StateVariable.h.

@@ -278,9 +270,7 @@

    - +
diff --git a/extras/doc/html/class_wave_folder-members.html b/extras/doc/html/class_wave_folder-members.html index 2bc69e0df..9cc4e92f2 100644 --- a/extras/doc/html/class_wave_folder-members.html +++ b/extras/doc/html/class_wave_folder-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/class_wave_folder.html b/extras/doc/html/class_wave_folder.html index 9137bf7d1..a58349de6 100644 --- a/extras/doc/html/class_wave_folder.html +++ b/extras/doc/html/class_wave_folder.html @@ -1,9 +1,9 @@ - + - + Mozzi: WaveFolder< T > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -117,7 +113,7 @@

A simple wavefolder.

-

Definition at line 38 of file WaveFolder.h.

+

Definition at line 37 of file WaveFolder.h.

@@ -126,16 +122,16 @@ - + - + - + - +

Public Member Functions

 Constructor.
 
void setHighLimit (T highLimit)
 Set the high limit where the wave will start to be folded back the other way. More...
 Set the high limit where the wave will start to be folded back the other way. More...
 
void setLowLimit (T lowLimit)
 Set the low limit where the wave will start to be folded back the other way. More...
 Set the low limit where the wave will start to be folded back the other way. More...
 
void setLimits (T lowLimit, T highLimit)
 Set the low and the high limits at the same time. More...
 Set the low and the high limits at the same time. More...
 
next (T in)
 Return the next folded sample. More...
 Return the next folded sample. More...
 

Member Function Documentation

@@ -174,7 +170,7 @@

Returns
the folded output.
-

Definition at line 86 of file WaveFolder.h.

+

Definition at line 85 of file WaveFolder.h.

@@ -212,7 +208,7 @@

Definition at line 49 of file WaveFolder.h.

+

Definition at line 48 of file WaveFolder.h.

@@ -262,7 +258,7 @@

Note
highLimit MUST be higher than lowLimit
-

Definition at line 73 of file WaveFolder.h.

+

Definition at line 72 of file WaveFolder.h.

@@ -300,7 +296,7 @@

Definition at line 60 of file WaveFolder.h.

+

Definition at line 59 of file WaveFolder.h.

@@ -310,9 +306,7 @@

    - +
diff --git a/extras/doc/html/class_wave_packet-members.html b/extras/doc/html/class_wave_packet-members.html index 4ff1fa351..9a003b2df 100644 --- a/extras/doc/html/class_wave_packet-members.html +++ b/extras/doc/html/class_wave_packet-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -117,9 +113,7 @@ diff --git a/extras/doc/html/class_wave_packet.html b/extras/doc/html/class_wave_packet.html index 7c97f2db5..291701740 100644 --- a/extras/doc/html/class_wave_packet.html +++ b/extras/doc/html/class_wave_packet.html @@ -1,9 +1,9 @@ - + - + Mozzi: WavePacket< ALGORITHM > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -108,8 +104,7 @@
-


-Wavepacket synthesis, with two overlapping streams of wave packets. +

Wavepacket synthesis, with two overlapping streams of wave packets. More...

#include <WavePacket.h>

@@ -122,14 +117,13 @@ WavePacketSample< ALGORITHM > - -
+ +

Detailed Description

template<int8_t ALGORITHM>
class WavePacket< ALGORITHM >

-


-Wavepacket synthesis, with two overlapping streams of wave packets.

+

Wavepacket synthesis, with two overlapping streams of wave packets.

Draws on Miller Puckette's Pure Data example, F14.wave.packet.pd. Each packet is an enveloped grain of a sin (or cos) wave. The frequency of the wave, the width of the envelopes and the rate of release of envelopes are the parameters which can be changed.

Template Parameters
@@ -146,19 +140,19 @@ - + - + - + - + - +
ALGORITHMoptions are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
 Constructor.
 
void set (int fundamental, int bandwidth, int centrefreq)
 Set all the parameters for the synthesis. More...
 Set all the parameters for the synthesis. More...
 
void setFundamental (int fundamental)
 Set the fundamental frequency. More...
 Set the fundamental frequency. More...
 
void setBandwidth (int bandwidth)
 Set the bandwidth. More...
 Set the bandwidth. More...
 
void setCentreFreq (int centrefreq)
 Set the centre frequency. More...
 Set the centre frequency. More...
 
int next ()
 Calculate the next synthesised sample. More...
 Calculate the next synthesised sample. More...
 

Member Function Documentation

@@ -240,8 +234,8 @@

Parameters
- +
fundamentalthe rate at which packets are produced.
bandwidththe width of each packet. A lower value allows more of the centre frequency to be audible, a rounder sound.
-A higher value produces narrower packets, a more buzzing sound.
bandwidththe width of each packet. A lower value allows more of the centre frequency to be audible, a rounder sound.
+ A higher value produces narrower packets, a more buzzing sound.
centrefreqthe oscillation frequency within each packet.
@@ -280,8 +274,8 @@

Parameters
- +
bandwidththe width of each packet. A lower value allows more of the centre frequency to be audible, a rounder sound.
-A higher value produces narrower packets, a more buzzing sound.
bandwidththe width of each packet. A lower value allows more of the centre frequency to be audible, a rounder sound.
+ A higher value produces narrower packets, a more buzzing sound.

@@ -372,9 +366,7 @@

    - +

diff --git a/extras/doc/html/class_wave_packet_sample-members.html b/extras/doc/html/class_wave_packet_sample-members.html index 66c273e2a..8f6b81373 100644 --- a/extras/doc/html/class_wave_packet_sample-members.html +++ b/extras/doc/html/class_wave_packet_sample-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -118,9 +114,7 @@ diff --git a/extras/doc/html/class_wave_packet_sample.html b/extras/doc/html/class_wave_packet_sample.html index c1aa806bf..bd1ff6274 100644 --- a/extras/doc/html/class_wave_packet_sample.html +++ b/extras/doc/html/class_wave_packet_sample.html @@ -1,9 +1,9 @@ - + - + Mozzi: WavePacketSample< ALGORITHM > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -107,7 +103,7 @@
-

A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains). +

A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains). More...

#include <WavePacketSample.h>

@@ -119,14 +115,14 @@
-WavePacket< ALGORITHM > - -
+WavePacket< ALGORITHM > + +

Detailed Description

template<int8_t ALGORITHM>
class WavePacketSample< ALGORITHM >

-

A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains).

+

A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains).

Template Parameters
@@ -134,27 +130,27 @@ -

Definition at line 22 of file WavePacketSample.h.

+

Definition at line 23 of file WavePacketSample.h.

ALGORITHMoptions are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
- + - + - + - + - + - +

Public Member Functions

void setTable (const int8_t *TABLE_NAME)
 Change the sound table which will be played. More...
 Change the sound table which will be played. More...
 
void set (int fundamental, int bandwidth, int centrefreq)
 Set all the parameters for the synthesis. More...
 Set all the parameters for the synthesis. More...
 
void setFundamental (int fundamental)
 Set the fundamental frequency. More...
 Set the fundamental frequency. More...
 
void setBandwidth (int bandwidth)
 Set the bandwidth. More...
 Set the bandwidth. More...
 
void setCentreFreq (int centrefreq)
 Set the centre frequency. More...
 Set the centre frequency. More...
 
int next ()
 Calculate the next synthesised sample. More...
 Calculate the next synthesised sample. More...
 

Member Function Documentation

@@ -236,8 +232,8 @@

Parameters
- +
fundamentalthe rate at which packets are produced.
bandwidththe width of each packet. A lower value allows more of the centre frequency to be audible, a rounder sound.
-A higher value produces narrower packets, a more buzzing sound.
bandwidththe width of each packet. A lower value allows more of the centre frequency to be audible, a rounder sound.
+ A higher value produces narrower packets, a more buzzing sound.
centrefreqthe oscillation frequency within each packet.
@@ -276,8 +272,8 @@

Parameters
- +
bandwidththe width of each packet. A lower value allows more of the centre frequency to be audible, a rounder sound.
-A higher value produces narrower packets, a more buzzing sound.
bandwidththe width of each packet. A lower value allows more of the centre frequency to be audible, a rounder sound.
+ A higher value produces narrower packets, a more buzzing sound.

@@ -396,7 +392,7 @@

Definition at line 29 of file WavePacketSample.h.

+

Definition at line 30 of file WavePacketSample.h.

@@ -406,9 +402,7 @@

    - +
diff --git a/extras/doc/html/class_wave_shaper.html b/extras/doc/html/class_wave_shaper.html index afa825193..407b8647c 100644 --- a/extras/doc/html/class_wave_shaper.html +++ b/extras/doc/html/class_wave_shaper.html @@ -1,9 +1,9 @@ - + - + Mozzi: WaveShaper< T > Class Template Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -104,7 +100,7 @@
-

WaveShaper maps values from its input to values in a table, which are returned as output. +

WaveShaper maps values from its input to values in a table, which are returned as output. More...

#include <WaveShaper.h>

@@ -112,7 +108,7 @@

template<class T>
class WaveShaper< T >

-

WaveShaper maps values from its input to values in a table, which are returned as output.

+

WaveShaper maps values from its input to values in a table, which are returned as output.

Template Parameters
@@ -127,9 +123,7 @@ diff --git a/extras/doc/html/class_wave_shaper_3_01char_01_4-members.html b/extras/doc/html/class_wave_shaper_3_01char_01_4-members.html index 64774a001..2e0e9ed5f 100644 --- a/extras/doc/html/class_wave_shaper_3_01char_01_4-members.html +++ b/extras/doc/html/class_wave_shaper_3_01char_01_4-members.html @@ -1,9 +1,9 @@ - + - +Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@ @@ -61,10 +57,10 @@
Tthe type of numbers being input to be shaped, chosen to match the table.
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/class_wave_shaper_3_01char_01_4.html b/extras/doc/html/class_wave_shaper_3_01char_01_4.html index 51e21a808..2722a190c 100644 --- a/extras/doc/html/class_wave_shaper_3_01char_01_4.html +++ b/extras/doc/html/class_wave_shaper_3_01char_01_4.html @@ -1,11 +1,11 @@ - + - + -Mozzi: WaveShaper< char > Class Template Reference +Mozzi: WaveShaper< char > Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
-
WaveShaper< char > Class Template Reference
+
WaveShaper< char > Class Reference
-

int8_t specialisation of WaveShaper template +

int8_t specialisation of WaveShaper template More...

#include <WaveShaper.h>

Detailed Description

-

template<>
-class WaveShaper< char >

- -

int8_t specialisation of WaveShaper template

+

int8_t specialisation of WaveShaper template

Definition at line 29 of file WaveShaper.h.

- + - +

Public Member Functions

 WaveShaper (const int8_t *TABLE_NAME)
 Constructor. More...
 Constructor. More...
 
int8_t next (byte in)
 Maps input to output, transforming it according to the table being used. More...
 Maps input to output, transforming it according to the table being used. More...
 

Constructor & Destructor Documentation

@@ -154,7 +147,7 @@

Constructor.

-

Use the template parameter to set type of numbers being mapped. For example, WaveShaper <int> myWaveShaper; makes a WaveShaper which uses ints.

Template Parameters
+

Use the template parameter to set type of numbers being mapped. For example, WaveShaper <int> myWaveShaper; makes a WaveShaper which uses ints.

Template Parameters
Tthe type of numbers being input to be shaped, chosen to match the table.
@@ -199,7 +192,7 @@

Parameters
- +
inthe input signal. For flexibility, it's up to you to give the correct offset to your input signal. So if you're mapping a signed 8-bit signal (such as the output of an Oscil) into a 256 cell table centred around cell 128, add 128 to offset the input value.
inthe input signal. For flexibility, it's up to you to give the correct offset to your input signal. So if you're mapping a signed 8-bit signal (such as the output of an Oscil) into a 256 cell table centred around cell 128, add 128 to offset the input value.

@@ -215,9 +208,7 @@

    - +

diff --git a/extras/doc/html/class_wave_shaper_3_01int_01_4-members.html b/extras/doc/html/class_wave_shaper_3_01int_01_4-members.html index 29e52c7b4..02ea69426 100644 --- a/extras/doc/html/class_wave_shaper_3_01int_01_4-members.html +++ b/extras/doc/html/class_wave_shaper_3_01int_01_4-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member List @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/class_wave_shaper_3_01int_01_4.html b/extras/doc/html/class_wave_shaper_3_01int_01_4.html index a6c033d40..5f05aaa8c 100644 --- a/extras/doc/html/class_wave_shaper_3_01int_01_4.html +++ b/extras/doc/html/class_wave_shaper_3_01int_01_4.html @@ -1,11 +1,11 @@ - + - + -Mozzi: WaveShaper< int > Class Template Reference +Mozzi: WaveShaper< int > Class Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
-
WaveShaper< int > Class Template Reference
+
WaveShaper< int > Class Reference
-

int specialisation of WaveShaper template +

int specialisation of WaveShaper template More...

#include <WaveShaper.h>

Detailed Description

-

template<>
-class WaveShaper< int >

- -

int specialisation of WaveShaper template

+

int specialisation of WaveShaper template

Definition at line 65 of file WaveShaper.h.

- + - +

Public Member Functions

 WaveShaper (const int16_t *TABLE_NAME)
 Constructor. More...
 Constructor. More...
 
int next (int in)
 Maps input to output, transforming it according to the table being used. More...
 Maps input to output, transforming it according to the table being used. More...
 

Constructor & Destructor Documentation

@@ -154,7 +147,7 @@

Constructor.

-

Use the template parameter to set type of numbers being mapped. For example, WaveShaper <int> myWaveShaper; makes a WaveShaper which uses ints.

Template Parameters
+

Use the template parameter to set type of numbers being mapped. For example, WaveShaper <int> myWaveShaper; makes a WaveShaper which uses ints.

Template Parameters
Tthe type of numbers being input to be shaped, chosen to match the table.
@@ -199,7 +192,7 @@

Parameters
- +
inthe input signal. For flexibility, it's up to you to give the correct offset to your input signal. So if you're mapping a signed 9-bit signal (such as the sum of 2 8-bit Oscils) into a 512 cell table centred around cell 256, add 256 to offset the input value. With a sigmoid table, this may be useful for compressing a bigger signal into the -244 to 243 output range of Mozzi, rather than dividing the signal and returning a int8_t from updateAudio().
inthe input signal. For flexibility, it's up to you to give the correct offset to your input signal. So if you're mapping a signed 9-bit signal (such as the sum of 2 8-bit Oscils) into a 512 cell table centred around cell 256, add 256 to offset the input value. With a sigmoid table, this may be useful for compressing a bigger signal into the -244 to 243 output range of Mozzi, rather than dividing the signal and returning a int8_t from updateAudio().

@@ -215,9 +208,7 @@

    - +

diff --git a/extras/doc/html/classes.html b/extras/doc/html/classes.html index bc87b2379..6112498da 100644 --- a/extras/doc/html/classes.html +++ b/extras/doc/html/classes.html @@ -1,9 +1,9 @@ - + - + Mozzi: Class Index @@ -13,10 +13,6 @@ - @@ -37,13 +33,13 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -103,47 +99,51 @@
Class Index
-
a | c | d | e | i | l | m | o | p | r | s | w
- - - - - - - - - - - - - - - - - - -
  a  
-
  e  
-
Line< unsigned char >   Phasor   StateVariable   
Line< unsigned int >   Portamento   StereoOutput   
ADSR   Ead   Line< unsigned long >   
  r  
-
  w  
-
AudioDelay   EventDelay   
  m  
-
AudioDelayFeedback   
  i  
-
RCpoll   WaveFolder   
AutoMap   MetaOscil   ResonantFilter   WavePacket   
AutoRange   Int2Type   Metronome   ReverbTank   WavePacketSample   
  c  
-
IntegerType   MonoOutput   RollingAverage   WaveShaper   
IntegerType< 1 >   MultiResonantFilter   RollingStat   WaveShaper< char >   
CapPoll   IntegerType< 2 >   
  o  
-
  s  
-
WaveShaper< int >   
CircularBuffer   IntegerType< 4 >   
ControlDelay   IntegerType< 8 >   Oscil   Sample   
  d  
-
IntMap   OverSample   SampleHuffman   
  l  
-
  p  
-
Smooth   
DCfilter   Stack   
Line   PDResonant   
-
a | c | d | e | i | l | m | o | p | r | s | w
+
A | C | D | E | I | L | M | O | P | R | S | W
+
diff --git a/extras/doc/html/config__checks__avr_8h_source.html b/extras/doc/html/config__checks__avr_8h_source.html index 18c323117..73acce6eb 100644 --- a/extras/doc/html/config__checks__avr_8h_source.html +++ b/extras/doc/html/config__checks__avr_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_avr.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,185 @@
config_checks_avr.h
-
1 /* For Mozzi-internal use: Apply hardware specific config defaults and config checks: AVR */
2 
3 /** @defgroup hardware
4  *
5  * @details This page details hardware specific notes, and availabe configuration options for the various platforms. */
6 
7 /** @ingroup hardware
8  * @page hardware_avr Mozzi on classic Arduino, Teensy 2.x, Arduino Mega, and other 8 bit "AVR"/ATMEGA architecture boards
9  *
10  * @section avr_status Port status and notes
11  * This is the original "port" of Mozzi, and thus very elaborate. The main challenges on this platform, compared to other MCUs, are limitations in
12  * flash, RAM, and CPU power.
13  *
14  * @section avr_output Output modes
15  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
16  * - MOZZI_OUTPUT_PWM
17  * - MOZZI_OUTPUT_2PIN_PWM
18  * - MOZZI_OUTPUT_EXTERNAL_TIMED
19  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
20  *
21  * In all modes, except MOZZI_OUTPUT_EXTERNAL_CUSTOM, Timer 1 is claimed, and is not available for any other purpose.
22  * This means, among other things, that pins 9 and 10 cannot be used for analogWrite(), while pins 3 and 11 should still be available
23  * @em except in MOZZI_OUTPUT_2PIN_PWM mode (as Timer2 is also claimed, then; for definite info on which pin is connected to which timer,
24  * check a suitable reference, as your board may differ). See *Mozzi>examples>11.Communication>Sinewave_PWM_pins_HIFI*. for an example
25  * of emulating analogWrite() on any digital pin, without the need for a hardware timer.
26  *
27  * @section avr_pwm MOZZI_OUTPUT_PWM
28  * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured
29  * within this tight limit. In particular, the default setup on the
30  * Arduino UNO is:
31  * - Mono: Pin 9 -> configurable using MOZZI_AUDIO_PIN_1
32  * - Stereo: Pin 9 (left) and Pin 10 (right) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_2
33  * For pinouts on other boards, refer to config/known_16bit_timers.
34  *
35  * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE: MOZZI_PWM_RATE.
36  *
37  * The available sample resolution is 488, i.e. almost 9 bits, providing some headroom above the 8 bit table resolution
38  * currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate.
39  *
40  * @section avr_2pin_pwm MOZZI_OUTPUT_2PIN_PWM
41  * In this mode, output is split across two pins (again, both connected to Timer 1), with each outputting 7 bits for a total of 14. This allows for
42  * much better dynamic range, providing much more definition than can be achieved using @ref avr_pwm , while using
43  * only modestly more processing power. Further, it allows for a much higher PWM carrier rate can be much higher (125 kHz by default; see @ref
44  * MOZZI_PWM_RATE), which is well beyond the audible range.
45  *
46  * On the downside, this mode requires an extra hardware timer (Timer2 in addition to Timer1), which may increase compatibility
47  * problems with other Arduino libraries that also require a timer. Further, a more elaborate hardware setup is needed, making it less convenient
48  * for rapid prototyping. For circuit details, see https://sensorium.github.io/Mozzi/learn/output/ .
49  *
50  * On the classic Arduino Uno, the default pinout in this mode is:
51  * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW
52  *
53  * Here is table of the default pins on some other boards. Rows with an x on it have actually been tested (and importantly, the outcome recoreded;
54  * input welcome on further boards.)
55  *
56  * resistor.....3.9k......499k \n
57  * x................9..........10...............Arduino Uno \n
58  * x................9..........10...............Arduino Duemilanove \n
59  * x................9..........10...............Arduino Nano \n
60  * x................9..........10...............Arduino Leonardo \n
61  * x................9..........10...............Ardweeny \n
62  * x................9..........10...............Boarduino \n
63  * x...............11.........12...............Freetronics EtherMega \n
64  * .................11.........12...............Arduino Mega \n
65  * .................14.........15...............Teensy \n
66  * .............B5(14)...B6(15)...........Teensy2 \n
67  * x...........B5(25)...B6(26)...........Teensy2++ \n
68  * .................13.........12...............Sanguino \n
69  *
70  * For pinouts on other AVR boards, config/known_16bit_timers might contain some hints.
71  *
72  * Rate of the PWM output can be controlled separately from @ref MOZZI_AUDIO_RATE, and is much higher (125kHz), by default: @ref MOZZI_PWM_RATE.
73  *
74  * The default sample resolution is 7 bits per pin, for a total of 14 bits. This can be configured within hardware limits (@ref MOZZI_PWM_RATE) using
75  * @ref MOZZI_AUDIO_BITS_PER_CHANNEL, but beware that increasing this will require even more accuracy in our output resistors (see the linked documentation, above).
76  *
77  * @section avr_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
78  * See @ref external_audio
79 */
80 
81 
82 #if not defined(MOZZI_AUDIO_MODE)
83 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
84 #endif
85 
86 #if not defined(MOZZI_AUDIO_RATE)
87 #define MOZZI_AUDIO_RATE 16384
88 #endif
89 
90 #if not defined(MOZZI_ANALOG_READ)
91 #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
92 #endif
93 
94 // Pins for regular PWM output
95 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
96 # if !defined(MOZZI_AUDIO_PIN_1)
97 #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN
98 #define MOZZI_AUDIO_PIN_1_REGISTER OCR1A
99 # endif
100 # if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_2)
101 #define MOZZI_AUDIO_PIN_2 TIMER1_B_PIN
102 #define MOZZI_AUDIO_PIN_2_REGISTER OCR1B
103 # endif
104 
105 # if !defined(MOZZI_PWM_RATE)
106 #define MOZZI_PWM_RATE 32768
107 # endif
108 
109 #define MOZZI_AUDIO_BITS 8
110 #define MOZZI_AUDIO_BITS_OPTIMISTIC 9
111 #define MOZZI_AUDIO_BIAS ((uint8_t) 244)
112 #endif
113 
114 // Pins for 2 pin HIFI PWM output
115 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
116 # if !defined(MOZZI_AUDIO_PIN_1)
117 #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN
118 #define MOZZI_AUDIO_PIN_1_REGISTER OCR1A
119 # endif
120 # if !defined(MOZZI_AUDIO_PIN_1_LOW)
121 #define MOZZI_AUDIO_PIN_1_LOW TIMER1_B_PIN
122 #define MOZZI_AUDIO_PIN_1_LOW_REGISTER OCR1B
123 # endif
124 
125 # if !defined(MOZZI_PWM_RATE)
126 #define MOZZI_PWM_RATE 125000
127 # endif
128 
129 # if !defined(MOZZI_AUDIO_BITS_PER_CHANNEL)
130 #define MOZZI_AUDIO_BITS_PER_CHANNEL 7
131 # endif
132 
133 #define MOZZI_AUDIO_BITS (2*MOZZI_AUDIO_BITS_PER_CHANNEL)
134 #endif
135 
136 // Step 2: Check
137 // NOTE: This step is not technically required, but a good idea in any port
138 
139 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
140 
141 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
142 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO, MOZZI_STEREO)
143 #endif
144 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
145 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO)
146 #endif
147 
148 /** should we enforce the following?
149 #if (MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM))
150 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_RATE, 16384, 32768)
151 #endif */
152 
153 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
154 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD)
155 #include "../config/known_16bit_timers.h"
156 
157 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
158 # if defined(TIMER1_C_PIN)
159 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN, TIMER1_C_PIN);
160 # else
161 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN);
162 # endif
163 #endif
#define MOZZI_ANALOG_READ
Whether to compile in support for non-blocking analog reads.
-
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_avr.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 /* For Mozzi-internal use: Apply hardware specific config defaults and config checks: AVR */
+
13 
+
14 /** @ingroup hardware
+
15  * @page hardware_avr Mozzi on classic Arduino, Teensy 2.x, Arduino Mega, and other 8 bit "AVR"/ATMEGA architecture boards
+
16  *
+
17  * @section avr_status Port status and notes
+
18  * This is the original "port" of Mozzi, and thus very elaborate. The main challenges on this platform, compared to other MCUs, are limitations in
+
19  * flash, RAM, and CPU power.
+
20  *
+
21  * @section avr_output Output modes
+
22  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
23  * - MOZZI_OUTPUT_PWM
+
24  * - MOZZI_OUTPUT_2PIN_PWM
+
25  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
26  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
27  *
+
28  * In all modes, except MOZZI_OUTPUT_EXTERNAL_CUSTOM, Timer 1 is claimed, and is not available for any other purpose.
+
29  * This means, among other things, that pins 9 and 10 cannot be used for analogWrite(), while pins 3 and 11 should still be available
+
30  * @em except in MOZZI_OUTPUT_2PIN_PWM mode (as Timer2 is also claimed, then; for definite info on which pin is connected to which timer,
+
31  * check a suitable reference, as your board may differ). See *Mozzi>examples>11.Communication>Sinewave_PWM_pins_HIFI*. for an example
+
32  * of emulating analogWrite() on any digital pin, without the need for a hardware timer.
+
33  *
+
34  * @section avr_pwm MOZZI_OUTPUT_PWM
+
35  * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured
+
36  * within this tight limit. In particular, the default setup on the
+
37  * Arduino UNO is:
+
38  * - Mono: Pin 9 -> configurable using MOZZI_AUDIO_PIN_1
+
39  * - Stereo: Pin 9 (left) and Pin 10 (right) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_2
+
40  * For pinouts on other boards, refer to config/known_16bit_timers.
+
41  *
+
42  * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE: MOZZI_PWM_RATE.
+
43  *
+
44  * The available sample resolution is 488, i.e. almost 9 bits, providing some headroom above the 8 bit table resolution
+
45  * currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate.
+
46  *
+
47  * @section avr_2pin_pwm MOZZI_OUTPUT_2PIN_PWM
+
48  * In this mode, output is split across two pins (again, both connected to Timer 1), with each outputting 7 bits for a total of 14. This allows for
+
49  * much better dynamic range, providing much more definition than can be achieved using @ref avr_pwm , while using
+
50  * only modestly more processing power. Further, it allows for a much higher PWM carrier rate can be much higher (125 kHz by default; see @ref
+
51  * MOZZI_PWM_RATE), which is well beyond the audible range.
+
52  *
+
53  * On the downside, this mode requires an extra hardware timer (Timer2 in addition to Timer1), which may increase compatibility
+
54  * problems with other Arduino libraries that also require a timer. Further, a more elaborate hardware setup is needed, making it less convenient
+
55  * for rapid prototyping. For circuit details, see https://sensorium.github.io/Mozzi/learn/output/ .
+
56  *
+
57  * On the classic Arduino Uno, the default pinout in this mode is:
+
58  * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW
+
59  *
+
60  * Here is table of the default pins on some other boards. Rows with an x on it have actually been tested (and importantly, the outcome recoreded;
+
61  * input welcome on further boards.)
+
62  *
+
63  * resistor.....3.9k......499k \n
+
64  * x................9..........10...............Arduino Uno \n
+
65  * x................9..........10...............Arduino Duemilanove \n
+
66  * x................9..........10...............Arduino Nano \n
+
67  * x................9..........10...............Arduino Leonardo \n
+
68  * x................9..........10...............Ardweeny \n
+
69  * x................9..........10...............Boarduino \n
+
70  * x...............11.........12...............Freetronics EtherMega \n
+
71  * .................11.........12...............Arduino Mega \n
+
72  * .................14.........15...............Teensy \n
+
73  * .............B5(14)...B6(15)...........Teensy2 \n
+
74  * x...........B5(25)...B6(26)...........Teensy2++ \n
+
75  * .................13.........12...............Sanguino \n
+
76  *
+
77  * For pinouts on other AVR boards, config/known_16bit_timers might contain some hints.
+
78  *
+
79  * Rate of the PWM output can be controlled separately from @ref MOZZI_AUDIO_RATE, and is much higher (125kHz), by default: @ref MOZZI_PWM_RATE.
+
80  *
+
81  * The default sample resolution is 7 bits per pin, for a total of 14 bits. This can be configured within hardware limits (@ref MOZZI_PWM_RATE) using
+
82  * @ref MOZZI_AUDIO_BITS_PER_CHANNEL, but beware that increasing this will require even more accuracy in our output resistors (see the linked documentation, above).
+
83  *
+
84  * @section avr_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
85  * See @ref external_audio
+
86 */
+
87 
+
88 
+
89 #if not defined(MOZZI_AUDIO_MODE)
+
90 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
+
91 #endif
+
92 
+
93 #if not defined(MOZZI_AUDIO_RATE)
+
94 #define MOZZI_AUDIO_RATE 16384
+
95 #endif
+
96 
+
97 #if not defined(MOZZI_ANALOG_READ)
+
98 #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
99 #endif
+
100 
+
101 // Pins for regular PWM output
+
102 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
103 # if !defined(MOZZI_AUDIO_PIN_1)
+
104 #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN
+
105 #define MOZZI_AUDIO_PIN_1_REGISTER OCR1A
+
106 # endif
+
107 # if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_2)
+
108 #define MOZZI_AUDIO_PIN_2 TIMER1_B_PIN
+
109 #define MOZZI_AUDIO_PIN_2_REGISTER OCR1B
+
110 # endif
+
111 
+
112 # if !defined(MOZZI_PWM_RATE)
+
113 #define MOZZI_PWM_RATE 32768
+
114 # endif
+
115 
+
116 #define MOZZI_AUDIO_BITS 8
+
117 #define MOZZI_AUDIO_BITS_OPTIMISTIC 9
+
118 #define MOZZI_AUDIO_BIAS ((uint8_t) 244)
+
119 #endif
+
120 
+
121 // Pins for 2 pin HIFI PWM output
+
122 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
123 # if !defined(MOZZI_AUDIO_PIN_1)
+
124 #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN
+
125 #define MOZZI_AUDIO_PIN_1_REGISTER OCR1A
+
126 # endif
+
127 # if !defined(MOZZI_AUDIO_PIN_1_LOW)
+
128 #define MOZZI_AUDIO_PIN_1_LOW TIMER1_B_PIN
+
129 #define MOZZI_AUDIO_PIN_1_LOW_REGISTER OCR1B
+
130 # endif
+
131 
+
132 # if !defined(MOZZI_PWM_RATE)
+
133 #define MOZZI_PWM_RATE 125000
+
134 # endif
+
135 
+
136 # if !defined(MOZZI_AUDIO_BITS_PER_CHANNEL)
+
137 #define MOZZI_AUDIO_BITS_PER_CHANNEL 7
+
138 # endif
+
139 
+
140 #define MOZZI_AUDIO_BITS (2*MOZZI_AUDIO_BITS_PER_CHANNEL)
+
141 #endif
+
142 
+
143 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10
+
144 
+
145 // Step 2: Check
+
146 // NOTE: This step is not technically required, but a good idea in any port
+
147 
+
148 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
149 
+
150 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
151 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO, MOZZI_STEREO)
+
152 #endif
+
153 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
154 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO)
+
155 #endif
+
156 
+
157 /** should we enforce the following?
+
158 #if (MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM))
+
159 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_RATE, 16384, 32768)
+
160 #endif */
+
161 
+
162 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
+
163 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD)
+
164 #include "../config/known_16bit_timers.h"
+
165 
+
166 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
+
167 # if defined(TIMER1_C_PIN)
+
168 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN, TIMER1_C_PIN);
+
169 # else
+
170 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN);
+
171 # endif
+
172 #endif
diff --git a/extras/doc/html/config__checks__esp32_8h_source.html b/extras/doc/html/config__checks__esp32_8h_source.html index 9475e4c13..6dd7b9a2e 100644 --- a/extras/doc/html/config__checks__esp32_8h_source.html +++ b/extras/doc/html/config__checks__esp32_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_esp32.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,160 @@
config_checks_esp32.h
-
1 #ifndef CONFIG_CHECK_ESP32_H
2 #define CONFIG_CHECK_ESP32_H
3 
4 /** @ingroup hardware
5  * @page hardware_esp32 Mozzi on ESP32-based boards.
6  *
7  * port by Dieter Vandoren and Thomas Friedrichsmeier
8  *
9  * @section esp32_status Port status and notes
10  * - Since flash memory is not built into the ESP32, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform.
11  * - Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. @ref MOZZI_AUDIO_INPUT is not implemented
12  * - twi_nonblock is not ported
13  * - WIFI-activity not yet tested, but likely the same notes as for ESP8266 apply, i.e. @em any Wifi activity is likely to introdcue considerable nose. Consider turning off WIFI.
14  * - The implementation of audioTicks() may be slightly inaccurate on this platform.
15  *
16  * @section esp32_output Output modes
17  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
18  * - MOZZI_OUTPUT_EXTERNAL_TIMED
19  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
20  * - MOZZI_OUTPUT_PDM_VIA_I2S
21  * - MOZZI_OUTPUT_I2S_DAC
22  * - MOZZI_OUTPUT_INTERNAL_DAC
23  *
24  * The default mode is @ref esp32_internal_dac .
25  *
26  * @section esp32_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
27  * The internal DAC has 8 bit resolution, and outputs to GPIO pins 25 and 26 (non-configurable). For simplicity of code, both pins are always used.
28  * In a mono configuration, both pins output the same sample.
29  *
30  * TODO: We could really use this to hack in a 2 PIN mode!
31  *
32  * @note
33  * The number 25 refers to "GPIO 25" or sometimes labelled "D25". Confusingly, many boards come with an additional, totally different numbering scheme on top of that.
34  * Check a detailed pinout diagram, if in any doubt.
35  *
36  * Internally, the inbuilt DAC is connected via an I2S interface. Which interface number to use can be configured using:
37  *
38  * @code
39  * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0)
40  * @endcode
41  *
42  * @section esp32_i2s_dac MOZZI_OUTPUT_I2S_DAC
43  * This mode outputs to a PT8211 (or compatible) I2S DAC, which allows for very high quality (mono or stereo) output. Communication needs the BCK, WS, and DATA(out) pins
44  * of one I2S interface. Presumably, any pins qualify, and you can configure this using:
45  * @code
46  * #define MOZZI_I2S_PIN_BCK ... // (default: 26)
47  * #define MOZZI_I2S_PIN_WS ... // (default: 15)
48  * #define MOZZI_I2S_PIN_DATA ... // (default: 33)
49  * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0)
50  * @endcode
51  *
52  * See the note above (@ref esp_internal_dac) regarding pin numbering. Also, please always test the default pinout, should a custom setting fail!
53  *
54  * As a technical note, I2S support in the ESP32 SDK has been reworked since this was implemented in Mozzi, and Mozzi uses the "legacy" implementation "i2s.h".
55  * This should not be an issue, unless you want to connect additional I2S components, yourself. In which case contributions are certainly welcome!
56  *
57  * @section esp32_pdm_via_i2s MOZZI_OUTPUT_PDM_VIA_I2S
58  * This mode uses the same setup as @ref esp32_i2s_dac, but rather than using an external DAC, the communication signal itself is modulated in PDM
59  * (pulse density modulation) encoded form. Thus not extra hardware is needed, and the signal is output on the DATA pin (see above). The BCK and
60  * WS pins are also claimed, but should be left non-connected, and do not produce anything meaningful. This can only be used in mono mode.
61  *
62  * Output resolution may be adjusted by defining MOZZI_PDM_RESOLUTION , where the default value of 4 means that each audio sample is encoded into four 32 bit blocks
63  * of ones and zeros. Obviously, more is potentially better, but at the cost of considerable computation power.
64  *
65  * @section esp32_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
66  * See @ref external_audio
67 */
68 
69 #if not IS_ESP32()
70 #error This header should be included for ESP32 architecture, only
71 #endif
72 
74 #if !defined(MOZZI_AUDIO_MODE)
75 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
76 #endif
77 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC)
78 
79 #if !defined(MOZZI_AUDIO_RATE)
80 #define MOZZI_AUDIO_RATE 32768
81 #endif
82 
83 #if defined(MOZZI_PWM_RATE)
84 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
85 #endif
86 
87 #if !defined(MOZZI_ANALOG_READ)
88 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
89 #endif
90 
91 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
92 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
93 
94 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_PDM_VIA_I2S)
95 # if !defined(MOZZI_I2S_PIN_BCK)
96 # define MOZZI_I2S_PIN_BCK 26
97 # endif
98 # if !defined(MOZZI_I2S_PIN_WS)
99 # define MOZZI_I2S_PIN_WS 25
100 # endif
101 # if !defined(MOZZI_I2S_PIN_DATA)
102 # define MOZZI_I2S_PIN_DATA 33
103 # endif
104 #endif
105 
106 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_PDM_VIA_I2S)
107 # include <driver/i2s.h>
108 # if !defined(MOZZI_IS2_PORT)
109 # define MOZZI_I2S_PORT I2S_NUM_0
110 # endif
111 #endif
112 
113 #if !defined(MOZZI_AUDIO_BITS)
114 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
115 # define MOZZI_AUDIO_BITS 8
116 # else
117 # define MOZZI_AUDIO_BITS 16
118 # endif
119 #endif
120 
121 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
122 # if !defined(MOZZI_PDM_RESOLUTION)
123 # define MOZZI_PDM_RESOLUTION 8
124 # endif
125 #else
126 # define MOZZI_PDM_RESOLUTION 1 // unconditionally, no other value allowed
127 #endif
128 
129 // All modes besides timed external bypass the output buffer!
130 #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
131 # define BYPASS_MOZZI_OUTPUT_BUFFER true
132 #endif
133 
134 #endif // #ifndef CONFIG_CHECK_ESP32_H
#define MOZZI_ANALOG_READ
Whether to compile in support for non-blocking analog reads.
-
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_esp32.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECK_ESP32_H
+
13 #define CONFIG_CHECK_ESP32_H
+
14 
+
15 /** @ingroup hardware
+
16  * @page hardware_esp32 Mozzi on ESP32-based boards.
+
17  *
+
18  * port by Dieter Vandoren and Thomas Friedrichsmeier
+
19  *
+
20  * @section esp32_status Port status and notes
+
21  * - Since flash memory is not built into the ESP32, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform.
+
22  * - Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. @ref MOZZI_AUDIO_INPUT is not implemented
+
23  * - twi_nonblock is not ported
+
24  * - WIFI-activity not yet tested, but likely the same notes as for ESP8266 apply, i.e. @em any Wifi activity is likely to introdcue considerable nose. Consider turning off WIFI.
+
25  * - The implementation of audioTicks() may be slightly inaccurate on this platform.
+
26  *
+
27  * @section esp32_output Output modes
+
28  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
29  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
30  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
31  * - MOZZI_OUTPUT_PDM_VIA_I2S
+
32  * - MOZZI_OUTPUT_I2S_DAC
+
33  * - MOZZI_OUTPUT_INTERNAL_DAC
+
34  *
+
35  * The default mode is @ref esp32_internal_dac .
+
36  *
+
37  * @section esp32_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
+
38  * The internal DAC has 8 bit resolution, and outputs to GPIO pins 25 and 26 (non-configurable). For simplicity of code, both pins are always used.
+
39  * In a mono configuration, both pins output the same sample.
+
40  *
+
41  * TODO: We could really use this to hack in a 2 PIN mode!
+
42  *
+
43  * @note
+
44  * The number 25 refers to "GPIO 25" or sometimes labelled "D25". Confusingly, many boards come with an additional, totally different numbering scheme on top of that.
+
45  * Check a detailed pinout diagram, if in any doubt.
+
46  *
+
47  * Internally, the inbuilt DAC is connected via an I2S interface. Which interface number to use can be configured using:
+
48  *
+
49  * @code
+
50  * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0)
+
51  * @endcode
+
52  *
+
53  * @section esp32_i2s_dac MOZZI_OUTPUT_I2S_DAC
+
54  * This mode outputs to a PT8211 (or compatible) I2S DAC, which allows for very high quality (mono or stereo) output. Communication needs the BCK, WS, and DATA(out) pins
+
55  * of one I2S interface. Presumably, any pins qualify, and you can configure this using:
+
56  * @code
+
57  * #define MOZZI_I2S_PIN_BCK ... // (default: 26)
+
58  * #define MOZZI_I2S_PIN_WS ... // (default: 15)
+
59  * #define MOZZI_I2S_PIN_DATA ... // (default: 33)
+
60  * #define MOZZI_I2S_PORT ... // (default: I2S_NUM_0)
+
61  * @endcode
+
62  *
+
63  * See the note above (@ref esp_internal_dac) regarding pin numbering. Also, please always test the default pinout, should a custom setting fail!
+
64  *
+
65  * As a technical note, I2S support in the ESP32 SDK has been reworked since this was implemented in Mozzi, and Mozzi uses the "legacy" implementation "i2s.h".
+
66  * This should not be an issue, unless you want to connect additional I2S components, yourself. In which case contributions are certainly welcome!
+
67  *
+
68  * @section esp32_pdm_via_i2s MOZZI_OUTPUT_PDM_VIA_I2S
+
69  * This mode uses the same setup as @ref esp32_i2s_dac, but rather than using an external DAC, the communication signal itself is modulated in PDM
+
70  * (pulse density modulation) encoded form. Thus not extra hardware is needed, and the signal is output on the DATA pin (see above). The BCK and
+
71  * WS pins are also claimed, but should be left non-connected, and do not produce anything meaningful. This can only be used in mono mode.
+
72  *
+
73  * Output resolution may be adjusted by defining MOZZI_PDM_RESOLUTION , where the default value of 4 means that each audio sample is encoded into four 32 bit blocks
+
74  * of ones and zeros. Obviously, more is potentially better, but at the cost of considerable computation power.
+
75  *
+
76  * @section esp32_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
77  * See @ref external_audio
+
78 */
+
79 
+
80 #if not IS_ESP32()
+
81 #error This header should be included for ESP32 architecture, only
+
82 #endif
+
83 
+ +
85 #if !defined(MOZZI_AUDIO_MODE)
+
86 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
+
87 #endif
+
88 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_INTERNAL_DAC)
+
89 
+
90 #if !defined(MOZZI_AUDIO_RATE)
+
91 #define MOZZI_AUDIO_RATE 32768
+
92 #endif
+
93 
+
94 #if defined(MOZZI_PWM_RATE)
+
95 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
+
96 #endif
+
97 
+
98 #if !defined(MOZZI_ANALOG_READ)
+
99 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
+
100 #endif
+
101 
+
102 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
+
103 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
+
104 
+
105 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_PDM_VIA_I2S)
+
106 # if !defined(MOZZI_I2S_PIN_BCK)
+
107 # define MOZZI_I2S_PIN_BCK 26
+
108 # endif
+
109 # if !defined(MOZZI_I2S_PIN_WS)
+
110 # define MOZZI_I2S_PIN_WS 25
+
111 # endif
+
112 # if !defined(MOZZI_I2S_PIN_DATA)
+
113 # define MOZZI_I2S_PIN_DATA 33
+
114 # endif
+
115 #endif
+
116 
+
117 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_I2S_DAC, MOZZI_OUTPUT_PDM_VIA_I2S)
+
118 # include <driver/i2s.h>
+
119 # if !defined(MOZZI_IS2_PORT)
+
120 # define MOZZI_I2S_PORT I2S_NUM_0
+
121 # endif
+
122 #endif
+
123 
+
124 #if !defined(MOZZI_AUDIO_BITS)
+
125 # if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
126 # define MOZZI_AUDIO_BITS 8
+
127 # else
+
128 # define MOZZI_AUDIO_BITS 16
+
129 # endif
+
130 #endif
+
131 
+
132 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S)
+
133 # if !defined(MOZZI_PDM_RESOLUTION)
+
134 # define MOZZI_PDM_RESOLUTION 8
+
135 # endif
+
136 #else
+
137 # define MOZZI_PDM_RESOLUTION 1 // unconditionally, no other value allowed
+
138 #endif
+
139 
+
140 // All modes besides timed external bypass the output buffer!
+
141 #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
142 # define BYPASS_MOZZI_OUTPUT_BUFFER true
+
143 #endif
+
144 
+
145 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12
+
146 
+
147 #endif // #ifndef CONFIG_CHECK_ESP32_H
diff --git a/extras/doc/html/config__checks__esp8266_8h_source.html b/extras/doc/html/config__checks__esp8266_8h_source.html index e262d68e0..c2edbe023 100644 --- a/extras/doc/html/config__checks__esp8266_8h_source.html +++ b/extras/doc/html/config__checks__esp8266_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_esp8266.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,134 @@
config_checks_esp8266.h
-
1 #ifndef CONFIG_CHECK_ESP8266_H
2 #define CONFIG_CHECK_ESP8266_H
3 
4 /** @ingroup hardware
5  * @page hardware_esp8266 Mozzi on ESP32-based boards.
6  *
7  * port by Thomas Friedrichsmeier
8  *
9  * @section esp8266_status Port status and notes
10  * - Since flash memory is not built into the ESP8266, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform.
11  * - Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. @ref MOZZI_AUDIO_INPUT is not available
12  * - twi_nonblock is not ported
13  * - Note that the ESP8266 pins can output less current than the other supported CPUs. The maximum is 12mA, with a recommendation to stay below 6mA.
14  * - WHEN CONNECTING A HEADPHONE, DIRECTLY, USE APPROPRIATE CURRENT LIMITING RESISTORS (>= 500Ohms).
15  * - _Any_ WiFi-activity can cause severe spikes in power consumption. This can cause audible "ticking" artifacts, long before any other symptoms.
16  * - If you do not require WiFi in your sketch, you should turn it off, _explicitly_, using @code WiFi.mode(WIFI_OFF) @endcode.
17  * - A juicy enough, well regulated power supply, and a stabilizing capacitor between VCC and Gnd can help a lot.
18  * - As the (PDM) output signal is digital, a single (fast!) transistor can be used to amplify it to an independent voltage level.
19  * - audioHook() calls `yield()` once for every audio sample generated. Thus, as long as your audio output buffer does not run empty, you should not need any additional `yield()`s inside `loop()`.
20  *
21  * @section esp8266_output Output modes
22  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
23  * - MOZZI_OUTPUT_EXTERNAL_TIMED
24  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
25  * - MOZZI_OUTPUT_PDM_VIA_I2S
26  * - MOZZI_OUTPUT_PDM_VIA_SERIAL
27  * - MOZZI_OUTPUT_I2S_DAC
28  *
29  * The default mode is @ref esp8266_pdm_via_serial .
30  *
31  * @note
32  * This port really does not currently come with a PWM mode!
33  *
34  * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_SERIAL
35  * Output is coded using pulse density modulation, and sent via GPIO2 (Serial1 TX).
36  * - This output mode uses timer1 for queuing audio sample, so that timer is not available for other uses.
37  * - Note that this mode has slightly lower effective analog output range than @ref esp8266_pdm_via_i2s, due to start/stop bits being added to the output stream.
38  * - Supports mono output, only, pins not configurable.
39  *
40  * The option @ref MOZZI_PDM_RESOLTUON (default value 2, corresponding to 64 ones and zeros per audio sample) can be used to adjust the output resolution.
41  * Obviously higher values demand more computation power.
42  *
43  * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_I2S
44  * Output is coded using pulse density modulation, and sent via the I2S pins. The I2S data out pin (GPIO3, which is also "RX") will have the output,
45  * but *all* I2S output pins (RX, GPIO2 and GPIO15) will be affected. Mozzi tries to set GPIO2 and GPIO15 to input mode, and *at the time of this writing*, this allows
46  * I2S output on RX even on boards such as the ESP01 (where GPIO15 is tied to Ground). However, it seems safest to assume that this mode may not be useable on boards where
47  * GPIO2 or GPIO15 are not available as output pins.
48  *
49  * Supports mono output, only, pins not configurable.
50  *
51  * Resolution may be controlled using MOZZI_PDM_RESOLUTION (see above; default value is 2).
52  *
53  * @section esp8266_i2s_dac MOZZI_OUTPUT_I2S_DAC
54  * Output is sent to an external DAC (such as a PT8211), digitally coded. This is the only mode that supports stereo (@ref MOZZI_AUDIO_CHANNELS). It also needs the least processing power.
55  * The pins cannot be configured (GPIO3/RX, GPIO2, and GPIO15).
56  *
57  * @section esp8266_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
58  * See @ref external_audio
59 */
60 
61 #if not IS_ESP8266()
62 #error This header should be included for ESP architecture, only
63 #endif
64 
66 #if !defined(MOZZI_AUDIO_MODE)
67 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PDM_VIA_SERIAL
68 #endif
69 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC)
70 
71 #if !defined(MOZZI_AUDIO_RATE)
72 #define MOZZI_AUDIO_RATE 32768
73 #endif
74 
75 #if !defined(MOZZI_AUDIO_BITS)
76 # define MOZZI_AUDIO_BITS 16
77 #endif
78 
79 #if !defined(MOZZI_ANALOG_READ)
80 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
81 #endif
82 
83 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
84 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
85 
86 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL)
87 # if !defined(PDM_RESOLUTION)
88 # define MOZZI_PDM_RESOLUTION 2
89 # endif
90 # include "disable_stereo_on_github_workflow.h"
91 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
92 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16)
93 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
94 # define MOZZI_PDM_RESOLUTION 1 // DO NOT CHANGE THIS VALUE! Not actually PDM coded, but this define is useful to keep code simple.
95 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16)
96 #endif
97 
98 #define PDM_RESOLUTION 2 // 1 corresponds to 32 PDM clocks per sample, 2 corresponds to 64 PDM clocks, etc. (and at some level you're going hit the hardware limits)
99 
100 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC)
101 // NOTE: On ESP / output via I2S, we simply use the I2S buffer as the output
102 // buffer, which saves RAM, but also simplifies things a lot
103 // esp. since i2s output already has output rate control -> no need for a
104 // separate output timer
105 #define BYPASS_MOZZI_OUTPUT_BUFFER true
106 #endif
107 
108 #endif // #ifndef CONFIG_CHECK_ESP8266_H
#define MOZZI_ANALOG_READ
Whether to compile in support for non-blocking analog reads.
-
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_esp8266.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECK_ESP8266_H
+
13 #define CONFIG_CHECK_ESP8266_H
+
14 
+
15 /** @ingroup hardware
+
16  * @page hardware_esp8266 Mozzi on ESP32-based boards.
+
17  *
+
18  * port by Thomas Friedrichsmeier
+
19  *
+
20  * @section esp8266_status Port status and notes
+
21  * - Since flash memory is not built into the ESP8266, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform.
+
22  * - Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. @ref MOZZI_AUDIO_INPUT is not available
+
23  * - twi_nonblock is not ported
+
24  * - Note that the ESP8266 pins can output less current than the other supported CPUs. The maximum is 12mA, with a recommendation to stay below 6mA.
+
25  * - WHEN CONNECTING A HEADPHONE, DIRECTLY, USE APPROPRIATE CURRENT LIMITING RESISTORS (>= 500Ohms).
+
26  * - _Any_ WiFi-activity can cause severe spikes in power consumption. This can cause audible "ticking" artifacts, long before any other symptoms.
+
27  * - If you do not require WiFi in your sketch, you should turn it off, _explicitly_, using @code WiFi.mode(WIFI_OFF) @endcode.
+
28  * - A juicy enough, well regulated power supply, and a stabilizing capacitor between VCC and Gnd can help a lot.
+
29  * - As the (PDM) output signal is digital, a single (fast!) transistor can be used to amplify it to an independent voltage level.
+
30  * - audioHook() calls `yield()` once for every audio sample generated. Thus, as long as your audio output buffer does not run empty, you should not need any additional `yield()`s inside `loop()`.
+
31  *
+
32  * @section esp8266_output Output modes
+
33  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
34  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
35  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
36  * - MOZZI_OUTPUT_PDM_VIA_I2S
+
37  * - MOZZI_OUTPUT_PDM_VIA_SERIAL
+
38  * - MOZZI_OUTPUT_I2S_DAC
+
39  *
+
40  * The default mode is @ref esp8266_pdm_via_serial .
+
41  *
+
42  * @note
+
43  * This port really does not currently come with a PWM mode!
+
44  *
+
45  * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_SERIAL
+
46  * Output is coded using pulse density modulation, and sent via GPIO2 (Serial1 TX).
+
47  * - This output mode uses timer1 for queuing audio sample, so that timer is not available for other uses.
+
48  * - Note that this mode has slightly lower effective analog output range than @ref esp8266_pdm_via_i2s, due to start/stop bits being added to the output stream.
+
49  * - Supports mono output, only, pins not configurable.
+
50  *
+
51  * The option @ref MOZZI_PDM_RESOLTUON (default value 2, corresponding to 64 ones and zeros per audio sample) can be used to adjust the output resolution.
+
52  * Obviously higher values demand more computation power.
+
53  *
+
54  * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_I2S
+
55  * Output is coded using pulse density modulation, and sent via the I2S pins. The I2S data out pin (GPIO3, which is also "RX") will have the output,
+
56  * but *all* I2S output pins (RX, GPIO2 and GPIO15) will be affected. Mozzi tries to set GPIO2 and GPIO15 to input mode, and *at the time of this writing*, this allows
+
57  * I2S output on RX even on boards such as the ESP01 (where GPIO15 is tied to Ground). However, it seems safest to assume that this mode may not be useable on boards where
+
58  * GPIO2 or GPIO15 are not available as output pins.
+
59  *
+
60  * Supports mono output, only, pins not configurable.
+
61  *
+
62  * Resolution may be controlled using MOZZI_PDM_RESOLUTION (see above; default value is 2).
+
63  *
+
64  * @section esp8266_i2s_dac MOZZI_OUTPUT_I2S_DAC
+
65  * Output is sent to an external DAC (such as a PT8211), digitally coded. This is the only mode that supports stereo (@ref MOZZI_AUDIO_CHANNELS). It also needs the least processing power.
+
66  * The pins cannot be configured (GPIO3/RX, GPIO2, and GPIO15).
+
67  *
+
68  * @section esp8266_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
69  * See @ref external_audio
+
70 */
+
71 
+
72 #if not IS_ESP8266()
+
73 #error This header should be included for ESP architecture, only
+
74 #endif
+
75 
+ +
77 #if !defined(MOZZI_AUDIO_MODE)
+
78 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PDM_VIA_SERIAL
+
79 #endif
+
80 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC)
+
81 
+
82 #if !defined(MOZZI_AUDIO_RATE)
+
83 #define MOZZI_AUDIO_RATE 32768
+
84 #endif
+
85 
+
86 #if !defined(MOZZI_AUDIO_BITS)
+
87 # define MOZZI_AUDIO_BITS 16
+
88 #endif
+
89 
+
90 #if !defined(MOZZI_ANALOG_READ)
+
91 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
+
92 #endif
+
93 
+
94 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
+
95 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
+
96 
+
97 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL)
+
98 # if !defined(PDM_RESOLUTION)
+
99 # define MOZZI_PDM_RESOLUTION 2
+
100 # endif
+
101 # include "disable_stereo_on_github_workflow.h"
+
102 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
+
103 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16)
+
104 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
+
105 # define MOZZI_PDM_RESOLUTION 1 // DO NOT CHANGE THIS VALUE! Not actually PDM coded, but this define is useful to keep code simple.
+
106 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16)
+
107 #endif
+
108 
+
109 #define PDM_RESOLUTION 2 // 1 corresponds to 32 PDM clocks per sample, 2 corresponds to 64 PDM clocks, etc. (and at some level you're going hit the hardware limits)
+
110 
+
111 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC)
+
112 // NOTE: On ESP / output via I2S, we simply use the I2S buffer as the output
+
113 // buffer, which saves RAM, but also simplifies things a lot
+
114 // esp. since i2s output already has output rate control -> no need for a
+
115 // separate output timer
+
116 #define BYPASS_MOZZI_OUTPUT_BUFFER true
+
117 #endif
+
118 
+
119 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10
+
120 
+
121 #endif // #ifndef CONFIG_CHECK_ESP8266_H
diff --git a/extras/doc/html/config__checks__generic_8h_source.html b/extras/doc/html/config__checks__generic_8h_source.html index 58eac88bc..fbb66c9a8 100644 --- a/extras/doc/html/config__checks__generic_8h_source.html +++ b/extras/doc/html/config__checks__generic_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_generic.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,50 +99,216 @@
config_checks_generic.h
-
1 /** For Mozzi-internal use: Check configuration options for (some) invalid settings, and apply default for options that have not been set, so far.
2  * */
3 
4 #ifndef MOZZI_CONFIG_CHECK_GENERIC_H
5 #define MOZZI_CONFIG_CHECK_GENERIC_H
6 
7 #include "../MozziConfigValues.h" // in case not user-included
8 #include "mozzi_macros.h"
9 
10 /// Step 0: Check for some stuff that user should never configure directly (but may be set, indirectly from the hardware-specific setups)
11 #if defined(BYPASS_MOZZI_OUTPUT_BUFFER)
12 #error "BYPASS_MOZZI_OUTPUT_BUFFER may not be customized via config"
13 #endif
14 
15 
16 //// Step 1: Apply missing defaults for generic config options (not the hardware specific ones)
17 #if not defined(MOZZI_COMPATIBILITY_LEVEL)
18 #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_2_0
19 #endif
20 
21 #if not defined(MOZZI_AUDIO_CHANNELS)
22 #define MOZZI_AUDIO_CHANNELS MOZZI_MONO
23 #endif
24 
25 //MOZZI_AUDIO_MODE -> hardware specific
26 //MOZZI_AUDIO_RATE -> hardware specific
27 
28 #if not defined(MOZZI_CONTROL_RATE)
29 # if defined(CONTROL_RATE) && (MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST)
30 # warning Please change CONTROL_RATE to MOZZI_CONTROL_RATE
31 # define MOZZI_CONTROL_RATE CONTROL_RATE
32 # else
33 # define MOZZI_CONTROL_RATE 64
34 # endif
35 #endif
36 
37 //MOZZI_ANALOG_READ -> hardware specific, but we want to insert a warning, if not supported, and user has not explicitly configured anything
38 #if not defined(MOZZI_ANALOG_READ)
39 #define MOZZI__ANALOG_READ_NOT_CONFIGURED
40 #endif
41 
42 #if not defined(MOZZI_AUDIO_INPUT)
43 #define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_NONE
44 #endif
45 
46 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && !defined(MOZZI_AUDIO_INPUT_PIN)
47 #warning Using audio input, but no audio input pin defined, explicitly. Defaulting to pin 0.
48 #define MOZZI_AUDIO_INPUT_PIN 0
49 #endif
50 
51 //MOZZI_PWM_RATE -> hardware specific
52 //MOZZI_AUDIO_PIN_1 -> hardware specific
53 //MOZZI_AUDIO_PIN_1_LOW -> hardware specific
54 //MOZZI_AUDIO_PIN_2 -> hardware specific
55 //MOZZI_AUDIO_PIN_2_LOW -> hardware specific
56 
57 
58 /// Step 2: Include the hardware specific checks-and-defaults-header
59 #if IS_AVR()
60 #include "config_checks_avr.h"
61 #elif IS_ESP32()
62 #include "config_checks_esp32.h"
63 #elif IS_ESP8266()
64 #include "config_checks_esp8266.h"
65 #elif IS_MBED()
66 #include "config_checks_mbed.h"
67 #elif IS_RENESAS()
68 #include "config_checks_renesas.h"
69 #elif IS_RP2040()
70 #include "config_checks_rp2040.h"
71 #elif IS_SAMD21()
72 #include "config_checks_samd21.h"
73 #elif IS_STM32DUINO()
74 #include "config_checks_stm32duino.h"
75 #elif IS_STM32MAPLE()
76 #include "config_checks_stm32maple.h"
77 #elif (IS_TEENSY3() || IS_TEENSY4())
78 #include "config_checks_teensy.h"
79 #else
80 #error Problem detecting hardware
81 #endif
82 
83 
84 /// Step 2b: Minimal special handling for MOZZI_OUTPUT_EXTERNAL_TIMED/CUSTOM
85 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) && !defined(MOZZI_AUDIO_BITS)
86 # define MOZZI_AUDIO_BITS 16
87 #endif
88 
89 
90 
91 /// Step 3: Apply various generic checks that make sense on more than one platform
92 MOZZI_CHECK_POW2(MOZZI_AUDIO_RATE)
94 
96 #error "MOZZI_AUDIO_INPUT depends on MOZZI_ANALOG_READ option"
97 #endif
98 
99 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && defined(MOZZI_AUDIO_INPUT_PIN)
100 #warning "MOZZI_AUDIO_INPUT_PIN defined without MOZZI_AUDIO_INPUT"
101 #endif
102 
104 #error "MOZZI_AUDIO_CHANNELS outside of (currently) supported range"
105 #endif
106 
107 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
108 #warning "Mozzi is configured to use an external void 'audioOutput(const AudioOutput f)' function. Please define one in your sketch"
109 #endif
110 
111 // Hardware-specific checks file should have more narrow checks for most options, below, but is not required to, so let's check for anything that is wildly out of scope:
114 
115 #if defined(MOZZI__ANALOG_READ_NOT_CONFIGURED)
116 # if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
117 # warning Asynchronous analog reads not implemented on this platform
118 # endif
119 # undef MOZZI__ANALOG_READ_NOT_CONFIGURED
120 #endif
121 
122 /// Step 4: Init Read-only defines that depend on other values
123 #if !defined(MOZZI_AUDIO_BIAS)
124 #define MOZZI_AUDIO_BIAS ((uint16_t) 1<<(MOZZI_AUDIO_BITS-1))
125 #endif
126 
127 #if !defined(MOZZI_AUDIO_BITS_OPTIMISTIC)
128 #define MOZZI_AUDIO_BITS_OPTIMISTIC MOZZI_AUDIO_BITS
129 #endif
130 
131 // TODO: Rename these defines
132 #if MOZZI_AUDIO_RATE == 8192
133 #define AUDIO_RATE_AS_LSHIFT 13
134 #define MICROS_PER_AUDIO_TICK 122
135 #elif MOZZI_AUDIO_RATE == 16384
136 #define AUDIO_RATE_AS_LSHIFT 14
137 #define MICROS_PER_AUDIO_TICK 61 // 1000000 / 16384 = 61.035, ...* 256 = 15625
138 #elif MOZZI_AUDIO_RATE == 32768
139 #define AUDIO_RATE_AS_LSHIFT 15
140 #define MICROS_PER_AUDIO_TICK 31 // = 1000000 / 32768 = 30.518, ...* 256 = 7812.6
141 #elif MOZZI_AUDIO_RATE == 65336
142 #define AUDIO_RATE_AS_LSHIFT 16
143 #define MICROS_PER_AUDIO_TICK 15
144 #else
145 #error Whoopsie, not LSHIFT defined for this audio rate. Please report and/or fix
146 #endif
147 
148 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
149 #define BYPASS_MOZZI_OUTPUT_BUFFER true
150 #endif
151 
152 /// Step 5: Patch up some backwards compatibility issues as far as config-related
154 # define AUDIO_RATE MOZZI_AUDIO_RATE
155 # if !defined(CONTROL_RATE)
156 # define CONTROL_RATE MOZZI_CONTROL_RATE
157 # endif
158 #endif
159 
160 /// Step 6: Some more checks that need to be at the end, because of requiring end of the foodchain headers
161 // TODO: Rather move this up again, and make AudioOutputStorage_t a primary config option
162 #include "../AudioOutput.h"
163 static_assert(MOZZI_AUDIO_BITS <= (8*sizeof(AudioOutputStorage_t)), "Configured MOZZI_AUDIO_BITS is too large for the internal storage type");
164 
165 #endif
#define MOZZI_CHECK_POW2(X)
Definition: mozzi_macros.h:32
-
#define MOZZI_OUTPUT_EXTERNAL_TIMED
-
#define MOZZI_CONTROL_RATE
Control rate setting.
-
#define MOZZI_OUTPUT_PDM_VIA_SERIAL
-
#define MOZZI_STEREO
-
#define MOZZI_CHECK_SUPPORTED(X,...)
Definition: mozzi_macros.h:24
-
#define MOZZI_AUDIO_INPUT_NONE
-
#define IS_SAMD21()
-
#define IS_TEENSY4()
-
#define MOZZI_COMPATIBILITY_LATEST
-
#define MOZZI_ANALOG_READ_NONE
-
#define IS_STM32DUINO()
-
#define IS_STM32MAPLE()
-
#define IS_AVR()
-
#define MOZZI_IS(X,...)
Definition: mozzi_macros.h:51
-
#define MOZZI_OUTPUT_PDM_VIA_I2S
-
#define IS_TEENSY3()
-
#define IS_RP2040()
-
#define MOZZI_OUTPUT_PWM
-
#define IS_MBED()
-
#define IS_RENESAS()
-
#define MOZZI_MONO
This file keeps a list of named configuration values.
-
#define MOZZI_COMPATIBILITY_2_0
-
#define MOZZI_OUTPUT_2PIN_PWM
-
#define MOZZI_AUDIO_CHANNELS
-
#define MOZZI_OUTPUT_INTERNAL_DAC
-
#define MOZZI_OUTPUT_EXTERNAL_CUSTOM
-
#define MOZZI_AUDIO_INPUT
Whether to enable built in audio input feature.
-
#define MOZZI_COMPATIBILITY_LEVEL
Mozzi generally tries to keep your old sketches working, but we continue to find new (and hopefully b...
-
#define IS_ESP8266()
-
#define MOZZI_OUTPUT_I2S_DAC
-
#define IS_ESP32()
-
#define MOZZI_AUDIO_INPUT_STANDARD
-
#define MOZZI_ANALOG_READ_STANDARD
-
#define AudioOutputStorage_t
The type used to store a single channel of a single frame, internally.
Definition: AudioOutput.h:53
+
1 /*
+
2  * config_checks_generic.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 /** @defgroup hardware
+
13  *@{
+
14  * @page hardware_aa_index This section contains hardware specific notes, and availabe configuration options for the various platforms.
+
15  *
+
16  * Mozzi works on many different platforms, but not the same output modes are available on all hardware. For boards specific notes
+
17  * and configuration options, see the relevant sub-pages in this section:
+
18  *
+
19  * - @ref hardware_avr
+
20  * - @ref hardware_esp32
+
21  * - @ref hardware_esp8266
+
22  * - @ref hardware_espmbed
+
23  * - @ref hardware_renesas
+
24  * - @ref hardware_rp2040
+
25  * - @ref hardware_samd21
+
26  * - @ref hardware_stm32duino
+
27  * - @ref hardware_stm32maple
+
28  * - @ref hardware_teensy
+
29  *@}
+
30 */
+
31 
+
32 /** For Mozzi-internal use: Check configuration options for (some) invalid settings, and apply default for options that have not been set, so far.
+
33  * */
+
34 
+
35 #ifndef MOZZI_CONFIG_CHECK_GENERIC_H
+
36 #define MOZZI_CONFIG_CHECK_GENERIC_H
+
37 
+
38 #include "../MozziConfigValues.h" // in case not user-included
+
39 #include "mozzi_macros.h"
+
40 
+
41 /// Step 0: Check for some stuff that user should never configure directly (but may be set, indirectly from the hardware-specific setups)
+
42 #if defined(BYPASS_MOZZI_OUTPUT_BUFFER)
+
43 #error "BYPASS_MOZZI_OUTPUT_BUFFER may not be customized via config"
+
44 #endif
+
45 
+
46 
+
47 //// Step 1: Apply missing defaults for generic config options (not the hardware specific ones)
+
48 #if not defined(MOZZI_COMPATIBILITY_LEVEL)
+
49 #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_2_0
+
50 #endif
+
51 
+
52 #if not defined(MOZZI_AUDIO_CHANNELS)
+
53 #define MOZZI_AUDIO_CHANNELS MOZZI_MONO
+
54 #endif
+
55 
+
56 //MOZZI_AUDIO_MODE -> hardware specific
+
57 //MOZZI_AUDIO_RATE -> hardware specific
+
58 
+
59 #if not defined(MOZZI_CONTROL_RATE)
+
60 # if defined(CONTROL_RATE) && (MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST)
+
61 # warning Please change CONTROL_RATE to MOZZI_CONTROL_RATE
+
62 # define MOZZI_CONTROL_RATE CONTROL_RATE
+
63 # else
+
64 # define MOZZI_CONTROL_RATE 64
+
65 # endif
+
66 #endif
+
67 
+
68 //MOZZI_ANALOG_READ -> hardware specific, but we want to insert a warning, if not supported, and user has not explicitly configured anything
+
69 #if not defined(MOZZI_ANALOG_READ)
+
70 #define MOZZI__ANALOG_READ_NOT_CONFIGURED
+
71 #endif
+
72 
+
73 #if not defined(MOZZI_AUDIO_INPUT)
+
74 #define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_NONE
+
75 #endif
+
76 
+
77 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && !defined(MOZZI_AUDIO_INPUT_PIN)
+
78 #warning Using audio input, but no audio input pin defined, explicitly. Defaulting to pin 0.
+
79 #define MOZZI_AUDIO_INPUT_PIN 0
+
80 #endif
+
81 
+
82 //MOZZI_PWM_RATE -> hardware specific
+
83 //MOZZI_AUDIO_PIN_1 -> hardware specific
+
84 //MOZZI_AUDIO_PIN_1_LOW -> hardware specific
+
85 //MOZZI_AUDIO_PIN_2 -> hardware specific
+
86 //MOZZI_AUDIO_PIN_2_LOW -> hardware specific
+
87 
+
88 
+
89 /// Step 2: Include the hardware specific checks-and-defaults-header
+
90 #if IS_AVR()
+
91 #include "config_checks_avr.h"
+
92 #elif IS_ESP32()
+
93 #include "config_checks_esp32.h"
+
94 #elif IS_ESP8266()
+
95 #include "config_checks_esp8266.h"
+
96 #elif IS_MBED()
+
97 #include "config_checks_mbed.h"
+
98 #elif IS_RENESAS()
+
99 #include "config_checks_renesas.h"
+
100 #elif IS_RP2040()
+
101 #include "config_checks_rp2040.h"
+
102 #elif IS_SAMD21()
+
103 #include "config_checks_samd21.h"
+
104 #elif IS_STM32DUINO()
+
105 #include "config_checks_stm32duino.h"
+
106 #elif IS_STM32MAPLE()
+
107 #include "config_checks_stm32maple.h"
+
108 #elif (IS_TEENSY3() || IS_TEENSY4())
+
109 #include "config_checks_teensy.h"
+
110 #else
+
111 #error Problem detecting hardware
+
112 #endif
+
113 
+
114 
+
115 /// Step 2b: Minimal special handling for MOZZI_OUTPUT_EXTERNAL_TIMED/CUSTOM
+
116 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) && !defined(MOZZI_AUDIO_BITS)
+
117 # define MOZZI_AUDIO_BITS 16
+
118 #endif
+
119 
+
120 
+
121 
+
122 /// Step 3: Apply various generic checks that make sense on more than one platform
+
123 MOZZI_CHECK_POW2(MOZZI_AUDIO_RATE)
+ +
125 
+ +
127 #error "MOZZI_AUDIO_INPUT depends on MOZZI_ANALOG_READ option"
+
128 #endif
+
129 
+
130 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && defined(MOZZI_AUDIO_INPUT_PIN)
+
131 #warning "MOZZI_AUDIO_INPUT_PIN defined without MOZZI_AUDIO_INPUT"
+
132 #endif
+
133 
+ +
135 #error "MOZZI_AUDIO_CHANNELS outside of (currently) supported range"
+
136 #endif
+
137 
+
138 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
139 #warning "Mozzi is configured to use an external void 'audioOutput(const AudioOutput f)' function. Please define one in your sketch"
+
140 #endif
+
141 
+
142 // Hardware-specific checks file should have more narrow checks for most options, below, but is not required to, so let's check for anything that is wildly out of scope:
+ + +
145 
+
146 #if defined(MOZZI__ANALOG_READ_NOT_CONFIGURED)
+
147 # if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
+
148 # warning Asynchronous analog reads not implemented on this platform
+
149 # endif
+
150 # undef MOZZI__ANALOG_READ_NOT_CONFIGURED
+
151 #endif
+
152 
+
153 #if defined(MOZZI_ANALOG_READ_RESOLUTION)
+
154 # if (MOZZI_ANALOG_READ_RESOLUTION < 1) || (MOZZI_ANALOG_READ_RESOLUTION > 16)
+
155 // NOTE: We could certainly allow more than 16 bits, but then the data type would need to be adjusted/adjustable, accrodingly.
+
156 # error MOZZI_ANALOG_READ_RESOLUTION must be between 1 and 16 bits
+
157 # endif
+
158 #endif
+
159 
+
160 /// Step 4: Init Read-only defines that depend on other values
+
161 #if !defined(MOZZI_AUDIO_BIAS)
+
162 #define MOZZI_AUDIO_BIAS ((uint16_t) 1<<(MOZZI_AUDIO_BITS-1))
+
163 #endif
+
164 
+
165 #if !defined(MOZZI_AUDIO_BITS_OPTIMISTIC)
+
166 #define MOZZI_AUDIO_BITS_OPTIMISTIC MOZZI_AUDIO_BITS
+
167 #endif
+
168 
+
169 // TODO: Rename these defines
+
170 #if MOZZI_AUDIO_RATE == 8192
+
171 #define AUDIO_RATE_AS_LSHIFT 13
+
172 #define MICROS_PER_AUDIO_TICK 122
+
173 #elif MOZZI_AUDIO_RATE == 16384
+
174 #define AUDIO_RATE_AS_LSHIFT 14
+
175 #define MICROS_PER_AUDIO_TICK 61 // 1000000 / 16384 = 61.035, ...* 256 = 15625
+
176 #elif MOZZI_AUDIO_RATE == 32768
+
177 #define AUDIO_RATE_AS_LSHIFT 15
+
178 #define MICROS_PER_AUDIO_TICK 31 // = 1000000 / 32768 = 30.518, ...* 256 = 7812.6
+
179 #elif MOZZI_AUDIO_RATE == 65336
+
180 #define AUDIO_RATE_AS_LSHIFT 16
+
181 #define MICROS_PER_AUDIO_TICK 15
+
182 #else
+
183 #error Whoopsie, not LSHIFT defined for this audio rate. Please report and/or fix
+
184 #endif
+
185 
+
186 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
187 #define BYPASS_MOZZI_OUTPUT_BUFFER true
+
188 #endif
+
189 
+
190 /// Step 5: Patch up some backwards compatibility issues as far as config-related
+ +
192 # define AUDIO_RATE MOZZI_AUDIO_RATE
+
193 # if !defined(CONTROL_RATE)
+
194 # define CONTROL_RATE MOZZI_CONTROL_RATE
+
195 # endif
+
196 #endif
+
197 
+
198 /// Step 6: Some more checks that need to be at the end, because of requiring end of the foodchain headers
+
199 // TODO: Rather move this up again, and make AudioOutputStorage_t a primary config option
+
200 #include "../AudioOutput.h"
+
201 static_assert(MOZZI_AUDIO_BITS <= (8*sizeof(AudioOutputStorage_t)), "Configured MOZZI_AUDIO_BITS is too large for the internal storage type");
+
202 
+
203 #endif
diff --git a/extras/doc/html/config__checks__mbed_8h_source.html b/extras/doc/html/config__checks__mbed_8h_source.html index 8cc7df6bf..a7eca845e 100644 --- a/extras/doc/html/config__checks__mbed_8h_source.html +++ b/extras/doc/html/config__checks__mbed_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_mbed.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,141 @@
config_checks_mbed.h
-
1 #ifndef CONFIG_CHECK_MBED_H
2 #define CONFIG_CHECK_MBED_H
3 
4 /** @ingroup hardware
5  * @page hardware_mbed Mozzi on MBED-based boards (Arduino Giga / Portenta).
6  *
7  * port by Thomas Friedrichsmeier & Thomas Combriat
8  *
9  * @section mbed_status Port status and notes
10  * Compiles and runs using Arduino's standard and Arduino_AdvancedAnalog libraries. This port is still **experimental**, testing reveals
11  * some instabilities for some configurations (in particular with @ref MOZZI_AUDIO_INPUT) that are under active investigations.
12  *
13  * This port is not complete yet, in particular:
14  * - Asynchroneous analog reads are not implemented (yet), `mozziAnalogRead()` relays to `analogRead()`. (Note that @ref MOZZI_AUDIO_INPUT @em is implemented!)
15  * - This port should support other MBED based Arduino boards like the Arduino Portenta, in *theory*, but the developer have only tested it on the Giga. Feedback welcome!
16  *
17  * @section mbed_output Output modes
18  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
19  * - MOZZI_OUTPUT_EXTERNAL_TIMED
20  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
21  * - MOZZI_OUTPUT_PDM_VIA_SERIAL
22  * - MOZZI_OUTPUT_INTERNAL_DAC
23  *
24  * The default mode is @ref mbed_internal_dac .
25  *
26  * @section mbed_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
27  * This uses the inbuild DAC on the board. The default is setting is appropriate for the Arduino Giga: 12 bits going to A13 (3.5mm jack connector's tip),
28  * and in stereo mode to pin A12 (3.5mm jack connector's first ring) additionally.
29  *
30  * For other boards is may be appropriate to customize:
31  * @code
32  * #define MOZZI_AUDIO_PIN_1 ... // mono / left channel; default: A13
33  * #define MOZZI_AUDIO_PIN_2 ... // stereo only: right channel; default: A12
34  * #define MOZZI_AUDIO_BITS ... // default is 12
35  * @endcode
36  *
37  * @section mbed_pdm_via_serial MOZZI_PDM_VIA_SERIAL
38  * Returns a pulse-density modulated (mono only) signal on one of the hardware UARTs of the board (Serial ports). Default is using the SERIAL2, on pin D18.
39  * You can confiugre the pins to use, but it must be connected to a hardware UART. Output is written to the TX pin, only, but the RX pin needs to be
40  * claimed as well. Beware of confusing pinout labelling, for instance SERIAL2_TX iss labelled "TX1" on the Arduino Giga. The audio resolution can be enhanced
41  * using @ref MOZZI_PDM_RESOLUTION, which is described in more detail here: @esp32_pdm_via_i2s .
42  *
43  * Configuration options:
44  * @code
45  * #define MOZZI_SERIAL_PIN_TX ... // default: SERIAL2_TX
46  * #define MOZZI_SERIAL_PIN_RX ... // *must* specify the matching one, if customizing the above; default: SERIAL2_RX
47  * #define MOZZI_PDM_RESOLUTION ... // default value is 2, for 2*32 ones and zeros per audio sample
48  * @endcode
49  *
50  * @section mbed_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
51  * See @ref external_audio
52 */
53 
54 
55 #if not IS_MBED()
56 #error This header should be included for MBED architecture, only
57 #endif
58 
60 #if !defined(MOZZI_AUDIO_MODE)
61 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
62 #endif
63 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_INTERNAL_DAC)
64 
65 #if !defined(MOZZI_AUDIO_RATE)
66 #define MOZZI_AUDIO_RATE 32768
67 #endif
68 
69 #if defined(MOZZI_PWM_RATE)
70 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
71 #endif
72 
73 #if !defined(MOZZI_ANALOG_READ)
74 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
75 #endif
76 
77 // yes, correct: async "single" reads are not implemented, but audio input is
78 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
79 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD)
80 
81 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
82 # if !defined(MOZZI_AUDIO_BITS)
83 # define MOZZI_AUDIO_BITS 12
84 # endif
85 # if !defined(MOZZI_AUDIO_PIN_1)
86 # define MOZZI_AUDIO_PIN_1 A13
87 # endif
88 # if !defined(MOZZI_AUDIO_PIN_2)
89 # define MOZZI_AUDIO_PIN_2 A12
90 # endif
91 #endif
92 
93 #if !defined(MOZZI_AUDIO_BITS)
94 # define MOZZI_AUDIO_BITS 16
95 #endif
96 
97 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
98 # if !defined(MOZZI_PDM_RESOLUTION)
99 # define MOZZI_PDM_RESOLUTION 2
100 # endif
101 # if !defined(MOZZI_SERIAL_PIN_TX)
102 # define MOZZI_SERIAL_PIN_TX SERIAL2_TX
103 # endif
104 # if !defined(MOZZI_SERIAL_PIN_RX)
105 # define MOZZI_SERIAL_PIN_RX SERIAL2_RX
106 # endif
107 #endif
108 
109 // All modes besides timed external bypass the output buffer!
110 #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
111 # define BYPASS_MOZZI_OUTPUT_BUFFER true
112 #endif
113 
114 #endif // #ifndef CONFIG_CHECK_MBED_H
#define MOZZI_ANALOG_READ
Whether to compile in support for non-blocking analog reads.
-
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_mbed.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECK_MBED_H
+
13 #define CONFIG_CHECK_MBED_H
+
14 
+
15 /** @ingroup hardware
+
16  * @page hardware_mbed Mozzi on MBED-based boards (Arduino Giga / Portenta).
+
17  *
+
18  * port by Thomas Friedrichsmeier & Thomas Combriat
+
19  *
+
20  * @section mbed_status Port status and notes
+
21  * Compiles and runs using Arduino's standard and Arduino_AdvancedAnalog libraries. This port is still **experimental**, testing reveals
+
22  * some instabilities for some configurations (in particular with @ref MOZZI_AUDIO_INPUT) that are under active investigations.
+
23  *
+
24  * This port is not complete yet, in particular:
+
25  * - Asynchroneous analog reads are not implemented (yet), `mozziAnalogRead()` relays to `analogRead()`. (Note that @ref MOZZI_AUDIO_INPUT @em is implemented!)
+
26  * - This port should support other MBED based Arduino boards like the Arduino Portenta, in *theory*, but the developer have only tested it on the Giga. Feedback welcome!
+
27  *
+
28  * @section mbed_output Output modes
+
29  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
30  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
31  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
32  * - MOZZI_OUTPUT_PDM_VIA_SERIAL
+
33  * - MOZZI_OUTPUT_INTERNAL_DAC
+
34  *
+
35  * The default mode is @ref mbed_internal_dac .
+
36  *
+
37  * @section mbed_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
+
38  * This uses the inbuild DAC on the board. The default is setting is appropriate for the Arduino Giga: 12 bits going to A13 (3.5mm jack connector's tip),
+
39  * and in stereo mode to pin A12 (3.5mm jack connector's first ring) additionally.
+
40  *
+
41  * For other boards is may be appropriate to customize:
+
42  * @code
+
43  * #define MOZZI_AUDIO_PIN_1 ... // mono / left channel; default: A13
+
44  * #define MOZZI_AUDIO_PIN_2 ... // stereo only: right channel; default: A12
+
45  * #define MOZZI_AUDIO_BITS ... // default is 12
+
46  * @endcode
+
47  *
+
48  * @section mbed_pdm_via_serial MOZZI_PDM_VIA_SERIAL
+
49  * Returns a pulse-density modulated (mono only) signal on one of the hardware UARTs of the board (Serial ports). Default is using the SERIAL2, on pin D18.
+
50  * You can confiugre the pins to use, but it must be connected to a hardware UART. Output is written to the TX pin, only, but the RX pin needs to be
+
51  * claimed as well. Beware of confusing pinout labelling, for instance SERIAL2_TX iss labelled "TX1" on the Arduino Giga. The audio resolution can be enhanced
+
52  * using @ref MOZZI_PDM_RESOLUTION, which is described in more detail here: @esp32_pdm_via_i2s .
+
53  *
+
54  * Configuration options:
+
55  * @code
+
56  * #define MOZZI_SERIAL_PIN_TX ... // default: SERIAL2_TX
+
57  * #define MOZZI_SERIAL_PIN_RX ... // *must* specify the matching one, if customizing the above; default: SERIAL2_RX
+
58  * #define MOZZI_PDM_RESOLUTION ... // default value is 2, for 2*32 ones and zeros per audio sample
+
59  * @endcode
+
60  *
+
61  * @section mbed_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
62  * See @ref external_audio
+
63 */
+
64 
+
65 
+
66 #if not IS_MBED()
+
67 #error This header should be included for MBED architecture, only
+
68 #endif
+
69 
+ +
71 #if !defined(MOZZI_AUDIO_MODE)
+
72 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
+
73 #endif
+
74 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_INTERNAL_DAC)
+
75 
+
76 #if !defined(MOZZI_AUDIO_RATE)
+
77 #define MOZZI_AUDIO_RATE 32768
+
78 #endif
+
79 
+
80 #if defined(MOZZI_PWM_RATE)
+
81 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
+
82 #endif
+
83 
+
84 #if !defined(MOZZI_ANALOG_READ)
+
85 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
+
86 #endif
+
87 
+
88 // yes, correct: async "single" reads are not implemented, but audio input is
+
89 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
+
90 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD)
+
91 
+
92 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
93 # if !defined(MOZZI_AUDIO_BITS)
+
94 # define MOZZI_AUDIO_BITS 12
+
95 # endif
+
96 # if !defined(MOZZI_AUDIO_PIN_1)
+
97 # define MOZZI_AUDIO_PIN_1 A13
+
98 # endif
+
99 # if !defined(MOZZI_AUDIO_PIN_2)
+
100 # define MOZZI_AUDIO_PIN_2 A12
+
101 # endif
+
102 #endif
+
103 
+
104 #if !defined(MOZZI_AUDIO_BITS)
+
105 # define MOZZI_AUDIO_BITS 16
+
106 #endif
+
107 
+
108 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_SERIAL)
+
109 # if !defined(MOZZI_PDM_RESOLUTION)
+
110 # define MOZZI_PDM_RESOLUTION 2
+
111 # endif
+
112 # if !defined(MOZZI_SERIAL_PIN_TX)
+
113 # define MOZZI_SERIAL_PIN_TX SERIAL2_TX
+
114 # endif
+
115 # if !defined(MOZZI_SERIAL_PIN_RX)
+
116 # define MOZZI_SERIAL_PIN_RX SERIAL2_RX
+
117 # endif
+
118 #endif
+
119 
+
120 // All modes besides timed external bypass the output buffer!
+
121 #if !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
122 # define BYPASS_MOZZI_OUTPUT_BUFFER true
+
123 #endif
+
124 
+
125 // TODO: This value is correct for Arduino Giga and Arduino Portenta, but not necessarily everywhere else
+
126 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 16
+
127 
+
128 #endif // #ifndef CONFIG_CHECK_MBED_H
diff --git a/extras/doc/html/config__checks__renesas_8h_source.html b/extras/doc/html/config__checks__renesas_8h_source.html index d3029e217..57b88b8ad 100644 --- a/extras/doc/html/config__checks__renesas_8h_source.html +++ b/extras/doc/html/config__checks__renesas_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_renesas.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,96 @@
config_checks_renesas.h
-
1 #ifndef CONFIG_CHECK_RENESAS_H
2 #define CONFIG_CHECK_RENESAS_H
3 
4 /** @ingroup hardware
5  * @page hardware_renesas Mozzi on Arduino Uno R4 - Renesas.
6  *
7  * port by Thomas Combriat
8  *
9  * @section renesas_status Port status and notes
10  * Compiles and runs using Arduino's standard library (Renesas 0.8.7 at the time of this writing).
11  *
12  * A few particularities:
13  * - Because this board has an on-board DAC (A0), but only one, STEREO is not implemented and Mozzi uses this pin. Usage of other pins using PWM for instance is not implemented yet.
14  * - getAudioInput() and mozziAnalogRead() return values in the Renesas' full ADC resolution of 0-16384 rather than AVR's 0-1023. *This might change in the near future for speed purposes.*
15  *
16  * @section rensesas_output Output modes
17  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
18  * - MOZZI_OUTPUT_EXTERNAL_TIMED
19  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
20  * - MOZZI_OUTPUT_INTERNAL_DAC
21  *
22  * The default mode is @ref renesas_internal_dac. Further modes may be added in the future.
23  *
24  * @section renesas_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
25  * This uses the inbuild DAC on the board on pin A0. Mono output only, and the pin is not configurable. Audio resolution is also fixed at 12 bits (which is what the board supports).
26  *
27  * This mode claims two timers (but it is not hardcoded, which ones).
28  *
29  * @section renesas_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
30  * MOZZI_OUTPUT_EXTERNAL_TIMED claimes one timer, MOZZI_OUTPUT_EXTERNAL_CUSTOM does not claim any timer.
31  * See @ref external_audio
32 */
33 
34 #if not IS_RENESAS()
35 #error This header should be included for RENESAS (Arduino Uno R4) architecture, only
36 #endif
37 
39 #if !defined(MOZZI_AUDIO_MODE)
40 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
41 #endif
42 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC)
43 
44 #if !defined(MOZZI_AUDIO_RATE)
45 #define MOZZI_AUDIO_RATE 32768
46 #endif
47 
48 #if defined(MOZZI_PWM_RATE)
49 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
50 #endif
51 
52 #if !defined(MOZZI_ANALOG_READ)
53 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
54 #endif
55 
56 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
57 
58 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
59 # if !defined(MOZZI_AUDIO_BITS)
60 # define MOZZI_AUDIO_BITS 12
61 # endif
62 # if !defined(MOZZI_AUDIO_PIN_1)
63 # define MOZZI_AUDIO_PIN_1 A0
64 # endif
65 # define BYPASS_MOZZI_OUTPUT_BUFFER true
66 # include "disable_stereo_on_github_workflow.h"
67 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
68 #endif
69 
70 #endif // #ifndef CONFIG_CHECK_RENESAS_H
#define MOZZI_ANALOG_READ
Whether to compile in support for non-blocking analog reads.
-
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_renesas.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECK_RENESAS_H
+
13 #define CONFIG_CHECK_RENESAS_H
+
14 
+
15 /** @ingroup hardware
+
16  * @page hardware_renesas Mozzi on Arduino Uno R4 - Renesas.
+
17  *
+
18  * port by Thomas Combriat
+
19  *
+
20  * @section renesas_status Port status and notes
+
21  * Compiles and runs using Arduino's standard library (Renesas 0.8.7 at the time of this writing).
+
22  *
+
23  * A few particularities:
+
24  * - Because this board has an on-board DAC (A0), but only one, STEREO is not implemented and Mozzi uses this pin. Usage of other pins using PWM for instance is not implemented yet.
+
25  * - getAudioInput() and mozziAnalogRead() return values in the Renesas' full ADC resolution of 0-16384 rather than AVR's 0-1023. *This might change in the near future for speed purposes.*
+
26  *
+
27  * @section rensesas_output Output modes
+
28  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
29  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
30  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
31  * - MOZZI_OUTPUT_INTERNAL_DAC
+
32  *
+
33  * The default mode is @ref renesas_internal_dac. Further modes may be added in the future.
+
34  *
+
35  * @section renesas_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
+
36  * This uses the inbuild DAC on the board on pin A0. Mono output only, and the pin is not configurable. Audio resolution is also fixed at 12 bits (which is what the board supports).
+
37  *
+
38  * This mode claims two timers (but it is not hardcoded, which ones).
+
39  *
+
40  * @section renesas_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
41  * MOZZI_OUTPUT_EXTERNAL_TIMED claimes one timer, MOZZI_OUTPUT_EXTERNAL_CUSTOM does not claim any timer.
+
42  * See @ref external_audio
+
43 */
+
44 
+
45 #if not IS_RENESAS()
+
46 #error This header should be included for RENESAS (Arduino Uno R4) architecture, only
+
47 #endif
+
48 
+ +
50 #if !defined(MOZZI_AUDIO_MODE)
+
51 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
+
52 #endif
+
53 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC)
+
54 
+
55 #if !defined(MOZZI_AUDIO_RATE)
+
56 #define MOZZI_AUDIO_RATE 32768
+
57 #endif
+
58 
+
59 #if defined(MOZZI_PWM_RATE)
+
60 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
+
61 #endif
+
62 
+
63 #if !defined(MOZZI_ANALOG_READ)
+
64 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
65 #endif
+
66 
+
67 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
+
68 
+
69 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
70 # if !defined(MOZZI_AUDIO_BITS)
+
71 # define MOZZI_AUDIO_BITS 12
+
72 # endif
+
73 # if !defined(MOZZI_AUDIO_PIN_1)
+
74 # define MOZZI_AUDIO_PIN_1 A0
+
75 # endif
+
76 # define BYPASS_MOZZI_OUTPUT_BUFFER true
+
77 # include "disable_stereo_on_github_workflow.h"
+
78 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
+
79 #endif
+
80 
+
81 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 14
+
82 
+
83 #endif // #ifndef CONFIG_CHECK_RENESAS_H
diff --git a/extras/doc/html/config__checks__rp2040_8h_source.html b/extras/doc/html/config__checks__rp2040_8h_source.html index 44cce780f..36970e4bb 100644 --- a/extras/doc/html/config__checks__rp2040_8h_source.html +++ b/extras/doc/html/config__checks__rp2040_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_rp2040.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,140 @@
config_checks_rp2040.h
-
1 #ifndef CONFIG_CHECK_RP2040_H
2 #define CONFIG_CHECK_RP2040_H
3 
4 /** @ingroup hardware
5  * @page hardware_rp2040 Mozzi on RP2040 (Raspberry Pi Pico)
6  *
7  * port by Thomas Friedrichsmeier
8  *
9  * @section rp2040_status Port status and notes
10  * Compiles and runs using [this core](https://github.com/earlephilhower/arduino-pico). Can probably be ported to the Mbed core for RP2040, relatively easily,
11  * as it relies mostly on the RP2040 SDK API. Tested on a Pi Pico.
12  *
13  * - This is a recent addition, implementation details may still change (currently just PWM driven by a timer; this may be worth changing to a DMA driven output)
14  * - Wavetables and samples are not kept in progmem on this platform. While apparently speed (of the external flash) is not much of an issue, the data always seems to be copied into RAM, anyway.
15  * - Note that getAudioInput() and mozziAnalogRead() return values in the RP2040's full ADC resolution of 0-4095 rather than AVR's 0-1023.
16  * - twi_nonblock is not ported
17  * - Code uses only one CPU core
18  *
19  * @section rp2040_output Output modes
20  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
21  * - MOZZI_OUTPUT_EXTERNAL_TIMED
22  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
23  * - MOZZI_OUTPUT_PWM
24  * - MOZZI_OUTPUT_I2S_DAC
25  *
26  * The default mode is @ref rp2040_pwm .
27  *
28  * @section rp2040_pdm MOZZI_OUTPUT_PWM
29  * Audio output is written to pin 0 (mono) or 0 and 1 (stereo), by default, with 11 bits of ouput resolution.
30  * One hardware timer interrupt and one DMA channel are claimed (number not hardcoded), a non-exclusive handler is installed on DMA_IRQ_0.
31  *
32  * Configuration options:
33  * @code
34  * #define MOZZI_AUDIO_PIN_1 ... // default is 0
35  * #define MOZZI_AUDIO_BITS ... // output resolution (bits); default is 11
36  * // additionally, for stereo:
37  * #define MOZZI_AUDIO_PIN_2 ... // default is 1; this must be on the same PWM slice as the first pin (i.e. neighboring)
38  * @endcode
39  *
40  * @section rp2040_i2s_dac MOZZI_OUTPUT_I2S_DAC
41  * Output to an external DAC, connected via I2S. This uses 16 bit (per audio channel), but can be changed to 8, 16, 24 (left aligned) and 32 resolution.
42  * Both plain I2S and LSBJ format (PT8211 needs this, for instance) are available. Plain format is used by default. The GPIO pins to use can be configured,
43  * - almost - freely (see below). Two DMA channels are claimed (numbers not hardcoded), non-exclusive handlers are installed on DMA_IRQ_0.
44  *
45  * Configuration options:
46  * @code
47  * #define MOZZI_AUDIO_BITS ... // available values are 8, 16 (default), 24 (LEFT ALIGN in 32 bits type!!) and 32 bits
48  * #define MOZZI_I2S_PIN_BCK ... // /BLCK) default is 20
49  * //#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) ... // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21
50  * #define MOZZI_I2S_PIN_DATA ... // (DOUT) default is 22
51  * #define MOZZI_I2S_FORMAT ... // may be MOZZI_I2S_FORMAT_LSBJ or MOZZI_I2S_FORMAT_PLAIN (default)
52  * @endcode
53  *
54  * @note
55  * The MOZZI_I2S_FORMAT_LSBJ option may require a relatively recent git-hub checkout of the arduino-pico core.
56  *
57  * @section rp2040_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
58  * See @ref external_audio
59 */
60 
61 #if not IS_RP2040()
62 #error This header should be included for RP2040 architecture (Raspberry Pi Pico and others), only
63 #endif
64 
66 #if !defined(MOZZI_AUDIO_MODE)
67 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
68 #endif
69 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_I2S_DAC)
70 
71 #if !defined(MOZZI_AUDIO_RATE)
72 #define MOZZI_AUDIO_RATE 32768
73 #endif
74 
75 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
76 # if !defined(MOZZI_AUDIO_BITS)
77 # define MOZZI_AUDIO_BITS 11
78 # endif
79 # if !defined(MOZZI_AUDIO_PIN_1)
80 # define MOZZI_AUDIO_PIN_1 0
81 # endif
82 # if !defined(MOZZI_AUDIO_PIN_2)
83 # define MOZZI_AUDIO_PIN_2 1
84 # endif
85 #endif
86 
87 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
88 # if !defined(MOZZI_AUDIO_BITS)
89 # define MOZZI_AUDIO_BITS 16
90 # endif
91 # if !defined(MOZZI_I2S_PIN_BCK)
92 # define MOZZI_I2S_PIN_BCK 20
93 # endif
94 //# define MOZZI_IS_PIN_WS(MOZZI_I2S_PIN_BCK + 1) // implicit
95 # if !defined(MOZZI_I2S_PIN_DATA)
96 # define MOZZI_I2S_PIN_DATA 22
97 # endif
98 # if !defined(MOZZI_I2S_FORMAT)
99 # define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_PLAIN
100 # endif
101 MOZZI_CHECK_SUPPORTED(MOZZI_I2S_FORMAT, MOZZI_I2S_FORMAT_PLAIN, MOZZI_I2S_FORMAT_LSBJ)
102 # define BYPASS_MOZZI_OUTPUT_BUFFER true
103 # define MOZZI_RP2040_BUFFERS 8 // number of DMA buffers used
104 # define MOZZI_RP2040_BUFFER_SIZE 256 // total size of the buffer, in samples
105 #endif
106 
107 #if !defined(MOZZI_ANALOG_READ)
108 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
109 #endif
110 
111 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
112 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_ANALOG_READ_STANDARD)
113 
114 #endif // #ifndef CONFIG_CHECK_RP2040_H
#define MOZZI_ANALOG_READ
Whether to compile in support for non-blocking analog reads.
-
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_rp2040.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECK_RP2040_H
+
13 #define CONFIG_CHECK_RP2040_H
+
14 
+
15 /** @ingroup hardware
+
16  * @page hardware_rp2040 Mozzi on RP2040 (Raspberry Pi Pico)
+
17  *
+
18  * port by Thomas Friedrichsmeier
+
19  *
+
20  * @section rp2040_status Port status and notes
+
21  * Compiles and runs using [this core](https://github.com/earlephilhower/arduino-pico). Can probably be ported to the Mbed core for RP2040, relatively easily,
+
22  * as it relies mostly on the RP2040 SDK API. Tested on a Pi Pico.
+
23  *
+
24  * - This is a recent addition, implementation details may still change (currently just PWM driven by a timer; this may be worth changing to a DMA driven output)
+
25  * - Wavetables and samples are not kept in progmem on this platform. While apparently speed (of the external flash) is not much of an issue, the data always seems to be copied into RAM, anyway.
+
26  * - Note that getAudioInput() and mozziAnalogRead() return values in the RP2040's full ADC resolution of 0-4095 rather than AVR's 0-1023.
+
27  * - twi_nonblock is not ported
+
28  * - Code uses only one CPU core
+
29  *
+
30  * @section rp2040_output Output modes
+
31  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
32  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
33  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
34  * - MOZZI_OUTPUT_PWM
+
35  * - MOZZI_OUTPUT_I2S_DAC
+
36  *
+
37  * The default mode is @ref rp2040_pwm .
+
38  *
+
39  * @section rp2040_pdm MOZZI_OUTPUT_PWM
+
40  * Audio output is written to pin 0 (mono) or 0 and 1 (stereo), by default, with 11 bits of ouput resolution.
+
41  * One hardware timer interrupt and one DMA channel are claimed (number not hardcoded), a non-exclusive handler is installed on DMA_IRQ_0.
+
42  *
+
43  * Configuration options:
+
44  * @code
+
45  * #define MOZZI_AUDIO_PIN_1 ... // default is 0
+
46  * #define MOZZI_AUDIO_BITS ... // output resolution (bits); default is 11
+
47  * // additionally, for stereo:
+
48  * #define MOZZI_AUDIO_PIN_2 ... // default is 1; this must be on the same PWM slice as the first pin (i.e. neighboring)
+
49  * @endcode
+
50  *
+
51  * @section rp2040_i2s_dac MOZZI_OUTPUT_I2S_DAC
+
52  * Output to an external DAC, connected via I2S. This uses 16 bit (per audio channel), but can be changed to 8, 16, 24 (left aligned) and 32 resolution.
+
53  * Both plain I2S and LSBJ format (PT8211 needs this, for instance) are available. Plain format is used by default. The GPIO pins to use can be configured,
+
54  * - almost - freely (see below). Two DMA channels are claimed (numbers not hardcoded), non-exclusive handlers are installed on DMA_IRQ_0.
+
55  *
+
56  * Configuration options:
+
57  * @code
+
58  * #define MOZZI_AUDIO_BITS ... // available values are 8, 16 (default), 24 (LEFT ALIGN in 32 bits type!!) and 32 bits
+
59  * #define MOZZI_I2S_PIN_BCK ... // /BLCK) default is 20
+
60  * //#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) ... // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21
+
61  * #define MOZZI_I2S_PIN_DATA ... // (DOUT) default is 22
+
62  * #define MOZZI_I2S_FORMAT ... // may be MOZZI_I2S_FORMAT_LSBJ or MOZZI_I2S_FORMAT_PLAIN (default)
+
63  * @endcode
+
64  *
+
65  * @note
+
66  * The MOZZI_I2S_FORMAT_LSBJ option may require a relatively recent git-hub checkout of the arduino-pico core.
+
67  *
+
68  * @section rp2040_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
69  * See @ref external_audio
+
70 */
+
71 
+
72 #if not IS_RP2040()
+
73 #error This header should be included for RP2040 architecture (Raspberry Pi Pico and others), only
+
74 #endif
+
75 
+ +
77 #if !defined(MOZZI_AUDIO_MODE)
+
78 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
+
79 #endif
+
80 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_I2S_DAC)
+
81 
+
82 #if !defined(MOZZI_AUDIO_RATE)
+
83 #define MOZZI_AUDIO_RATE 32768
+
84 #endif
+
85 
+
86 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
87 # if !defined(MOZZI_AUDIO_BITS)
+
88 # define MOZZI_AUDIO_BITS 11
+
89 # endif
+
90 # if !defined(MOZZI_AUDIO_PIN_1)
+
91 # define MOZZI_AUDIO_PIN_1 0
+
92 # endif
+
93 # if !defined(MOZZI_AUDIO_PIN_2)
+
94 # define MOZZI_AUDIO_PIN_2 1
+
95 # endif
+
96 #endif
+
97 
+
98 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
+
99 # if !defined(MOZZI_AUDIO_BITS)
+
100 # define MOZZI_AUDIO_BITS 16
+
101 # endif
+
102 # if !defined(MOZZI_I2S_PIN_BCK)
+
103 # define MOZZI_I2S_PIN_BCK 20
+
104 # endif
+
105 //# define MOZZI_IS_PIN_WS(MOZZI_I2S_PIN_BCK + 1) // implicit
+
106 # if !defined(MOZZI_I2S_PIN_DATA)
+
107 # define MOZZI_I2S_PIN_DATA 22
+
108 # endif
+
109 # if !defined(MOZZI_I2S_FORMAT)
+
110 # define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_PLAIN
+
111 # endif
+
112 MOZZI_CHECK_SUPPORTED(MOZZI_I2S_FORMAT, MOZZI_I2S_FORMAT_PLAIN, MOZZI_I2S_FORMAT_LSBJ)
+
113 # define BYPASS_MOZZI_OUTPUT_BUFFER true
+
114 # define MOZZI_RP2040_BUFFERS 8 // number of DMA buffers used
+
115 # define MOZZI_RP2040_BUFFER_SIZE 256 // total size of the buffer, in samples
+
116 #endif
+
117 
+
118 #if !defined(MOZZI_ANALOG_READ)
+
119 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
120 #endif
+
121 
+
122 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12
+
123 
+
124 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
+
125 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_ANALOG_READ_STANDARD)
+
126 
+
127 #endif // #ifndef CONFIG_CHECK_RP2040_H
diff --git a/extras/doc/html/config__checks__samd21_8h_source.html b/extras/doc/html/config__checks__samd21_8h_source.html index 00611c7cc..6582f6a4a 100644 --- a/extras/doc/html/config__checks__samd21_8h_source.html +++ b/extras/doc/html/config__checks__samd21_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_samd21.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,17 +99,95 @@
config_checks_samd21.h
-
1 #ifndef CONFIG_CHECK_SAMD21_H
2 #define CONFIG_CHECK_SAMD21_H
3 
4 /** @ingroup hardware
5  * @page hardware_samd Mozzi on SAMD21 based boards (Arduino Circuitplayground M0 and others)
6  *
7  * port by Adrian Freed
8  *
9  * @section samd_status Port status and notes
10  * - @def MOZZI_ANALOG_READ and MOZZI_ANALOG_INPUT are not implemented (contributions welcome)
11  * - We don't have a lot of data, which boards this port has been tested on. Success or not, let us know, if you are using Mozzi on SAMD21 boards
12  *
13  * @section samd_output_modes Output modes
14  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
15  * - MOZZI_OUTPUT_EXTERNAL_TIMED
16  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
17  * - MOZZI_OUTPUT_INTERNAL_DAC
18  *
19  * The default mode is @ref samd_internal_dac , meaning, only boards with an inbuilt DAC are covered by default
20  * (you could stil use one of the external output modes, however).
21  *
22  * @section samd_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
23  * Output resolution is 10 bits by default, and goes to pin DAC0. Only mono output is supported. Within the hardware limits of your board, you can configure the following:
24  *
25  * @code
26  * #define MOZZI_AUDIO_PIN_1 ... // default is DAC0
27  * #define MOZZI_AUDIO_BITS ... // default is 10
28  * @endcode
29  *
30  * @section samd_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
31  * See @ref external_audio
32 */
33 
34 #if not IS_SAMD21()
35 #error This header should be included for SAMD21 architecture (Arduino Circuitplayground M0 and others), only
36 #endif
37 
39 #if !defined(MOZZI_AUDIO_MODE)
40 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
41 #endif
42 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC)
43 
44 #if !defined(MOZZI_AUDIO_RATE)
45 #define MOZZI_AUDIO_RATE 32768
46 #endif
47 
48 #if defined(MOZZI_PWM_RATE)
49 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
50 #endif
51 
52 #if !defined(MOZZI_ANALOG_READ)
53 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
54 #endif
55 
56 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
57 
58 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
59 # if !defined(MOZZI_AUDIO_BITS)
60 # define MOZZI_AUDIO_BITS 10
61 # endif
62 # if !defined(MOZZI_AUDIO_PIN_1)
63 # define MOZZI_AUDIO_PIN_1 DAC0
64 # endif
65 # include "disable_stereo_on_github_workflow.h"
66 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
67 #endif
68 
69 #endif // #ifndef CONFIG_CHECK_SAMD21_H
#define MOZZI_ANALOG_READ
Whether to compile in support for non-blocking analog reads.
-
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_samd21.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECK_SAMD21_H
+
13 #define CONFIG_CHECK_SAMD21_H
+
14 
+
15 /** @ingroup hardware
+
16  * @page hardware_samd Mozzi on SAMD21 based boards (Arduino Circuitplayground M0 and others)
+
17  *
+
18  * port by Adrian Freed
+
19  *
+
20  * @section samd_status Port status and notes
+
21  * - @def MOZZI_ANALOG_READ and MOZZI_ANALOG_INPUT are not implemented (contributions welcome)
+
22  * - We don't have a lot of data, which boards this port has been tested on. Success or not, let us know, if you are using Mozzi on SAMD21 boards
+
23  *
+
24  * @section samd_output_modes Output modes
+
25  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
26  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
27  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
28  * - MOZZI_OUTPUT_INTERNAL_DAC
+
29  *
+
30  * The default mode is @ref samd_internal_dac , meaning, only boards with an inbuilt DAC are covered by default
+
31  * (you could stil use one of the external output modes, however).
+
32  *
+
33  * @section samd_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
+
34  * Output resolution is 10 bits by default, and goes to pin DAC0. Only mono output is supported. Within the hardware limits of your board, you can configure the following:
+
35  *
+
36  * @code
+
37  * #define MOZZI_AUDIO_PIN_1 ... // default is DAC0
+
38  * #define MOZZI_AUDIO_BITS ... // default is 10
+
39  * @endcode
+
40  *
+
41  * @section samd_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
42  * See @ref external_audio
+
43 */
+
44 
+
45 #if not IS_SAMD21()
+
46 #error This header should be included for SAMD21 architecture (Arduino Circuitplayground M0 and others), only
+
47 #endif
+
48 
+ +
50 #if !defined(MOZZI_AUDIO_MODE)
+
51 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
+
52 #endif
+
53 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC)
+
54 
+
55 #if !defined(MOZZI_AUDIO_RATE)
+
56 #define MOZZI_AUDIO_RATE 32768
+
57 #endif
+
58 
+
59 #if defined(MOZZI_PWM_RATE)
+
60 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
+
61 #endif
+
62 
+
63 #if !defined(MOZZI_ANALOG_READ)
+
64 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
+
65 #endif
+
66 
+
67 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
+
68 
+
69 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
70 # if !defined(MOZZI_AUDIO_BITS)
+
71 # define MOZZI_AUDIO_BITS 10
+
72 # endif
+
73 # if !defined(MOZZI_AUDIO_PIN_1)
+
74 # define MOZZI_AUDIO_PIN_1 DAC0
+
75 # endif
+
76 # include "disable_stereo_on_github_workflow.h"
+
77 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
+
78 #endif
+
79 
+
80 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12
+
81 
+
82 #endif // #ifndef CONFIG_CHECK_SAMD21_H
diff --git a/extras/doc/html/config__checks__stm32duino_8h_source.html b/extras/doc/html/config__checks__stm32duino_8h_source.html index 232c7820e..4ae6e5a43 100644 --- a/extras/doc/html/config__checks__stm32duino_8h_source.html +++ b/extras/doc/html/config__checks__stm32duino_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_stm32duino.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,158 @@
config_checks_stm32duino.h
-
1 #ifndef CONFIG_CHECKS_STM32DUINO_H
2 #define CONFIG_CHECKS_STM32DUINO_H
3 
4 /** @ingroup hardware
5 * @page hardware_stm32_disambiguation Mozzi on STM32-based boards - disambiguation
6 *
7 * * The situation on STM32-based boards is rather confusing, as there are several competing Arduino cores. Importantly:
8 * - Some boards use dedicated cores (e.g. Arduino Giga / Portenta @ref hardware_mbed) etc. For those, see the relevant sections (if we support them).
9 * - There is a series of libmaple-based cores, including [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32). These are highly optimized,
10 * and provide very complete support, but only for a limited number of boards. Unfortunately, at the time of this writing (2023/04), they are not available for installation
11 * via the Arduino Board Manager, and they do not currently seem actively maintained.
12 * For using these with Mozzi, see @ref hardware_stm32_maple
13 * - A generic Arduino core for STM32 is the [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32). It supports a huge set of boards, and seems to have offical
14 * backing by STM, but some features of the libmaple based cores are still lacking. To complete confusion, this core now uses the label "STM32duino", which used to be what
15 * the libmaple cores above were known by (don't blame Mozzi for this mess!).
16 * For using this with Mozzi, see @ref hardware_stm32duino
17 * */
18 
19 /** @ingroup hardware
20  * @page hardware_stm32duino Mozzi on STM32duino-based boards.
21  *
22  * port by Thomas Friedrichsmeier
23  *
24  * @note
25  * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32duino core.
26  *
27  * @section stm32duino_status Port status and usage notes
28  * Tested on a STM32F103C8T6 blue pill board as well as an STM32F411CE black pill board, i.e. on sboards _without_ a
29  * real DAC. Compiles and runs, with a bunch of caveats (see below). Should probably run on any other board supported by the
30  * [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32) (although this theory is untested).
31  * When trying any other board, you probably want to check the platform specific settings (see below), carefully, importantly, whether the desired output resolution is
32  * achievable, and whether the desired output pins are PWM capable.
33  *
34  * - @ref MOZZI_ANALOG_READ input implementation is somewhat experimental, and may not be able to service a whole lot of pins (contributions welcome)
35  * - @ref MOZZI_AUDIO_INPUT is completely untested (but implemented in theory; feedback welcome!)
36  * - getAudioInput() and mozziAnalogRead() return values in the STM32's full ADC resolution (the exact range depending on the board in use) rather than AVR's 0-1023.
37  * - twi_nonblock is not ported
38  *
39  * @section stm32duino_output_modes Output modes
40  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
41  * - MOZZI_OUTPUT_EXTERNAL_TIMED
42  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
43  * - MOZZI_OUTPUT_PWM
44  * - MOZZI_OUTPUT_PWM_2PIN
45  *
46  * The default mode is @ref stm32duino_pwm .
47  *
48  * @note
49  * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32_maple !
50  *
51  * @section stm32duino_pwm MOZZI_OUTPUT_PWM
52  * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PA8 (mono/left), PA9 (right channel in stereo).
53  * This mode uses two hardware timers: One for the PWM (Timer 3 when using the default pin configuration), and a second for updating the output at audio rate.
54  * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this.
55  * The following settings may be costumized, if desired:
56  *
57  * @code
58  * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PA8
59  * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim, must not be the same of the timer for the above pin. Default TIM2
60  * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10
61  * // For stereo, only:
62  * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PA9
63  * @endcode
64  *
65  * @section stm32duino_pwm MOZZI_OUTPUT_2PIN_PWM
66  * This mode is very similar to @ref stm32duino_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required
67  * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode.
68  * Output is at 2*7 bits at up to 560kHz carrier frequency (but limited to 5 times audio rate).
69  *
70  * Customizable configuration options:
71  * @code
72  * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PA8
73  * #define MOZZI_AUDIO_PIN_1_LOW ... // Low byte of the output. Default: PA9
74  * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2
75  * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7
76  * @endcode
77  *
78  * @section stm32duino_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
79  * See @ref external_audio .
80  * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2).
81 */
82 
83 #if not IS_STM32DUINO()
84 #error This header should be included for STM32 (stm32duino.com core), only
85 #endif
86 
87 #if !defined(MOZZI_AUDIO_MODE)
88 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
89 #endif
90 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
91 
92 #if !defined(MOZZI_AUDIO_RATE)
93 # define MOZZI_AUDIO_RATE 32768
94 #endif
95 
96 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
97 # if !defined(MOZZI_AUDIO_UPDATE_TIMER)
98 # define MOZZI_AUDIO_UPDATE_TIMER TIM2
99 # endif
100 #endif
101 
102 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
103 # if !defined(MOZZI_AUDIO_PIN_1)
104 # define MOZZI_AUDIO_PIN_1 PA8
105 # endif
106 # if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_1)
107 # define MOZZI_AUDIO_PIN_2 PA9
108 # endif
109 # if !defined(MOZZI_AUDIO_BITS)
110 # define MOZZI_AUDIO_BITS 10
111 # endif
112 # define MOZZI_AUDIO_BITS_PER_CHANNEL MOZZI_AUDIO_BITS
113 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
114 # if !defined(MOZZI_AUDIO_PIN_1)
115 # define MOZZI_AUDIO_PIN_1 PA8
116 # endif
117 # if !defined(MOZZI_AUDIO_PIN_1_LOW)
118 # define MOZZI_AUDIO_PIN_1_LOW PA9
119 # endif
120 # include "disable_stereo_on_github_workflow.h"
121 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
122 # if !defined(MOZZI_AUDIO_PER_CHANNEL)
123 # define MOZZI_AUDIO_BITS_PER_CHANNEL 7
124 # endif
125 # define MOZZI_AUDIO_BITS (MOZZI_AUDIO_BITS_PER_CHANNEL * 2)
126 #endif
127 
128 #if !defined(MOZZI_ANALOG_READ)
129 #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
130 #endif
131 
132 
133 #endif // #ifndef CONFIG_CHECKS_STM32DUINO_H
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_stm32duino.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECKS_STM32DUINO_H
+
13 #define CONFIG_CHECKS_STM32DUINO_H
+
14 
+
15 /** @ingroup hardware
+
16 * @page hardware_stm32_disambiguation Mozzi on STM32-based boards - disambiguation
+
17 *
+
18 * * The situation on STM32-based boards is rather confusing, as there are several competing Arduino cores. Importantly:
+
19 * - Some boards use dedicated cores (e.g. Arduino Giga / Portenta @ref hardware_mbed) etc. For those, see the relevant sections (if we support them).
+
20 * - There is a series of libmaple-based cores, including [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32). These are highly optimized,
+
21 * and provide very complete support, but only for a limited number of boards. Unfortunately, at the time of this writing (2023/04), they are not available for installation
+
22 * via the Arduino Board Manager, and they do not currently seem actively maintained.
+
23 * For using these with Mozzi, see @ref hardware_stm32_maple
+
24 * - A generic Arduino core for STM32 is the [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32). It supports a huge set of boards, and seems to have offical
+
25 * backing by STM, but some features of the libmaple based cores are still lacking. To complete confusion, this core now uses the label "STM32duino", which used to be what
+
26 * the libmaple cores above were known by (don't blame Mozzi for this mess!).
+
27 * For using this with Mozzi, see @ref hardware_stm32duino
+
28 * */
+
29 
+
30 /** @ingroup hardware
+
31  * @page hardware_stm32duino Mozzi on STM32duino-based boards.
+
32  *
+
33  * port by Thomas Friedrichsmeier
+
34  *
+
35  * @note
+
36  * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32duino core.
+
37  *
+
38  * @section stm32duino_status Port status and usage notes
+
39  * Tested on a STM32F103C8T6 blue pill board as well as an STM32F411CE black pill board, i.e. on sboards _without_ a
+
40  * real DAC. Compiles and runs, with a bunch of caveats (see below). Should probably run on any other board supported by the
+
41  * [STM32duino core](https://github.com/stm32duino/Arduino_Core_STM32) (although this theory is untested).
+
42  * When trying any other board, you probably want to check the platform specific settings (see below), carefully, importantly, whether the desired output resolution is
+
43  * achievable, and whether the desired output pins are PWM capable.
+
44  *
+
45  * - @ref MOZZI_ANALOG_READ input implementation is somewhat experimental, and may not be able to service a whole lot of pins (contributions welcome)
+
46  * - @ref MOZZI_AUDIO_INPUT is completely untested (but implemented in theory; feedback welcome!)
+
47  * - getAudioInput() and mozziAnalogRead() return values in the STM32's full ADC resolution (the exact range depending on the board in use) rather than AVR's 0-1023.
+
48  * - twi_nonblock is not ported
+
49  *
+
50  * @section stm32duino_output_modes Output modes
+
51  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
52  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
53  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
54  * - MOZZI_OUTPUT_PWM
+
55  * - MOZZI_OUTPUT_PWM_2PIN
+
56  *
+
57  * The default mode is @ref stm32duino_pwm .
+
58  *
+
59  * @note
+
60  * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32_maple !
+
61  *
+
62  * @section stm32duino_pwm MOZZI_OUTPUT_PWM
+
63  * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PA8 (mono/left), PA9 (right channel in stereo).
+
64  * This mode uses two hardware timers: One for the PWM (Timer 3 when using the default pin configuration), and a second for updating the output at audio rate.
+
65  * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this.
+
66  * The following settings may be costumized, if desired:
+
67  *
+
68  * @code
+
69  * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PA8
+
70  * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim, must not be the same of the timer for the above pin. Default TIM2
+
71  * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10
+
72  * // For stereo, only:
+
73  * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PA9
+
74  * @endcode
+
75  *
+
76  * @section stm32duino_pwm MOZZI_OUTPUT_2PIN_PWM
+
77  * This mode is very similar to @ref stm32duino_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required
+
78  * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode.
+
79  * Output is at 2*7 bits at up to 560kHz carrier frequency (but limited to 5 times audio rate).
+
80  *
+
81  * Customizable configuration options:
+
82  * @code
+
83  * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PA8
+
84  * #define MOZZI_AUDIO_PIN_1_LOW ... // Low byte of the output. Default: PA9
+
85  * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2
+
86  * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7
+
87  * @endcode
+
88  *
+
89  * @section stm32duino_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
90  * See @ref external_audio .
+
91  * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2).
+
92 */
+
93 
+
94 #if not IS_STM32DUINO()
+
95 #error This header should be included for STM32 (stm32duino.com core), only
+
96 #endif
+
97 
+
98 #if !defined(MOZZI_AUDIO_MODE)
+
99 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
+
100 #endif
+
101 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
+
102 
+
103 #if !defined(MOZZI_AUDIO_RATE)
+
104 # define MOZZI_AUDIO_RATE 32768
+
105 #endif
+
106 
+
107 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
108 # if !defined(MOZZI_AUDIO_UPDATE_TIMER)
+
109 # define MOZZI_AUDIO_UPDATE_TIMER TIM2
+
110 # endif
+
111 #endif
+
112 
+
113 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
114 # if !defined(MOZZI_AUDIO_PIN_1)
+
115 # define MOZZI_AUDIO_PIN_1 PA8
+
116 # endif
+
117 # if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_1)
+
118 # define MOZZI_AUDIO_PIN_2 PA9
+
119 # endif
+
120 # if !defined(MOZZI_AUDIO_BITS)
+
121 # define MOZZI_AUDIO_BITS 10
+
122 # endif
+
123 # define MOZZI_AUDIO_BITS_PER_CHANNEL MOZZI_AUDIO_BITS
+
124 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
125 # if !defined(MOZZI_AUDIO_PIN_1)
+
126 # define MOZZI_AUDIO_PIN_1 PA8
+
127 # endif
+
128 # if !defined(MOZZI_AUDIO_PIN_1_LOW)
+
129 # define MOZZI_AUDIO_PIN_1_LOW PA9
+
130 # endif
+
131 # include "disable_stereo_on_github_workflow.h"
+
132 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
+
133 # if !defined(MOZZI_AUDIO_PER_CHANNEL)
+
134 # define MOZZI_AUDIO_BITS_PER_CHANNEL 7
+
135 # endif
+
136 # define MOZZI_AUDIO_BITS (MOZZI_AUDIO_BITS_PER_CHANNEL * 2)
+
137 #endif
+
138 
+
139 #if !defined(MOZZI_ANALOG_READ)
+
140 #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
141 #endif
+
142 
+
143 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION ADC_RESOLUTION
+
144 
+
145 #endif // #ifndef CONFIG_CHECKS_STM32DUINO_H
diff --git a/extras/doc/html/config__checks__stm32maple_8h_source.html b/extras/doc/html/config__checks__stm32maple_8h_source.html index 77603ded1..becd03b9e 100644 --- a/extras/doc/html/config__checks__stm32maple_8h_source.html +++ b/extras/doc/html/config__checks__stm32maple_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_stm32maple.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,150 @@
config_checks_stm32maple.h
-
1 #ifndef CONFIG_CHECKS_STM32MAPLE_H
2 #define CONFIG_CHECKS_STM32MAPLE_H
3 
4 /** @ingroup hardware
5  * @page hardware_stm32_maple Mozzi on STM32duino-based boards.
6  * port by Thomas Friedrichsmeier
7  *
8  * @note
9  * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32 "libmaple based" core.
10  *
11  * @note
12  * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32duino !
13  *
14  * @section stm32_maple_status Status and peculiarities of this port
15  * Compiles for and runs on a STM32F103C8T6 blue pill board, with a bunch of caveats (see below), i.e. on a board _without_ a
16  * real DAC. Should probably run on any other board supported by [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Arduino_STM32) (although this theory is untested).
17  *
18  * @note that at the time of this writing, [Stev Strong's slightliy more recent fork of this core](https://github.com/stevstrong/Arduino_STM32/) does *not* work with
19  * Mozzi, apparently due to a bug in pwmWrite().
20  *
21  * - If you want to use MIDI, be sure to replace "MIDI_CREATE_DEFAULT_INSTANCE()" with "MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI)" (or Serial2)
22  * - @ref MOZZI_AUDIO_INPUT_STANDARD is implemented in theory, but untested (feedback welcome)
23  * - getAudioInput() and mozziAnalogRead() return values in the STM32's full ADC resolution of 0-4095 rather than AVR's 0-1023.
24  *- twi_nonblock is not ported
25  *
26  * @section stm32_output_modes Output modes
27  *
28  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
29  * - MOZZI_OUTPUT_EXTERNAL_TIMED
30  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
31  * - MOZZI_OUTPUT_PWM
32  * - MOZZI_OUTPUT_PWM_2PIN
33  *
34  * The default mode is @ref stm32_maple_pwm .
35  *
36  * @section stm32_maple_pwm MOZZI_OUTPUT_PWM
37  * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PB8 (mono/left), PB9 (right channel in stereo).
38  * This mode uses two hardware timers: One for the PWM (Timer 4 when using the default pin configuration), and a second for updating the output at audio rate.
39  * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this.
40  * The following settings may be costumized, if desired:
41  *
42  * @code
43  * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PB8
44  * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set ot the hardware timer connected to the above pin. Default: 4
45  * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default 2
46  * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10
47  * // For stereo, only:
48  * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PB9
49  * @endcode
50  *
51  * @section stm32_maple_2pin_pwm MOZZI_OUTPUT_2PIN_PWM
52  * This mode is very similar to @ref stm32_maple_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required
53  * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode.
54  * Output is at 2*7 bits at up to 560kHz carrier frequency (but limited to 5 times audio rate).
55  *
56  * Customizable configuration options:
57  * @code
58  * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PB8
59  * #define MOZZI_AUDIO_PIN_2 ... // Low byte of the output. Default: PB9
60  * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set to the number of the hardware timer connect to the above pins. Default: 4
61  * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2
62  * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7
63  * @endcode
64  *
65  * @section stm32_maple_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
66  * See @ref external_audio
67  * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2).
68 */
69 
70 
71 #if not IS_STM32MAPLE()
72 #error This header should be included for STM32 (libmaple based core), only
73 #endif
74 
75 #if !defined(MOZZI_AUDIO_MODE)
76 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
77 #endif
78 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
79 
80 #if !defined(MOZZI_AUDIO_RATE)
81 # define MOZZI_AUDIO_RATE 32768
82 #endif
83 
84 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
85 # if !defined(MOZZI_AUDIO_UPDATE_TIMER)
86 # define MOZZI_AUDIO_UPDATE_TIMER 2
87 # endif
88 # if !defined(MOZZI_AUDIO_PWM_TIMER)
89 # define MOZZI_AUDIO_PWM_TIMER 4
90 # endif
91 #endif
92 
93 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
94 # if !defined(MOZZI_AUDIO_PIN_1)
95 # define MOZZI_AUDIO_PIN_1 PB8
96 # endif
97 # if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_1)
98 # define MOZZI_AUDIO_PIN_2 PB9
99 # endif
100 # if !defined(MOZZI_AUDIO_BITS)
101 # define MOZZI_AUDIO_BITS 10
102 # endif
103 # define MOZZI_AUDIO_BITS_PER_CHANNEL MOZZI_AUDIO_BITS
104 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
105 # if !defined(MOZZI_AUDIO_PIN_1)
106 # define MOZZI_AUDIO_PIN_1 PB8
107 # endif
108 # if !defined(MOZZI_AUDIO_PIN_1_LOW)
109 # define MOZZI_AUDIO_PIN_1_LOW PB9
110 # endif
111 # include "disable_stereo_on_github_workflow.h"
112 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
113 # if !defined(MOZZI_AUDIO_PER_CHANNEL)
114 # define MOZZI_AUDIO_PER_CHANNEL 7
115 # endif
116 # define MOZZI_AUDIO_BITS MOZZI_AUDIO_BITS_PER_CHANNEL * 2
117 #endif
118 
119 #if !defined(MOZZI_ANALOG_READ)
120 #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
121 #endif
122 
123 
124 #endif // #ifndef CONFIG_CHECKS_STM32MAPLE_H
#define MOZZI_AUDIO_MODE
+
1 /*
+
2  * config_checks_stm32maple.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECKS_STM32MAPLE_H
+
13 #define CONFIG_CHECKS_STM32MAPLE_H
+
14 
+
15 /** @ingroup hardware
+
16  * @page hardware_stm32_maple Mozzi on STM32duino-based boards.
+
17  * port by Thomas Friedrichsmeier
+
18  *
+
19  * @note
+
20  * Be sure to understand the info given at @ref hardwware_stm32_disambiguation . This page is about using Mozzi with the STM32 "libmaple based" core.
+
21  *
+
22  * @note
+
23  * This port may look similar to, but uses a different default GPIO pinout than @hardware_stm32duino !
+
24  *
+
25  * @section stm32_maple_status Status and peculiarities of this port
+
26  * Compiles for and runs on a STM32F103C8T6 blue pill board, with a bunch of caveats (see below), i.e. on a board _without_ a
+
27  * real DAC. Should probably run on any other board supported by [Roger Clark's libmaple-based core](https://github.com/rogerclarkmelbourne/Ardu0ino_STM32) (although this theory is untested).
+
28  *
+
29  * @note that at the time of this writing, [Stev Strong's slightliy more recent fork of this core](https://github.com/stevstrong/Arduino_STM32/) does *not* work with
+
30  * Mozzi, apparently due to a bug in pwmWrite().
+
31  *
+
32  * - If you want to use MIDI, be sure to replace "MIDI_CREATE_DEFAULT_INSTANCE()" with "MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI)" (or Serial2)
+
33  * - @ref MOZZI_AUDIO_INPUT_STANDARD is implemented in theory, but untested (feedback welcome)
+
34  * - getAudioInput() and mozziAnalogRead() return values in the STM32's full ADC resolution of 0-4095 rather than AVR's 0-1023.
+
35  *- twi_nonblock is not ported
+
36  *
+
37  * @section stm32_output_modes Output modes
+
38  *
+
39  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
40  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
41  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
42  * - MOZZI_OUTPUT_PWM
+
43  * - MOZZI_OUTPUT_PWM_2PIN
+
44  *
+
45  * The default mode is @ref stm32_maple_pwm .
+
46  *
+
47  * @section stm32_maple_pwm MOZZI_OUTPUT_PWM
+
48  * Standard pulse width modulated output to one (mono) or two (stereo, see @ref MOZZI_AUDIO_CHANNELS) GPIO pins. Default pinout: PB8 (mono/left), PB9 (right channel in stereo).
+
49  * This mode uses two hardware timers: One for the PWM (Timer 4 when using the default pin configuration), and a second for updating the output at audio rate.
+
50  * The default audio resolution is 10 bits, which results in a carrier frequency of ~70kHz on a 72MHz CPU. On slower boards you will have to descrease this.
+
51  * The following settings may be costumized, if desired:
+
52  *
+
53  * @code
+
54  * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: PB8
+
55  * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set ot the hardware timer connected to the above pin. Default: 4
+
56  * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default 2
+
57  * #define MOZZI_AUDIO_BITS ... // Output resolution in bits. Default is 10
+
58  * // For stereo, only:
+
59  * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. This *must* be connected to the same hardware timer as MOZZI_AUDIO_PIN_1 ! Default: PB9
+
60  * @endcode
+
61  *
+
62  * @section stm32_maple_2pin_pwm MOZZI_OUTPUT_2PIN_PWM
+
63  * This mode is very similar to @ref stm32_maple_pwm, but splitting output for a single channel across two GPIO pins for better resolution. For details on the required
+
64  * hardware setup, and configuration tradeoffs, see @ref avr_2pin_pwm . Stereo output is not available in this mode.
+
65  * Output is at 2*7 bits at up to 560kHz carrier frequency (but limited to 5 times audio rate).
+
66  *
+
67  * Customizable configuration options:
+
68  * @code
+
69  * #define MOZZI_AUDIO_PIN_1 ... // High byte of the output. Default: PB8
+
70  * #define MOZZI_AUDIO_PIN_2 ... // Low byte of the output. Default: PB9
+
71  * #define MOZZI_AUDIO_PWM_TIMER ... // Must be set to the number of the hardware timer connect to the above pins. Default: 4
+
72  * #define MOZZI_AUDIO_UPDATE_TIMER ... // Second hardware timer to claim. Default TIM2
+
73  * #define MOZZI_AUDIO_BITS_PER_CHANNEL ... // Bits per pin. Default is 7
+
74  * @endcode
+
75  *
+
76  * @section stm32_maple_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
77  * See @ref external_audio
+
78  * The (single) hardware timer claimed for MOZZI_OUTPUT_EXTERNAL_TIMED may be configured using "MOZZI_AUDIO_UPDATE_TIMER" (default: TIM2).
+
79 */
+
80 
+
81 
+
82 #if not IS_STM32MAPLE()
+
83 #error This header should be included for STM32 (libmaple based core), only
+
84 #endif
+
85 
+
86 #if !defined(MOZZI_AUDIO_MODE)
+
87 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
+
88 #endif
+
89 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
+
90 
+
91 #if !defined(MOZZI_AUDIO_RATE)
+
92 # define MOZZI_AUDIO_RATE 32768
+
93 #endif
+
94 
+
95 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
96 # if !defined(MOZZI_AUDIO_UPDATE_TIMER)
+
97 # define MOZZI_AUDIO_UPDATE_TIMER 2
+
98 # endif
+
99 # if !defined(MOZZI_AUDIO_PWM_TIMER)
+
100 # define MOZZI_AUDIO_PWM_TIMER 4
+
101 # endif
+
102 #endif
+
103 
+
104 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
105 # if !defined(MOZZI_AUDIO_PIN_1)
+
106 # define MOZZI_AUDIO_PIN_1 PB8
+
107 # endif
+
108 # if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_1)
+
109 # define MOZZI_AUDIO_PIN_2 PB9
+
110 # endif
+
111 # if !defined(MOZZI_AUDIO_BITS)
+
112 # define MOZZI_AUDIO_BITS 10
+
113 # endif
+
114 # define MOZZI_AUDIO_BITS_PER_CHANNEL MOZZI_AUDIO_BITS
+
115 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
116 # if !defined(MOZZI_AUDIO_PIN_1)
+
117 # define MOZZI_AUDIO_PIN_1 PB8
+
118 # endif
+
119 # if !defined(MOZZI_AUDIO_PIN_1_LOW)
+
120 # define MOZZI_AUDIO_PIN_1_LOW PB9
+
121 # endif
+
122 # include "disable_stereo_on_github_workflow.h"
+
123 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
+
124 # if !defined(MOZZI_AUDIO_PER_CHANNEL)
+
125 # define MOZZI_AUDIO_PER_CHANNEL 7
+
126 # endif
+
127 # define MOZZI_AUDIO_BITS MOZZI_AUDIO_BITS_PER_CHANNEL * 2
+
128 #endif
+
129 
+
130 #if !defined(MOZZI_ANALOG_READ)
+
131 #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
132 #endif
+
133 
+
134 // TODO: This probably isn't correct for all boards!
+
135 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 12
+
136 
+
137 #endif // #ifndef CONFIG_CHECKS_STM32MAPLE_H
diff --git a/extras/doc/html/config__checks__teensy_8h_source.html b/extras/doc/html/config__checks__teensy_8h_source.html index 330371343..6b5035421 100644 --- a/extras/doc/html/config__checks__teensy_8h_source.html +++ b/extras/doc/html/config__checks__teensy_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_teensy.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,168 @@
config_checks_teensy.h
-
1 #ifndef CONFIG_CHECK_TEENSY_H
2 #define CONFIG_CHECK_TEENSY_H
3 
4 /** @ingroup hardware
5  * @page hardware_teensy3 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards.
6  *
7  * port by Tim Barrass
8  *
9  * @note
10  * For Teensy 4.x see @ref hardware_teensy4
11  *
12  * @section teensy3_status Port status and ussage notes
13  * This port requires the following two libraries (which should be part of a default installtion, however):
14  * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 3.* by Daniel Gilbert
15  * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva
16  *
17  * Some of the differences for Teensy 3.* which will affect users include:
18  * - twi_nonblock code by Marije Baalman for non-blocking I2C is not compatible with Teensy 3.0/3.1/3.2.
19  *
20  * @section teensy3_output Output modes
21  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
22  * - MOZZI_OUTPUT_EXTERNAL_TIMED
23  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
24  * - MOZZI_OUTPUT_INTERNAL_DAC
25  *
26  * The default mode is @ref teensy3_internal_dac .
27  *
28  * @section teensy3_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
29  * Output is to the inbuilt DAC. Output resolution is 12 bits. Mono, only. The DAC output pin differs from board to boards.
30  * In most cases the appropriate pin will be set outmatically. If needed, you can specify the DAC pin, explicitly:
31  *
32  * @code
33  * #define MOZZI_AUDIO_PIN_1 ... // Default: A14, A12, or A21, depending on board
34  * @endcode
35  *
36  * @section teensy3_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
37  * See @ref external_audio
38 */
39 
40 
41 /** @ingroup hardware
42  * @page hardware_teensy4 Mozzi on Teensy 4.x boards.
43  *
44  * port by Thomas Combriat
45  *
46  * @note
47  * For Teensy 3.x see @ref hardware_teensy3
48  *
49  * @section teensy4_status Port status and ussage notes
50  * This port requires the following two libraries (which should be part of a default installtion, however):
51  * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 4.* by Daniel Gilbert
52  * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva
53  *
54  * Contrary to the Teensy 3, the Teensy 4 do not have any DAC. The output is done on pin A8 (PWM) by default (see below).
55  * twi_nonblock is not ported.
56  *
57  * @section teensy3_output Output modes
58  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
59  * - MOZZI_OUTPUT_EXTERNAL_TIMED
60  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
61  * - MOZZI_OUTPUT_PWM
62  *
63  * The default mode is @ref teensy4_pwm .
64  *
65  * @section teensy4_pwm MOZZI_OUTPUT_PWM
66  * Output is to a GPIO pin (or two in stereo). The output resolution is fixed at 10 bits, and a 146484 kHz carrier frequency.
67  * The output pins can be configured as:
68  *
69  * @code
70  * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: A8
71  * // For stereo, only:
72  * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. Default: A9
73  * @endcode
74  *
75  * @section teensy4_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
76  * See @ref external_audio
77 */
78 
79 
80 #if !(IS_TEENSY3() || IS_TEENSY4())
81 #error This header should be included for Teensy (3.x or 4.x) boards, only
82 #endif
83 
84 
85 
86 #if IS_TEENSY3()
87 # include "disable_2pinmode_on_github_workflow.h"
88 # if !defined(MOZZI_AUDIO_MODE)
89 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
90 # endif
91 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC)
92 #elif IS_TEENSY4()
93 # include "disable_2pinmode_on_github_workflow.h"
94 # if !defined(MOZZI_AUDIO_MODE)
95 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
96 # endif
97 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM)
98 #endif
99 
100 #if !defined(MOZZI_AUDIO_RATE)
101 #define MOZZI_AUDIO_RATE 32768
102 #endif
103 
104 #if defined(MOZZI_PWM_RATE)
105 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
106 #endif
107 
108 #if !defined(MOZZI_ANALOG_READ)
109 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
110 #endif
111 
112 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
113 
114 #include "teensyPinMap.h"
115 
116 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
117 # define MOZZI_AUDIO_BITS 12 // not configurable
118 # if !defined(MOZZI_AUDIO_PIN_1)
119 # if defined(__MKL26Z64__)
120 # define MOZZI_AUDIO_PIN_1 A12
121 # elif defined(__MK20DX128__) || defined(__MK20DX256__)
122 # define MOZZI_AUDIO_PIN_1 A14
123 # elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
124 # define MOZZI_AUDIO_PIN_1 A21
125 # else
126 # error DAC pin not know for this board. Please define MOZZI_AUDIO_PIN_1 as appropriate
127 # endif
128 # endif
129 # include "disable_stereo_on_github_workflow.h"
130 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
131 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
132 # define MOZZI_AUDIO_BITS 10 // not configurable
133 # if !defined(MOZZI_AUDIO_PIN_1)
134 # define MOZZI_AUDIO_PIN_1 A8
135 # endif
136 # if !defined(MOZZI_AUDIO_PIN_2)
137 # define MOZZI_AUDIO_PIN_2 A9
138 # endif
139 #endif
140 
141 #endif // #ifndef CONFIG_CHECK_TEENSY_H
#define MOZZI_ANALOG_READ
Whether to compile in support for non-blocking analog reads.
+
1 /*
+
2  * config_checks_teensy.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2023-2024 Thomas Friedrichsmeier 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 CONFIG_CHECK_TEENSY_H
+
13 #define CONFIG_CHECK_TEENSY_H
+
14 
+
15 /** @ingroup hardware
+
16  * @page hardware_teensy3 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards.
+
17  *
+
18  * port by Tim Barrass
+
19  *
+
20  * @note
+
21  * For Teensy 4.x see @ref hardware_teensy4
+
22  *
+
23  * @section teensy3_status Port status and ussage notes
+
24  * This port requires the following two libraries (which should be part of a default installtion, however):
+
25  * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 3.* by Daniel Gilbert
+
26  * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva
+
27  *
+
28  * Some of the differences for Teensy 3.* which will affect users include:
+
29  * - twi_nonblock code by Marije Baalman for non-blocking I2C is not compatible with Teensy 3.0/3.1/3.2.
+
30  *
+
31  * @section teensy3_output Output modes
+
32  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
33  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
34  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
35  * - MOZZI_OUTPUT_INTERNAL_DAC
+
36  *
+
37  * The default mode is @ref teensy3_internal_dac .
+
38  *
+
39  * @section teensy3_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
+
40  * Output is to the inbuilt DAC. Output resolution is 12 bits. Mono, only. The DAC output pin differs from board to boards.
+
41  * In most cases the appropriate pin will be set outmatically. If needed, you can specify the DAC pin, explicitly:
+
42  *
+
43  * @code
+
44  * #define MOZZI_AUDIO_PIN_1 ... // Default: A14, A12, or A21, depending on board
+
45  * @endcode
+
46  *
+
47  * @section teensy3_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
48  * See @ref external_audio
+
49 */
+
50 
+
51 
+
52 /** @ingroup hardware
+
53  * @page hardware_teensy4 Mozzi on Teensy 4.x boards.
+
54  *
+
55  * port by Thomas Combriat
+
56  *
+
57  * @note
+
58  * For Teensy 3.x see @ref hardware_teensy3
+
59  *
+
60  * @section teensy4_status Port status and ussage notes
+
61  * This port requires the following two libraries (which should be part of a default installtion, however):
+
62  * - [Timer library](https://github.com/loglow/IntervalTimer) for Teensy 4.* by Daniel Gilbert
+
63  * - [ADC library](http://github.com/pedvide/ADC) by Pedro Villanueva
+
64  *
+
65  * Contrary to the Teensy 3, the Teensy 4 do not have any DAC. The output is done on pin A8 (PWM) by default (see below).
+
66  * twi_nonblock is not ported.
+
67  *
+
68  * @section teensy3_output Output modes
+
69  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
70  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
71  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
72  * - MOZZI_OUTPUT_PWM
+
73  *
+
74  * The default mode is @ref teensy4_pwm .
+
75  *
+
76  * @section teensy4_pwm MOZZI_OUTPUT_PWM
+
77  * Output is to a GPIO pin (or two in stereo). The output resolution is fixed at 10 bits, and a 146484 kHz carrier frequency.
+
78  * The output pins can be configured as:
+
79  *
+
80  * @code
+
81  * #define MOZZI_AUDIO_PIN_1 ... // Left / mono output pin. Default: A8
+
82  * // For stereo, only:
+
83  * #define MOZZI_AUDIO_PIN_2 ... // Right channel output pin. Default: A9
+
84  * @endcode
+
85  *
+
86  * @section teensy4_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
87  * See @ref external_audio
+
88 */
+
89 
+
90 
+
91 #if !(IS_TEENSY3() || IS_TEENSY4())
+
92 #error This header should be included for Teensy (3.x or 4.x) boards, only
+
93 #endif
+
94 
+
95 
+
96 
+
97 #if IS_TEENSY3()
+
98 # include "disable_2pinmode_on_github_workflow.h"
+
99 # if !defined(MOZZI_AUDIO_MODE)
+
100 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_INTERNAL_DAC
+
101 # endif
+
102 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_INTERNAL_DAC)
+
103 #elif IS_TEENSY4()
+
104 # include "disable_2pinmode_on_github_workflow.h"
+
105 # if !defined(MOZZI_AUDIO_MODE)
+
106 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
+
107 # endif
+
108 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PWM)
+
109 #endif
+
110 
+
111 #if !defined(MOZZI_AUDIO_RATE)
+
112 #define MOZZI_AUDIO_RATE 32768
+
113 #endif
+
114 
+
115 #if defined(MOZZI_PWM_RATE)
+
116 #error Configuration of MOZZI_PWM_RATE is not currently supported on this platform (always same as MOZZI_AUDIO_RATE)
+
117 #endif
+
118 
+
119 #if !defined(MOZZI_ANALOG_READ)
+
120 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
121 #endif
+
122 
+
123 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
+
124 
+
125 #include "teensyPinMap.h"
+
126 
+
127 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
128 # define MOZZI_AUDIO_BITS 12 // not configurable
+
129 # if !defined(MOZZI_AUDIO_PIN_1)
+
130 # if defined(__MKL26Z64__)
+
131 # define MOZZI_AUDIO_PIN_1 A12
+
132 # elif defined(__MK20DX128__) || defined(__MK20DX256__)
+
133 # define MOZZI_AUDIO_PIN_1 A14
+
134 # elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
+
135 # define MOZZI_AUDIO_PIN_1 A21
+
136 # else
+
137 # error DAC pin not know for this board. Please define MOZZI_AUDIO_PIN_1 as appropriate
+
138 # endif
+
139 # endif
+
140 # include "disable_stereo_on_github_workflow.h"
+
141 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
+
142 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
143 # define MOZZI_AUDIO_BITS 10 // not configurable
+
144 # if !defined(MOZZI_AUDIO_PIN_1)
+
145 # define MOZZI_AUDIO_PIN_1 A8
+
146 # endif
+
147 # if !defined(MOZZI_AUDIO_PIN_2)
+
148 # define MOZZI_AUDIO_PIN_2 A9
+
149 # endif
+
150 #endif
+
151 
+
152 //TODO: Not 100% sure this is correct in all cases.
+
153 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10
+
154 
+
155 #endif // #ifndef CONFIG_CHECK_TEENSY_H
diff --git a/extras/doc/html/config__checks__template_8h_source.html b/extras/doc/html/config__checks__template_8h_source.html index a4557fd77..286f26ec1 100644 --- a/extras/doc/html/config__checks__template_8h_source.html +++ b/extras/doc/html/config__checks__template_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_checks_template.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,141 @@
config_checks_template.h
-
1 /** NOTE Template only: Copy and adjust this file when adding a new port.
2  *
3  * More instructions on the process are to be found in MozziGuts_impl_template.hpp. Read those first!
4  *
5  * What this file shall do:
6  * 1) Set default values for certain configurable options. Try to stick to the defines already in use as much as possible,
7  * so configuration is consistent across ports.
8  * 2) Have some checks for configuration values that are not supported on this port
9  * 3) Document some details of your port
10  */
11 
12 /** NOTE: If your port doesn't support MOZZI_OUTPUT_2PIN_PWM, add this include to make compilation of HIFI examples pass on the github runner */
14 /** NOTE: All ports need to provide a default for this */
15 #if not defined(MOZZI_AUDIO_MODE)
16 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
17 #endif
18 /** NOTE: And all ports should allow only supported output modes. Note that MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
19 are usually trivial to implement, so we'll assume your port allows them, too: */
20 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
21 
22 /** NOTE: All ports need to provide a default for this. 32768 is reasonable on most modern MCUs, but 16384 may be useful for weaker MCUs. */
23 #if not defined(MOZZI_AUDIO_RATE)
24 # define MOZZI_AUDIO_RATE 32768
25 #endif
26 
27 /** NOTE: *If* your port has an implementation for asynchronous analog reads, these shall be enabled by default. */
28 #if not defined(MOZZI_ANALOG_READ)
29 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
30 #endif
31 /** NOTE: *Otherwise* you may additionally document that as not-yet-supported like so: */
32 // MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ)
33 
34 /** NOTE: Example for additional config options depending on a specific output mode: */
35 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_INTERNAL_DAC)
36 # if !defined(MOZZI_AUDIO_PIN_1)
37 # define MOZZI_AUDIO_PIN_1 5
38 # endif
39 /** NOTE: All ports need to provide a default for this, for all audio modes _except_ for the external ones: */
40 # if !defined(MOZZI_AUDIO_BITS)
41 # define MOZZI_AUDIO_BITS 10
42 # endif
43 /** NOTE: If only mono is supported in this output mode: */
44 # include "disable_stereo_on_github_workflow.h" // This allows stereo sketches to compile (in mono) in automated testing builds.
45 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO)
46 #endif
47 
48 /** NOTE: You may also set further, implementation-specific defines, here. E.g. BYPASS_MOZZI_OUTPUT_BUFFER. Defines that are purely
49  * specific to your port (i.e. only needed inside MozziGuts_impt_YOURPLATFORM.h, should be #undef'ed at the end of that file. */
50 
51 
52 /** NOTE: The following is an example documentation for your port. In order not to end up in the real documentation, the comment starts
53  * with "/*", only. Change that to "/**" to enable documentation to be extracted. */
54 
55 /* @ingroup hardware
56  * @page hardware_MYPORT Mozzi on MYPORT architecture based boards (e.g. MOST PROMINENT BOARD)
57  *
58  * Port added by YOUR_NAME.
59  *
60  * @section MYPORT_status Status of this port and usage notes
61  * This port has been tested on BOARD A, BOARD B, but is expected to work on other boards using this family of MCUs, too.
62  * The default MOZZI_AUDIO_RATE is set to 32678 Hz. Asynchronous analog reads are not yet implemented, so be careful
63  * not to use mozziAnalogRead() too much. Also @ref MOZZI_AUDIO_INPUT is not available.
64  *
65  * When connecting external circuitry, keep in mind that the GPIO pins on this CPU are rated at a max of 3 mA. Be careful
66  * not to over-stress them. It is further recommended not to make use of feature X when using Mozzi, as it will
67  * introduce considerable noise into the audio.
68  *
69  * Also, something else to keep in mind about this port.
70  *
71  * @section MYPORT_output_modes Output modes
72  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
73  * - MOZZI_OUTPUT_EXTERNAL_TIMED
74  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
75  * - MOZZI_OUTPUT_INTERNAL_DAC
76  *
77  * The default mode is @ref MYPORT_internal_dac , meaning, only boards with an inbuilt DAC are covered by default
78  * (you could stil use one of the external output modes, however).
79  *
80  * @section MYPORT_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
81  * Output resolution is 10 bits by default, and goes to pin DAC0. Hardware timer 1 is claimed by Mozzi.
82  * Only mono output is supported. Within the hardware limits of your board, you can configure the following:
83  *
84  * @code
85  * #define MOZZI_AUDIO_PIN_1 ... // default is DAC0
86  * #define MOZZI_AUDIO_BITS ... // default is 10
87  * @endcode
88  *
89  * @section MYPORT_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
90  * See @ref external_audio
91 */
#define MOZZI_AUDIO_MODE
+
1 /** NOTE Template only: Copy and adjust this file when adding a new port.
+
2  *
+
3  * More instructions on the process are to be found in MozziGuts_impl_template.hpp. Read those first!
+
4  *
+
5  * What this file shall do:
+
6  * 1) Set default values for certain configurable options. Try to stick to the defines already in use as much as possible,
+
7  * so configuration is consistent across ports.
+
8  * 2) Have some checks for configuration values that are not supported on this port
+
9  * 3) Document some details of your port
+
10  */
+
11 
+
12 /*
+
13  * config_checks_template.h
+
14  *
+
15  * This file is part of Mozzi.
+
16  *
+
17  * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team
+
18  * NOTE: In your port, don't forget to update the above copyright notice!
+
19  *
+
20  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
21  *
+
22 */
+
23 
+
24 /** NOTE: If your port doesn't support MOZZI_OUTPUT_2PIN_PWM, add this include to make compilation of HIFI examples pass on the github runner */
+ +
26 /** NOTE: All ports need to provide a default for this */
+
27 #if not defined(MOZZI_AUDIO_MODE)
+
28 # define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
+
29 #endif
+
30 /** NOTE: And all ports should allow only supported output modes. Note that MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
31 are usually trivial to implement, so we'll assume your port allows them, too: */
+
32 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
+
33 
+
34 /** NOTE: All ports need to provide a default for this. 32768 is reasonable on most modern MCUs, but 16384 may be useful for weaker MCUs. */
+
35 #if not defined(MOZZI_AUDIO_RATE)
+
36 # define MOZZI_AUDIO_RATE 32768
+
37 #endif
+
38 
+
39 /** NOTE: *If* your port has an implementation for asynchronous analog reads, these shall be enabled by default. */
+
40 #if not defined(MOZZI_ANALOG_READ)
+
41 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
42 #endif
+
43 /** NOTE: *Otherwise* you may additionally document that as not-yet-supported like so: */
+
44 // MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ)
+
45 
+
46 /** NOTE: This should be set to whichever resolution (in bits) mozziAnalogRead() returns values in by default in your implementation.
+
47  * mozziAnalogRead<bits>() will shift the return value accordingly. Generally you will set this to the default hardware resolution for this platform.
+
48  *
+
49  * @em Optionally, you could to set this to the user configurable MOZZI_ANALOG_READ_RESOLUTION (if it has been defined), and configure your ADC reads,
+
50  * accordingly, avoiding the extra shift operation:
+
51  *
+
52  * @code
+
53 #ifdef MOZZI_ANALOG_READ_RESOLUTION
+
54 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION MOZZI_ANALOG_READ_RESOLUTION
+
55 #define MOZZI__IMPL_SET_ANALOG_READ_RESOLUTION
+
56 #else
+
57 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 16
+
58 #endif
+
59 
+
60 [...]
+
61 
+
62 //inside MozziGuts_impl_MPLATFORM, function setupMozziADC():
+
63 #ifdef MOZZI__IMPL_SET_ANALOG_READ_RESOLUTION
+
64 analogReadResolution(MOZZI_ANALOG_READ_RESOLUTION);
+
65 #endif
+
66  * @endcode
+
67 */
+
68 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10
+
69 
+
70 /** NOTE: Example for additional config options depending on a specific output mode: */
+
71 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_INTERNAL_DAC)
+
72 # if !defined(MOZZI_AUDIO_PIN_1)
+
73 # define MOZZI_AUDIO_PIN_1 5
+
74 # endif
+
75 /** NOTE: All ports need to provide a default for this, for all audio modes _except_ for the external ones: */
+
76 # if !defined(MOZZI_AUDIO_BITS)
+
77 # define MOZZI_AUDIO_BITS 10
+
78 # endif
+
79 /** NOTE: If only mono is supported in this output mode: */
+
80 # include "disable_stereo_on_github_workflow.h" // This allows stereo sketches to compile (in mono) in automated testing builds.
+
81 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO)
+
82 #endif
+
83 
+
84 
+
85 /** NOTE: You may also set further, implementation-specific defines, here. E.g. BYPASS_MOZZI_OUTPUT_BUFFER. Defines that are purely
+
86  * specific to your port (i.e. only needed inside MozziGuts_impt_YOURPLATFORM.h, should be #undef'ed at the end of that file. */
+
87 
+
88 
+
89 /** NOTE: The following is an example documentation for your port. In order not to end up in the real documentation, the comment starts
+
90  * with "/*", only. Change that to "/**" to enable documentation to be extracted. */
+
91 
+
92 /* @ingroup hardware
+
93  * @page hardware_MYPORT Mozzi on MYPORT architecture based boards (e.g. MOST PROMINENT BOARD)
+
94  *
+
95  * Port added by YOUR_NAME.
+
96  *
+
97  * @section MYPORT_status Status of this port and usage notes
+
98  * This port has been tested on BOARD A, BOARD B, but is expected to work on other boards using this family of MCUs, too.
+
99  * The default MOZZI_AUDIO_RATE is set to 32678 Hz. Asynchronous analog reads are not yet implemented, so be careful
+
100  * not to use mozziAnalogRead() too much. Also @ref MOZZI_AUDIO_INPUT is not available.
+
101  *
+
102  * When connecting external circuitry, keep in mind that the GPIO pins on this CPU are rated at a max of 3 mA. Be careful
+
103  * not to over-stress them. It is further recommended not to make use of feature X when using Mozzi, as it will
+
104  * introduce considerable noise into the audio.
+
105  *
+
106  * Also, something else to keep in mind about this port.
+
107  *
+
108  * @section MYPORT_output_modes Output modes
+
109  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
+
110  * - MOZZI_OUTPUT_EXTERNAL_TIMED
+
111  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
112  * - MOZZI_OUTPUT_INTERNAL_DAC
+
113  *
+
114  * The default mode is @ref MYPORT_internal_dac , meaning, only boards with an inbuilt DAC are covered by default
+
115  * (you could stil use one of the external output modes, however).
+
116  *
+
117  * @section MYPORT_internal_dac MOZZI_OUTPUT_INTERNAL_DAC
+
118  * Output resolution is 10 bits by default, and goes to pin DAC0. Hardware timer 1 is claimed by Mozzi.
+
119  * Only mono output is supported. Within the hardware limits of your board, you can configure the following:
+
120  *
+
121  * @code
+
122  * #define MOZZI_AUDIO_PIN_1 ... // default is DAC0
+
123  * #define MOZZI_AUDIO_BITS ... // default is 10
+
124  * @endcode
+
125  *
+
126  * @section MYPORT_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
127  * See @ref external_audio
+
128 */
diff --git a/extras/doc/html/config__example__avr__hifi_8h_source.html b/extras/doc/html/config__example__avr__hifi_8h_source.html index 1f006d2da..560ccc8a5 100644 --- a/extras/doc/html/config__example__avr__hifi_8h_source.html +++ b/extras/doc/html/config__example__avr__hifi_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_example_avr_hifi.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,32 @@
config_example_avr_hifi.h
-
1 /* Configuration example
2 
3 This example is targetted at the AVR platform (Arduino Uno & friends), only!
4 
5 Set configuration options according to the mode that was formerly known as "HIFI".
6 Do read up on the required hardware circuitry! */
7 
8 #include "MozziConfigValues.h" // for named option values
9 
10 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
11 //#define MOZZI_AUDIO_RATE 32768 // the default, in this mode
12 //#define MOZZI_PWM_RATE 125000 // the default, in this mode
13 //#define MOZZI_AUDIO_BITS_PER_CHANNEL 2 // the default, in this mode
14 
15 // should you wish to customize the output pins:
16 //#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN
17 //#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin
18 //#define AUDIO_AUDIO_PIN_1_LOW TIMER1_B_PIN
19 //#define MOZZI_AUDIO_PIN_1_LOW_REGISTER OCR1B // must also specify the hardware register responsible for this pin
#define MOZZI_OUTPUT_2PIN_PWM
+
1 /* Configuration example
+
2 
+
3 This example is targetted at the AVR platform (Arduino Uno & friends), only!
+
4 
+
5 Set configuration options according to the mode that was formerly known as "HIFI".
+
6 Do read up on the required hardware circuitry! */
+
7 
+
8 #include "MozziConfigValues.h" // for named option values
+
9 
+
10 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
+
11 //#define MOZZI_AUDIO_RATE 32768 // the default, in this mode
+
12 //#define MOZZI_PWM_RATE 125000 // the default, in this mode
+
13 //#define MOZZI_AUDIO_BITS_PER_CHANNEL 2 // the default, in this mode
+
14 
+
15 // should you wish to customize the output pins:
+
16 //#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN
+
17 //#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin
+
18 //#define AUDIO_AUDIO_PIN_1_LOW TIMER1_B_PIN
+
19 //#define MOZZI_AUDIO_PIN_1_LOW_REGISTER OCR1B // must also specify the hardware register responsible for this pin
diff --git a/extras/doc/html/config__example__avr__legacy__standard__mode_8h_source.html b/extras/doc/html/config__example__avr__legacy__standard__mode_8h_source.html index c4efca34e..56883206b 100644 --- a/extras/doc/html/config__example__avr__legacy__standard__mode_8h_source.html +++ b/extras/doc/html/config__example__avr__legacy__standard__mode_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_example_avr_legacy_standard_mode.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,28 @@
config_example_avr_legacy_standard_mode.h
-
1 /* Configuration example
2 
3 This example is targetted at the AVR platform (Arduino Uno & friends), only!
4 
5 Set configuration options according to the mode that was formerly known as "STANDARD" (not STANDARD_PLUS). */
6 
7 #include "MozziConfigValues.h" // for named option values
8 
9 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM
10 #define MOZZI_AUDIO_RATE 16384
11 #define MOZZI_PWM_RATE 16384
12 
13 // should you wish to customize the output pin:
14 //#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN
15 //#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin
+
1 /* Configuration example
+
2 
+
3 This example is targetted at the AVR platform (Arduino Uno & friends), only!
+
4 
+
5 Set configuration options according to the mode that was formerly known as "STANDARD" (not STANDARD_PLUS). */
+
6 
+
7 #include "MozziConfigValues.h" // for named option values
+
8 
+
9 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM
+
10 #define MOZZI_AUDIO_RATE 16384
+
11 #define MOZZI_PWM_RATE 16384
+
12 
+
13 // should you wish to customize the output pin:
+
14 //#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN
+
15 //#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin
+
diff --git a/extras/doc/html/config__example__avr__legacy__standardplus__mode_8h_source.html b/extras/doc/html/config__example__avr__legacy__standardplus__mode_8h_source.html index f455eff6b..5708b00c5 100644 --- a/extras/doc/html/config__example__avr__legacy__standardplus__mode_8h_source.html +++ b/extras/doc/html/config__example__avr__legacy__standardplus__mode_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_example_avr_legacy_standardplus_mode.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,31 @@
config_example_avr_legacy_standardplus_mode.h
-
1 /* Configuration example
2 
3 This example is targetted at the AVR platform (Arduino Uno & friends), only!
4 
5 The configuration formerly known as STANDARD_PLUS is still the default on AVR, so you
6 do not need to configure anything! This file just lists the relevant settings involved: */
7 
8 #include "MozziConfigValues.h" // for named option values
9 
10 // all of these are the defaults on AVR, anyway, thus commented
11 //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM
12 //#define MOZZI_AUDIO_RATE 16384
13 //#define MOZZI_PWM_RATE 32768
14 
15 
16 // should you wish to customize the output pin:
17 //#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN
18 //#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin
+
1 /* Configuration example
+
2 
+
3 This example is targetted at the AVR platform (Arduino Uno & friends), only!
+
4 
+
5 The configuration formerly known as STANDARD_PLUS is still the default on AVR, so you
+
6 do not need to configure anything! This file just lists the relevant settings involved: */
+
7 
+
8 #include "MozziConfigValues.h" // for named option values
+
9 
+
10 // all of these are the defaults on AVR, anyway, thus commented
+
11 //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM
+
12 //#define MOZZI_AUDIO_RATE 16384
+
13 //#define MOZZI_PWM_RATE 32768
+
14 
+
15 
+
16 // should you wish to customize the output pin:
+
17 //#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN
+
18 //#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin
+
diff --git a/extras/doc/html/config__example__avr__stereo_8h_source.html b/extras/doc/html/config__example__avr__stereo_8h_source.html index 9bc3039f0..9335a4482 100644 --- a/extras/doc/html/config__example__avr__stereo_8h_source.html +++ b/extras/doc/html/config__example__avr__stereo_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_example_avr_stereo.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,28 @@
config_example_avr_stereo.h
-
1 /* Configuration example
2 
3 This example is targetted at the AVR platform (Arduino Uno & friends), only!
4 
5 This example shows setting up stereo mode on AVR. */
6 
7 #include "MozziConfigValues.h" // for named option values
8 
9 #define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
10 
11 // should you wish to customize the output pins:
12 //#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN
13 //#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin
14 //#define AUDIO_AUDIO_PIN_2 TIMER1_B_PIN
15 //#define MOZZI_AUDIO_PIN_2_REGISTER OCR1B // must also specify the hardware register responsible for this pin
#define MOZZI_STEREO
+
1 /* Configuration example
+
2 
+
3 This example is targetted at the AVR platform (Arduino Uno & friends), only!
+
4 
+
5 This example shows setting up stereo mode on AVR. */
+
6 
+
7 #include "MozziConfigValues.h" // for named option values
+
8 
+
9 #define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
+
10 
+
11 // should you wish to customize the output pins:
+
12 //#define AUDIO_AUDIO_PIN_1 TIMER1_A_PIN
+
13 //#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A // must also specify the hardware register responsible for this pin
+
14 //#define AUDIO_AUDIO_PIN_2 TIMER1_B_PIN
+
15 //#define MOZZI_AUDIO_PIN_2_REGISTER OCR1B // must also specify the hardware register responsible for this pin
diff --git a/extras/doc/html/config__example__external_8h_source.html b/extras/doc/html/config__example__external_8h_source.html index c64d7a2a5..1ad6a6316 100644 --- a/extras/doc/html/config__example__external_8h_source.html +++ b/extras/doc/html/config__example__external_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_example_external.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,28 @@
config_example_external.h
-
1 /* Configuration example
2 
3 Configure Mozzi for "external" audio output. You will need to provide an audioOutput() function in your sketch.
4 
5 See TODO: link to relevant tutorial
6 */
7 
8 #include "MozziConfigValues.h" // for named option values
9 
10 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
11 // or use this:
12 //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM
13 
14 //#define MOZZI_AUDIO_RATE 32768 // the default, in this mode
15 //#define MOZZI_AUDIO_BITS 16 // the default in this mode, but e.g. when connecting to a 24-bit DAC, you'd set 24, here.
#define MOZZI_OUTPUT_EXTERNAL_TIMED
+
1 /* Configuration example
+
2 
+
3 Configure Mozzi for "external" audio output. You will need to provide an audioOutput() function in your sketch.
+
4 
+
5 See TODO: link to relevant tutorial
+
6 */
+
7 
+
8 #include "MozziConfigValues.h" // for named option values
+
9 
+
10 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
+
11 // or use this:
+
12 //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
13 
+
14 //#define MOZZI_AUDIO_RATE 32768 // the default, in this mode
+
15 //#define MOZZI_AUDIO_BITS 16 // the default in this mode, but e.g. when connecting to a 24-bit DAC, you'd set 24, here.
diff --git a/extras/doc/html/config__example__rp2040__i2s__pt8211__mono_8h_source.html b/extras/doc/html/config__example__rp2040__i2s__pt8211__mono_8h_source.html index 6d91d458a..3df7c4fc2 100644 --- a/extras/doc/html/config__example__rp2040__i2s__pt8211__mono_8h_source.html +++ b/extras/doc/html/config__example__rp2040__i2s__pt8211__mono_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_example_rp2040_i2s_pt8211_mono.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,18 +99,30 @@
config_example_rp2040_i2s_pt8211_mono.h
-
1 /* Configuration example
2 
3 This example is targetted at the RP2040 (raspberry Pi pico) platform only!
4 
5 Configure the Raspberry Pico to output sound in mono on a I2S DAC on LSBJ format (like the PT8211). */
6 
7 
8 #include "MozziConfigValues.h" // for named option values
9 
10 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_I2S_DAC
11 #define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_LSBJ // PT8211 is on LSBJ format
12 
13 // all of these are the defaults on RP2040 outputting on I2S, anyway, thus commented
14 #define MOZZI_AUDIO_BITS 16
15 #define MOZZI_I2S_PIN_BCK 20
16 #define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21
17 #define MOZZI_I2S_PIN_DATA 22
#define MOZZI_I2S_FORMAT_LSBJ
- -
#define MOZZI_OUTPUT_I2S_DAC
+
1 /* Configuration example
+
2 
+
3 This example is targetted at the RP2040 (raspberry Pi pico) platform only!
+
4 
+
5 Configure the Raspberry Pico to output sound in mono on a I2S DAC on LSBJ format (like the PT8211). */
+
6 
+
7 
+
8 #include "MozziConfigValues.h" // for named option values
+
9 
+
10 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_I2S_DAC
+
11 #define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_LSBJ // PT8211 is on LSBJ format
+
12 
+
13 // all of these are the defaults on RP2040 outputting on I2S, anyway, thus commented
+
14 #define MOZZI_AUDIO_BITS 16
+
15 #define MOZZI_I2S_PIN_BCK 20
+
16 #define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21
+
17 #define MOZZI_I2S_PIN_DATA 22
diff --git a/extras/doc/html/config__example__rp2040__pwm_8h_source.html b/extras/doc/html/config__example__rp2040__pwm_8h_source.html index 3f467443a..8036495ca 100644 --- a/extras/doc/html/config__example__rp2040__pwm_8h_source.html +++ b/extras/doc/html/config__example__rp2040__pwm_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: config_example_rp2040_pwm.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,29 @@
config_example_rp2040_pwm.h
-
1 /* Configuration example
2 
3 This example is targetted at the RP2040 (raspberry Pi pico) platform only!
4 
5 The configuration formerly known as STANDARD_PLUS is still the default on RP2040, so you
6 do not need to configure anything! This file just lists the relevant settings involved: */
7 
8 #include "MozziConfigValues.h" // for named option values
9 
10 // all of these are the defaults on RP2040, anyway, thus commented
11 //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM
12 //#define MOZZI_AUDIO_RATE 32768
13 
14 
15 // should you wish to customize the output pin:
16 //#define AUDIO_AUDIO_PIN_1 0
+
1 /* Configuration example
+
2 
+
3 This example is targetted at the RP2040 (raspberry Pi pico) platform only!
+
4 
+
5 The configuration formerly known as STANDARD_PLUS is still the default on RP2040, so you
+
6 do not need to configure anything! This file just lists the relevant settings involved: */
+
7 
+
8 #include "MozziConfigValues.h" // for named option values
+
9 
+
10 // all of these are the defaults on RP2040, anyway, thus commented
+
11 //#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_MODE_PWM
+
12 //#define MOZZI_AUDIO_RATE 32768
+
13 
+
14 
+
15 // should you wish to customize the output pin:
+
16 //#define AUDIO_AUDIO_PIN_1 0
+
diff --git a/extras/doc/html/dir_0d6feda837323b0c7a50b1cca0a6cf12.html b/extras/doc/html/dir_0d6feda837323b0c7a50b1cca0a6cf12.html index 479b23f61..34a12ba4f 100644 --- a/extras/doc/html/dir_0d6feda837323b0c7a50b1cca0a6cf12.html +++ b/extras/doc/html/dir_0d6feda837323b0c7a50b1cca0a6cf12.html @@ -1,9 +1,9 @@ - + - + Mozzi: SampleHuffman_Umpah Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -109,9 +105,7 @@ diff --git a/extras/doc/html/dir_3faa5fff9e46bf8b8f48c87f683ce0e6.html b/extras/doc/html/dir_3faa5fff9e46bf8b8f48c87f683ce0e6.html index 7453b2b3c..860258e6a 100644 --- a/extras/doc/html/dir_3faa5fff9e46bf8b8f48c87f683ce0e6.html +++ b/extras/doc/html/dir_3faa5fff9e46bf8b8f48c87f683ce0e6.html @@ -1,9 +1,9 @@ - + - + Mozzi: python Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -107,7 +103,7 @@

Files

file  char2mozzi.py [code]
A script for converting raw 8 bit sound data files to wavetables for Mozzi.

+ A script for converting raw 8 bit sound data files to wavetables for Mozzi.
 
@@ -116,9 +112,7 @@ diff --git a/extras/doc/html/dir_7374381ecdb819c64ee9b6ea2bd3370d.html b/extras/doc/html/dir_7374381ecdb819c64ee9b6ea2bd3370d.html index 7a44bec56..49da3cb64 100644 --- a/extras/doc/html/dir_7374381ecdb819c64ee9b6ea2bd3370d.html +++ b/extras/doc/html/dir_7374381ecdb819c64ee9b6ea2bd3370d.html @@ -1,9 +1,9 @@ - + - + Mozzi: internal Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -109,9 +105,7 @@ diff --git a/extras/doc/html/dir_91ea62b43b2ac03ee8b1ec98abec0fd0.html b/extras/doc/html/dir_91ea62b43b2ac03ee8b1ec98abec0fd0.html index f64c96978..392451905 100644 --- a/extras/doc/html/dir_91ea62b43b2ac03ee8b1ec98abec0fd0.html +++ b/extras/doc/html/dir_91ea62b43b2ac03ee8b1ec98abec0fd0.html @@ -1,9 +1,9 @@ - + - + Mozzi: Skeleton_Multi Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -109,9 +105,7 @@ diff --git a/extras/doc/html/dir_972072f1ab172f7c6da94578c90fb35b.html b/extras/doc/html/dir_972072f1ab172f7c6da94578c90fb35b.html index 47dbc880b..834184cff 100644 --- a/extras/doc/html/dir_972072f1ab172f7c6da94578c90fb35b.html +++ b/extras/doc/html/dir_972072f1ab172f7c6da94578c90fb35b.html @@ -1,9 +1,9 @@ - + - + Mozzi: 01.Basics Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/dir_9ca29615486e86932f4b900563144736.html b/extras/doc/html/dir_9ca29615486e86932f4b900563144736.html index 41f92718b..0e4d322c0 100644 --- a/extras/doc/html/dir_9ca29615486e86932f4b900563144736.html +++ b/extras/doc/html/dir_9ca29615486e86932f4b900563144736.html @@ -1,9 +1,9 @@ - + - + Mozzi: 08.Samples Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/dir_9f351d46ce3cc29445a41dc3a31e6919.html b/extras/doc/html/dir_9f351d46ce3cc29445a41dc3a31e6919.html index 4ac8ec3b4..f6ff7f69e 100644 --- a/extras/doc/html/dir_9f351d46ce3cc29445a41dc3a31e6919.html +++ b/extras/doc/html/dir_9f351d46ce3cc29445a41dc3a31e6919.html @@ -1,9 +1,9 @@ - + - + Mozzi: config Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -115,9 +111,7 @@ diff --git a/extras/doc/html/dir_d28a4824dc47e487b107a5db32ef43c4.html b/extras/doc/html/dir_d28a4824dc47e487b107a5db32ef43c4.html index 65e12422f..90088dcb7 100644 --- a/extras/doc/html/dir_d28a4824dc47e487b107a5db32ef43c4.html +++ b/extras/doc/html/dir_d28a4824dc47e487b107a5db32ef43c4.html @@ -1,9 +1,9 @@ - + - + Mozzi: examples Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -109,9 +105,7 @@ diff --git a/extras/doc/html/dir_da40a2d191134d083f9bacf4a8879a55.html b/extras/doc/html/dir_da40a2d191134d083f9bacf4a8879a55.html index 7b9530d5d..8c097057c 100644 --- a/extras/doc/html/dir_da40a2d191134d083f9bacf4a8879a55.html +++ b/extras/doc/html/dir_da40a2d191134d083f9bacf4a8879a55.html @@ -1,9 +1,9 @@ - + - + Mozzi: 03.Sensors Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -113,9 +109,7 @@ diff --git a/extras/doc/html/dir_dd81b9de5c9027a54e49f977944ecdc1.html b/extras/doc/html/dir_dd81b9de5c9027a54e49f977944ecdc1.html index ae2efe9e4..fe9c98e04 100644 --- a/extras/doc/html/dir_dd81b9de5c9027a54e49f977944ecdc1.html +++ b/extras/doc/html/dir_dd81b9de5c9027a54e49f977944ecdc1.html @@ -1,9 +1,9 @@ - + - + Mozzi: Piezo_SampleScrubber Directory Reference @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -109,9 +105,7 @@ diff --git a/extras/doc/html/disable__2pinmode__on__github__workflow_8h_source.html b/extras/doc/html/disable__2pinmode__on__github__workflow_8h_source.html index fe5e7423c..8e70cf123 100644 --- a/extras/doc/html/disable__2pinmode__on__github__workflow_8h_source.html +++ b/extras/doc/html/disable__2pinmode__on__github__workflow_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: disable_2pinmode_on_github_workflow.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@
- + @@ -80,7 +76,7 @@
@@ -103,15 +99,24 @@
disable_2pinmode_on_github_workflow.h
-
1 /* This purely internal header takes care of disabling stereo mode when on a github runner. Intended to be used
2  * on platforms that don't support stereo, allowing the compilation to proceed without error. */
3 
4 #if __has_include("../detect_github_runner.h") // the marker file we added inside the workflow
5  // do nothing, if this isn't present
6 # if defined(MOZZI_AUDIO_MODE) && MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
7 # undef MOZZI_AUDIO_MODE
8 # warning Disabled 2pin pwm output mode on github runner
9 # endif
10 
11 #endif
+
1 /* This purely internal header takes care of disabling stereo mode when on a github runner. Intended to be used
+
2  * on platforms that don't support stereo, allowing the compilation to proceed without error. */
+
3 
+
4 #if __has_include("../detect_github_runner.h") // the marker file we added inside the workflow
+
5  // do nothing, if this isn't present
+
6 # if defined(MOZZI_AUDIO_MODE) && MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
+
7 # undef MOZZI_AUDIO_MODE
+
8 # warning Disabled 2pin pwm output mode on github runner
+
9 # endif
+
10 
+
11 #endif
+
diff --git a/extras/doc/html/disable__stereo__on__github__workflow_8h_source.html b/extras/doc/html/disable__stereo__on__github__workflow_8h_source.html index e1544d0f1..4d1ba7725 100644 --- a/extras/doc/html/disable__stereo__on__github__workflow_8h_source.html +++ b/extras/doc/html/disable__stereo__on__github__workflow_8h_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: disable_stereo_on_github_workflow.h Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,15 +99,26 @@
disable_stereo_on_github_workflow.h
-
1 /* This purely internal header takes care of disabling stereo mode when on a github runner. Intended to be used
2  * on platforms that don't support stereo, allowing the compilation to proceed without error. */
3 
4 #if __has_include("../detect_github_runner.h") // the marker file we added inside the workflow
5  // do nothing, if this isn't present
6 # if defined(MOZZI_AUDIO_CHANNELS) && (MOZZI_AUDIO_CHANNELS > 1)
7 # define GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO
8 # undef MOZZI_AUDIO_CHANNELS
9 # define MOZZI_AUDIO_CHANNELS MOZZI_MONO
10 # warning Disabled stereo compilation while in Github runner.
11 # endif
12 
13 #endif
+
1 /* This purely internal header takes care of disabling stereo mode when on a github runner. Intended to be used
+
2  * on platforms that don't support stereo, allowing the compilation to proceed without error. */
+
3 
+
4 #if __has_include("../detect_github_runner.h") // the marker file we added inside the workflow
+
5  // do nothing, if this isn't present
+
6 # if defined(MOZZI_AUDIO_CHANNELS) && (MOZZI_AUDIO_CHANNELS > 1)
+
7 # define GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO
+
8 # undef MOZZI_AUDIO_CHANNELS
+
9 # define MOZZI_AUDIO_CHANNELS MOZZI_MONO
+
10 # warning Disabled stereo compilation while in Github runner.
+
11 # endif
+
12 
+
13 #endif
+
diff --git a/extras/doc/html/doxygen.css b/extras/doc/html/doxygen.css index c8f7a2a3f..f2c4902bd 100644 --- a/extras/doc/html/doxygen.css +++ b/extras/doc/html/doxygen.css @@ -1,4 +1,4 @@ -/* The standard CSS for doxygen 1.8.14 */ +/* The standard CSS for doxygen 1.9.1 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; @@ -53,17 +53,24 @@ dt { font-weight: bold; } -div.multicol { +ul.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; + column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; + column-count: 3; } p.startli, p.startdd { margin-top: 2px; } +th p.starttd, th p.intertd, th p.endtd { + font-size: 100%; + font-weight: 700; +} + p.starttd { margin-top: 0px; } @@ -80,6 +87,15 @@ p.endtd { margin-bottom: 2px; } +p.interli { +} + +p.interdd { +} + +p.intertd { +} + /* @end */ caption { @@ -87,30 +103,96 @@ caption { } span.legend { - font-size: 70%; - text-align: center; + font-size: 70%; + text-align: center; } h3.version { - font-size: 90%; - text-align: center; + font-size: 90%; + text-align: center; } -div.qindex, div.navtab{ - background-color: #E2E8D0; - border: 1px solid #889C4C; - text-align: center; +div.navtab { + border-right: 1px solid #889C4C; + padding-right: 15px; + text-align: right; + line-height: 110%; } -div.qindex, div.navpath { +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} +td.navtabHL { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +a.navtab { + font-weight: bold; +} + +div.qindex{ + text-align: center; width: 100%; line-height: 140%; + font-size: 130%; + color: #A0A0A0; } -div.navtab { - margin-right: 15px; +dt.alphachar{ + font-size: 180%; + font-weight: bold; } +.alphachar a{ + color: black; +} + +.alphachar a:hover, .alphachar a:visited{ + text-decoration: none; +} + +.classindex dl { + padding: 25px; + column-count:1 +} + +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; +} + +.classindex dl.odd { + background-color: #F4F6EE; +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } +} + + /* @group Link Styling */ a { @@ -127,19 +209,8 @@ a:hover { text-decoration: underline; } -a.qindex { - font-weight: bold; -} - -a.qindexHL { - font-weight: bold; - background-color: #7E9146; - color: #ffffff; - border: 1px double #637237; -} - .contents a.qindexHL:visited { - color: #ffffff; + color: #FFFFFF; } a.el { @@ -150,11 +221,11 @@ a.elRef { } a.code, a.code:visited, a.line, a.line:visited { - color: #4665A2; + color: #252B15; } a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { - color: #4665A2; + color: #252B15; } /* @end */ @@ -163,9 +234,28 @@ dl.el { margin-left: -1cm; } +ul { + overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + pre.fragment { - border: 1px solid #C4CFE5; - background-color: #FBFCFD; + border: 1px solid #AFC07D; + background-color: #F9FAF6; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; @@ -177,8 +267,8 @@ pre.fragment { } div.fragment { - padding: 0px; - margin: 4px 8px 4px 2px; + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; background-color: #F9FAF6; border: 1px solid #AFC07D; } @@ -248,7 +338,7 @@ span.lineno a:hover { div.ah, span.ah { background-color: black; font-weight: bold; - color: #ffffff; + color: #FFFFFF; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; @@ -324,7 +414,7 @@ img.formulaDsp { } -img.formulaInl { +img.formulaInl, img.inline { vertical-align: middle; } @@ -402,6 +492,13 @@ blockquote { padding: 0 12px 0 16px; } +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #7E9146; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + /* @end */ /* @@ -488,7 +585,7 @@ table.memberdecls { } .memSeparator { - border-bottom: 1px solid #DEE4F0; + border-bottom: 1px solid #CFD9B1; line-height: 1px; margin: 0px; padding: 0px; @@ -498,7 +595,7 @@ table.memberdecls { white-space: nowrap; } -.memItemRight { +.memItemRight, .memTemplItemRight { width: 100%; } @@ -666,17 +763,17 @@ dl.reflist dd { padding-left: 0px; } -.params .paramname, .retval .paramname { +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { font-weight: bold; vertical-align: top; } -.params .paramtype { +.params .paramtype, .tparams .paramtype { font-style: italic; vertical-align: top; } -.params .paramdir { +.params .paramdir, .tparams .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } @@ -1081,72 +1178,143 @@ div.headertitle padding: 5px 5px 5px 10px; } -dl -{ - padding: 0 0 0 10px; +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; } -/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ -dl.section -{ +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { margin-left: 0px; padding-left: 0px; } -dl.note -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #D0C000; +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; } -dl.warning, dl.attention -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #FF0000; +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; } -dl.pre, dl.post, dl.invariant -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00D000; +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; } -dl.deprecated -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #505050; +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; } -dl.todo -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00C0E0; +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; } -dl.test -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #3030E0; +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; } -dl.bug -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #C08050; +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; } dl.section dd { @@ -1245,10 +1413,12 @@ dl.citelist dt { font-weight:bold; margin-right:10px; padding:5px; + text-align:right; + width:52px; } dl.citelist dd { - margin:2px 0; + margin:2px 0 2px 72px; padding:5px 0; } @@ -1263,6 +1433,11 @@ div.toc { width: 200px; } +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; @@ -1271,6 +1446,12 @@ div.toc li { padding-top: 2px; } +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #252B15; @@ -1300,6 +1481,32 @@ div.toc li.level4 { margin-left: 45px; } +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ +} + +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + .inherit_header { font-weight: bold; color: gray; @@ -1413,7 +1620,7 @@ tr.heading h2 { } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { - border-top-color: #ffffff; + border-top-color: #FFFFFF; border-width: 10px; margin: 0px -10px; } @@ -1441,7 +1648,7 @@ tr.heading h2 { } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { - border-bottom-color: #ffffff; + border-bottom-color: #FFFFFF; border-width: 10px; margin: 0px -10px; } @@ -1468,7 +1675,7 @@ tr.heading h2 { left: 100%; } #powerTip.e:after { - border-left-color: #ffffff; + border-left-color: #FFFFFF; border-width: 10px; top: 50%; margin-top: -10px; @@ -1484,7 +1691,7 @@ tr.heading h2 { right: 100%; } #powerTip.w:after { - border-right-color: #ffffff; + border-right-color: #FFFFFF; border-width: 10px; top: 50%; margin-top: -10px; @@ -1517,7 +1724,6 @@ tr.heading h2 { /* @group Markdown */ -/* table.markdownTable { border-collapse:collapse; margin-top: 4px; @@ -1529,15 +1735,10 @@ table.markdownTable td, table.markdownTable th { padding: 3px 7px 2px; } -table.markdownTableHead tr { -} - -table.markdownTableBodyLeft td, table.markdownTable th { - border: 1px solid #0B0D06; - padding: 3px 7px 2px; +table.markdownTable tr { } -th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { background-color: #13160B; color: #FFFFFF; font-size: 110%; @@ -1545,52 +1746,48 @@ th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th padding-top: 5px; } -th.markdownTableHeadLeft { +th.markdownTableHeadLeft, td.markdownTableBodyLeft { text-align: left } -th.markdownTableHeadRight { +th.markdownTableHeadRight, td.markdownTableBodyRight { text-align: right } -th.markdownTableHeadCenter { +th.markdownTableHeadCenter, td.markdownTableBodyCenter { text-align: center } -*/ -table.markdownTable { - border-collapse:collapse; - margin-top: 4px; - margin-bottom: 4px; -} - -table.markdownTable td, table.markdownTable th { - border: 1px solid #0B0D06; - padding: 3px 7px 2px; +.DocNodeRTL { + text-align: right; + direction: rtl; } -table.markdownTable tr { +.DocNodeLTR { + text-align: left; + direction: ltr; } -th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { - background-color: #374F7F; - color: #FFFFFF; - font-size: 110%; - padding-bottom: 4px; - padding-top: 5px; +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; } -th.markdownTableHeadLeft, td.markdownTableBodyLeft { - text-align: left +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; } -th.markdownTableHeadRight, td.markdownTableBodyRight { - text-align: right +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; } +/* @end */ -th.markdownTableHeadCenter, td.markdownTableBodyCenter { - text-align: center +u { + text-decoration: underline; } - -/* @end */ diff --git a/extras/doc/html/dynsections.js b/extras/doc/html/dynsections.js index 537e3e498..88f2c27e6 100644 --- a/extras/doc/html/dynsections.js +++ b/extras/doc/html/dynsections.js @@ -1,25 +1,26 @@ /* - @licstart The following is the entire license notice for the - JavaScript code in this file. + @licstart The following is the entire license notice for the JavaScript code in this file. - Copyright (C) 1997-2017 by Dimitri van Heesch + The MIT License (MIT) - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + Copyright (C) 1997-2020 by Dimitri van Heesch - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. - @licend The above is the entire license notice - for the JavaScript code in this file + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file */ function toggleVisibility(linkObj) { @@ -60,7 +61,7 @@ function toggleLevel(level) $(this).show(); } else if (l==level+1) { i.removeClass('iconfclosed iconfopen').addClass('iconfclosed'); - a.html('▶'); + a.html('►'); $(this).show(); } else { $(this).hide(); @@ -87,7 +88,7 @@ function toggleFolder(id) // replace down arrow by right arrow for current row var currentRowSpans = currentRow.find("span"); currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed"); - currentRowSpans.filter(".arrow").html('▶'); + currentRowSpans.filter(".arrow").html('►'); rows.filter("[id^=row_"+id+"]").hide(); // hide all children } else { // we are SHOWING // replace right arrow by down arrow for current row @@ -97,7 +98,7 @@ function toggleFolder(id) // replace down arrows by right arrows for child rows var childRowsSpans = childRows.find("span"); childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed"); - childRowsSpans.filter(".arrow").html('▶'); + childRowsSpans.filter(".arrow").html('►'); childRows.show(); //show all children } updateStripes(); @@ -121,7 +122,7 @@ function toggleInherit(id) $(document).ready(function() { $('.code,.codeRef').each(function() { - $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html()); + $(this).data('powertip',$('#a'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html()); $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true }); }); }); diff --git a/extras/doc/html/examples.html b/extras/doc/html/examples.html index 6fe874d64..8f3a9ef18 100644 --- a/extras/doc/html/examples.html +++ b/extras/doc/html/examples.html @@ -1,9 +1,9 @@ - + - + Mozzi: Examples @@ -13,10 +13,6 @@ - @@ -37,13 +33,13 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -104,59 +100,57 @@
Here is a list of all examples:
@@ -164,9 +158,7 @@ diff --git a/extras/doc/html/examples.js b/extras/doc/html/examples.js index c48dcabe8..7fc6e2a66 100644 --- a/extras/doc/html/examples.js +++ b/extras/doc/html/examples.js @@ -1,30 +1,29 @@ var examples = [ - [ "01.Basics/Vibrato/Vibrato.ino", "01_8_basics_2_vibrato_2_vibrato_8ino-example.html", null ], + [ "07.Envelopes/ADSR_Envelope/ADSR_Envelope.ino", "07_8_envelopes_2_a_d_s_r__envelope_2_a_d_s_r__envelope_8ino-example.html", null ], + [ "09.Delays/AudioDelay/AudioDelay.ino", "09_8_delays_2_audio_delay_2_audio_delay_8ino-example.html", null ], + [ "09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino", "09_8_delays_2_audio_delay_feedback_2_audio_delay_feedback_8ino-example.html", null ], + [ "03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino", "03_8_sensors_2_knob__l_d_r_x2__wave_packet_2_knob__l_d_r_x2__wave_packet_8ino-example.html", null ], [ "02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino", "02_8_control_2_control__echo__theremin_2_control__echo__theremin_8ino-example.html", null ], - [ "02.Control/Control_Tremelo/Control_Tremelo.ino", "02_8_control_2_control__tremelo_2_control__tremelo_8ino-example.html", null ], + [ "05.Control_Filters/DCFilter/DCFilter.ino", "05_8_control__filters_2_d_c_filter_2_d_c_filter_8ino-example.html", null ], + [ "07.Envelopes/Ead_Envelope/Ead_Envelope.ino", "07_8_envelopes_2_ead__envelope_2_ead__envelope_8ino-example.html", null ], [ "02.Control/EventDelay/EventDelay.ino", "02_8_control_2_event_delay_2_event_delay_8ino-example.html", null ], + [ "02.Control/Control_Tremelo/Control_Tremelo.ino", "02_8_control_2_control__tremelo_2_control__tremelo_8ino-example.html", null ], + [ "06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino", "06_8_synthesis_2_non_alias__meta_oscil_2_non_alias__meta_oscil_8ino-example.html", null ], [ "02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino", "02_8_control_2_metronome__sample_huffman_2_metronome__sample_huffman_8ino-example.html", null ], - [ "03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino", "03_8_sensors_2_knob__l_d_r_x2__wave_packet_2_knob__l_d_r_x2__wave_packet_8ino-example.html", null ], - [ "05.Control_Filters/DCFilter/DCFilter.ino", "05_8_control__filters_2_d_c_filter_2_d_c_filter_8ino-example.html", null ], - [ "05.Control_Filters/Smooth/Smooth.ino", "05_8_control__filters_2_smooth_2_smooth_8ino-example.html", null ], - [ "05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino", "05_8_control__filters_2_teensy__u_s_b__m_i_d_i_portamento_2_teensy__u_s_b__m_i_d_i_portamento_8ino-example.html", null ], + [ "01.Basics/Vibrato/Vibrato.ino", "01_8_basics_2_vibrato_2_vibrato_8ino-example.html", null ], [ "05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino", "05_8_control__filters_2_thermistor__over_sample_2_thermistor__over_sample_8ino-example.html", null ], - [ "06.Synthesis/NonAlias_MetaOscil/NonAlias_MetaOscil.ino", "06_8_synthesis_2_non_alias__meta_oscil_2_non_alias__meta_oscil_8ino-example.html", null ], [ "06.Synthesis/PWM_Phasing/PWM_Phasing.ino", "06_8_synthesis_2_p_w_m__phasing_2_p_w_m__phasing_8ino-example.html", null ], - [ "06.Synthesis/WavePacket/WavePacket.ino", "06_8_synthesis_2_wave_packet_2_wave_packet_8ino-example.html", null ], - [ "06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino", "06_8_synthesis_2_wave_packet__sample_2_wave_packet__sample_8ino-example.html", null ], - [ "06.Synthesis/WaveShaper/WaveShaper.ino", "06_8_synthesis_2_wave_shaper_2_wave_shaper_8ino-example.html", null ], - [ "07.Envelopes/ADSR_Envelope/ADSR_Envelope.ino", "07_8_envelopes_2_a_d_s_r__envelope_2_a_d_s_r__envelope_8ino-example.html", null ], - [ "07.Envelopes/Ead_Envelope/Ead_Envelope.ino", "07_8_envelopes_2_ead__envelope_2_ead__envelope_8ino-example.html", null ], - [ "08.Samples/Sample/Sample.ino", "08_8_samples_2_sample_2_sample_8ino-example.html", null ], - [ "08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino", "08_8_samples_2_sample_huffman__umpah_2_sample_huffman__umpah_8ino-example.html", null ], - [ "09.Delays/AudioDelay/AudioDelay.ino", "09_8_delays_2_audio_delay_2_audio_delay_8ino-example.html", null ], - [ "09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino", "09_8_delays_2_audio_delay_feedback_2_audio_delay_feedback_8ino-example.html", null ], - [ "09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino", "09_8_delays_2_reverb_tank__s_t_a_n_d_a_r_d_2_reverb_tank__s_t_a_n_d_a_r_d_8ino-example.html", null ], - [ "10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino", "10_8_audio__filters_2_multi_resonant_filter_2_multi_resonant_filter_8ino-example.html", null ], + [ "05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino", "05_8_control__filters_2_teensy__u_s_b__m_i_d_i_portamento_2_teensy__u_s_b__m_i_d_i_portamento_8ino-example.html", null ], [ "10.Audio_Filters/ResonantFilter/ResonantFilter.ino", "10_8_audio__filters_2_resonant_filter_2_resonant_filter_8ino-example.html", null ], [ "10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino", "10_8_audio__filters_2_resonant_filter16_2_resonant_filter16_8ino-example.html", null ], + [ "10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino", "10_8_audio__filters_2_multi_resonant_filter_2_multi_resonant_filter_8ino-example.html", null ], + [ "09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino", "09_8_delays_2_reverb_tank__s_t_a_n_d_a_r_d_2_reverb_tank__s_t_a_n_d_a_r_d_8ino-example.html", null ], + [ "08.Samples/Sample/Sample.ino", "08_8_samples_2_sample_2_sample_8ino-example.html", null ], + [ "08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino", "08_8_samples_2_sample_huffman__umpah_2_sample_huffman__umpah_8ino-example.html", null ], + [ "05.Control_Filters/Smooth/Smooth.ino", "05_8_control__filters_2_smooth_2_smooth_8ino-example.html", null ], [ "11.Audio_Filters/StateVariableFilter/StateVariableFilter.ino", "11_8_audio__filters_2_state_variable_filter_2_state_variable_filter_8ino-example.html", null ], - [ "fromAlmostNBit", "from_almost_n_bit-example.html", null ] + [ "06.Synthesis/WavePacket/WavePacket.ino", "06_8_synthesis_2_wave_packet_2_wave_packet_8ino-example.html", null ], + [ "06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino", "06_8_synthesis_2_wave_packet__sample_2_wave_packet__sample_8ino-example.html", null ], + [ "06.Synthesis/WaveShaper/WaveShaper.ino", "06_8_synthesis_2_wave_shaper_2_wave_shaper_8ino-example.html", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/files.html b/extras/doc/html/files.html index 39338af11..685f067f8 100644 --- a/extras/doc/html/files.html +++ b/extras/doc/html/files.html @@ -1,9 +1,9 @@ - + - + Mozzi: File List @@ -13,10 +13,6 @@ - @@ -37,13 +33,13 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -107,97 +103,115 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 ADSR.h
 audio2huff.py
 AudioConfigESP.h
 AudioConfigESP32.h
 AudioConfigHiSpeed14bitPwm.h
 AudioConfigRP2040.h
 AudioConfigSAMD21.h
 AudioConfigStandard9bitPwm.h
 AudioConfigStandardPlus.h
 AudioConfigSTM32.h
 AudioConfigTeensy3_12bit.h
 AudioConfigTeensy4.h
 AudioDelay.h
 AudioDelayFeedback.h
 AudioOutput.h
 AutoMap.h
 AutoRange.h
 blahblah4b_int8.h
 CapPoll.h
 char2mozzi.py
A script for converting raw 8 bit sound data files to wavetables for Mozzi.
 chebyshev_int8.py
 CircularBuffer.h
 ControlDelay.h
 DCfilter.h
 Ead.h
 EventDelay.h
 float2mozzi.py
 float2mozzi_uint8.py
 hardware_defines.h
 IntegerType.h
 IntMap.h
 known_16bit_timers.h
 Line.h
 LowPassFilter.h
 meta.h
 MetaOscil.h
 Metronome.h
 mozzi_analog.cpp
 mozzi_analog.h
 mozzi_config.h
 mozzi_fixmath.cpp
 mozzi_fixmath.h
 mozzi_midi.cpp
 mozzi_midi.h
 mozzi_pgmspace.h
 mozzi_rand.cpp
 mozzi_rand.h
 mozzi_utils.cpp
 mozzi_utils.h
 MozziGuts.cpp
 MozziGuts.h
 MozziGuts_impl_AVR.hpp
 MozziGuts_impl_ESP32.hpp
 MozziGuts_impl_ESP8266.hpp
 MozziGuts_impl_RP2040.hpp
 MozziGuts_impl_SAMD.hpp
 MozziGuts_impl_STM32.hpp
 MozziGuts_impl_TEENSY.hpp
 MozziGuts_impl_template.hpp
 mult16x16.h
 mult16x8.h
 mult32x16.h
 Oscil.h
 OverSample.h
 PDResonant.h
 Phasor.h
 Portamento.h
 primes.h
 RCpoll.h
 ResonantFilter.h
 ReverbTank.h
 RollingAverage.h
 RollingStat.h
 Sample.h
 SampleHuffman.h
 sin1024_int8.py
 sin8192_uint8.py
 sin_multi_levels_int8.py
 Smooth.h
 sounddata.h
 Stack.h
 StateVariable.h
 table_generator_template.py
 teensyPinMap.h
 triangle.py
 triangle512_uint8.h
 twi_nonblock.cpp
 twi_nonblock.h
 umpah_huff.h
 WaveFolder.h
 WavePacket.h
 WavePacketSample.h
 WaveShaper.h
 AudioDelay.h
 AudioDelayFeedback.h
 AudioOutput.h
 AutoMap.h
 AutoRange.h
 blahblah4b_int8.h
 CapPoll.h
 char2mozzi.pyA script for converting raw 8 bit sound data files to wavetables for Mozzi
 chebyshev_int8.py
 CircularBuffer.h
 config_checks_avr.h
 config_checks_esp32.h
 config_checks_esp8266.h
 config_checks_generic.h
 config_checks_mbed.h
 config_checks_renesas.h
 config_checks_rp2040.h
 config_checks_samd21.h
 config_checks_stm32duino.h
 config_checks_stm32maple.h
 config_checks_teensy.h
 config_checks_template.h
 config_example_avr_hifi.h
 config_example_avr_legacy_standard_mode.h
 config_example_avr_legacy_standardplus_mode.h
 config_example_avr_stereo.h
 config_example_external.h
 config_example_rp2040_i2s_pt8211_mono.h
 config_example_rp2040_pwm.h
 ControlDelay.h
 DCfilter.h
 disable_2pinmode_on_github_workflow.h
 disable_stereo_on_github_workflow.h
 Ead.h
 EventDelay.h
 float2mozzi.py
 float2mozzi_uint8.py
 hardware_defines.h
 IntegerType.h
 IntMap.h
 known_16bit_timers.h
 Line.h
 LowPassFilter.h
 meta.h
 MetaOscil.h
 Metronome.h
 Mozzi.hThis is the main include file in Mozzi
 mozzi_analog.h
 mozzi_config_documentation.h
 mozzi_fixmath.cpp
 mozzi_fixmath.h
 mozzi_macros.h
 mozzi_midi.h
 mozzi_pgmspace.h
 mozzi_rand.h
 mozzi_rand_p.h
 mozzi_utils.h
 MozziConfigValues.hThis file keeps a list of named configuration values
 MozziGuts.h
 MozziGuts.hpp
 MozziGuts_impl_AVR.hpp
 MozziGuts_impl_ESP32.hpp
 MozziGuts_impl_ESP8266.hpp
 MozziGuts_impl_MBED.hpp
 MozziGuts_impl_RENESAS.hpp
 MozziGuts_impl_RENESAS_ADC.hpp
 MozziGuts_impl_RENESAS_analog.hpp
 MozziGuts_impl_RP2040.hpp
 MozziGuts_impl_SAMD.hpp
 MozziGuts_impl_STM32.hpp
 MozziGuts_impl_STM32duino.hpp
 MozziGuts_impl_STM32duino_analog.hpp
 MozziGuts_impl_TEENSY.hpp
 MozziGuts_impl_template.hpp
 MozziHeadersOnly.hThis file provides declarations of the Mozzi Core Functions Mozzi functions, but no implementation
 mult16x16.h
 mult16x8.h
 mult32x16.h
 Oscil.h
 OverSample.h
 PDResonant.h
 Phasor.h
 Portamento.h
 primes.h
 RCpoll.h
 ResonantFilter.h
 ReverbTank.h
 RollingAverage.h
 RollingStat.h
 Sample.h
 SampleHuffman.h
 sin1024_int8.py
 sin8192_uint8.py
 sin_multi_levels_int8.py
 Skeleton_Multi_Unit2.cpp
 Smooth.h
 Stack.h
 StateVariable.h
 table_generator_template.py
 teensyPinMap.h
 triangle.py
 twi_nonblock.h
 twi_nonblock.hpp
 twi_nonblock_HeadersOnly.hThis file provides declarations of the Mozzi Core Functions twi_nonblock functions, but no implementation
 umpah_huff.h
 WaveFolder.h
 WavePacket.h
 WavePacketSample.h
 WaveShaper.h
@@ -205,9 +219,7 @@ diff --git a/extras/doc/html/files_dup.js b/extras/doc/html/files_dup.js index 098d9d7a5..896442190 100644 --- a/extras/doc/html/files_dup.js +++ b/extras/doc/html/files_dup.js @@ -2,16 +2,6 @@ var files_dup = [ [ "ADSR.h", "_a_d_s_r_8h_source.html", null ], [ "audio2huff.py", "audio2huff_8py_source.html", null ], - [ "AudioConfigESP.h", "_audio_config_e_s_p_8h_source.html", null ], - [ "AudioConfigESP32.h", "_audio_config_e_s_p32_8h_source.html", null ], - [ "AudioConfigHiSpeed14bitPwm.h", "_audio_config_hi_speed14bit_pwm_8h_source.html", null ], - [ "AudioConfigRP2040.h", "_audio_config_r_p2040_8h_source.html", null ], - [ "AudioConfigSAMD21.h", "_audio_config_s_a_m_d21_8h_source.html", null ], - [ "AudioConfigStandard9bitPwm.h", "_audio_config_standard9bit_pwm_8h_source.html", null ], - [ "AudioConfigStandardPlus.h", "_audio_config_standard_plus_8h_source.html", null ], - [ "AudioConfigSTM32.h", "_audio_config_s_t_m32_8h_source.html", null ], - [ "AudioConfigTeensy3_12bit.h", "_audio_config_teensy3__12bit_8h_source.html", null ], - [ "AudioConfigTeensy4.h", "_audio_config_teensy4_8h_source.html", null ], [ "AudioDelay.h", "_audio_delay_8h_source.html", null ], [ "AudioDelayFeedback.h", "_audio_delay_feedback_8h_source.html", null ], [ "AudioOutput.h", "_audio_output_8h_source.html", null ], @@ -22,8 +12,29 @@ var files_dup = [ "char2mozzi.py", "char2mozzi_8py.html", "char2mozzi_8py" ], [ "chebyshev_int8.py", "chebyshev__int8_8py_source.html", null ], [ "CircularBuffer.h", "_circular_buffer_8h_source.html", null ], + [ "config_checks_avr.h", "config__checks__avr_8h_source.html", null ], + [ "config_checks_esp32.h", "config__checks__esp32_8h_source.html", null ], + [ "config_checks_esp8266.h", "config__checks__esp8266_8h_source.html", null ], + [ "config_checks_generic.h", "config__checks__generic_8h_source.html", null ], + [ "config_checks_mbed.h", "config__checks__mbed_8h_source.html", null ], + [ "config_checks_renesas.h", "config__checks__renesas_8h_source.html", null ], + [ "config_checks_rp2040.h", "config__checks__rp2040_8h_source.html", null ], + [ "config_checks_samd21.h", "config__checks__samd21_8h_source.html", null ], + [ "config_checks_stm32duino.h", "config__checks__stm32duino_8h_source.html", null ], + [ "config_checks_stm32maple.h", "config__checks__stm32maple_8h_source.html", null ], + [ "config_checks_teensy.h", "config__checks__teensy_8h_source.html", null ], + [ "config_checks_template.h", "config__checks__template_8h_source.html", null ], + [ "config_example_avr_hifi.h", "config__example__avr__hifi_8h_source.html", null ], + [ "config_example_avr_legacy_standard_mode.h", "config__example__avr__legacy__standard__mode_8h_source.html", null ], + [ "config_example_avr_legacy_standardplus_mode.h", "config__example__avr__legacy__standardplus__mode_8h_source.html", null ], + [ "config_example_avr_stereo.h", "config__example__avr__stereo_8h_source.html", null ], + [ "config_example_external.h", "config__example__external_8h_source.html", null ], + [ "config_example_rp2040_i2s_pt8211_mono.h", "config__example__rp2040__i2s__pt8211__mono_8h_source.html", null ], + [ "config_example_rp2040_pwm.h", "config__example__rp2040__pwm_8h_source.html", null ], [ "ControlDelay.h", "_control_delay_8h_source.html", null ], [ "DCfilter.h", "_d_cfilter_8h_source.html", null ], + [ "disable_2pinmode_on_github_workflow.h", "disable__2pinmode__on__github__workflow_8h_source.html", null ], + [ "disable_stereo_on_github_workflow.h", "disable__stereo__on__github__workflow_8h_source.html", null ], [ "Ead.h", "_ead_8h_source.html", null ], [ "EventDelay.h", "_event_delay_8h_source.html", null ], [ "float2mozzi.py", "float2mozzi_8py_source.html", null ], @@ -37,28 +48,35 @@ var files_dup = [ "meta.h", "meta_8h_source.html", null ], [ "MetaOscil.h", "_meta_oscil_8h_source.html", null ], [ "Metronome.h", "_metronome_8h_source.html", null ], - [ "mozzi_analog.cpp", "mozzi__analog_8cpp_source.html", null ], + [ "Mozzi.h", "_mozzi_8h.html", null ], [ "mozzi_analog.h", "mozzi__analog_8h_source.html", null ], - [ "mozzi_config.h", "mozzi__config_8h_source.html", null ], + [ "mozzi_config_documentation.h", "mozzi__config__documentation_8h.html", "mozzi__config__documentation_8h" ], [ "mozzi_fixmath.cpp", "mozzi__fixmath_8cpp_source.html", null ], [ "mozzi_fixmath.h", "mozzi__fixmath_8h_source.html", null ], - [ "mozzi_midi.cpp", "mozzi__midi_8cpp_source.html", null ], + [ "mozzi_macros.h", "mozzi__macros_8h_source.html", null ], [ "mozzi_midi.h", "mozzi__midi_8h_source.html", null ], [ "mozzi_pgmspace.h", "mozzi__pgmspace_8h_source.html", null ], - [ "mozzi_rand.cpp", "mozzi__rand_8cpp_source.html", null ], [ "mozzi_rand.h", "mozzi__rand_8h_source.html", null ], - [ "mozzi_utils.cpp", "mozzi__utils_8cpp_source.html", null ], + [ "mozzi_rand_p.h", "mozzi__rand__p_8h_source.html", null ], [ "mozzi_utils.h", "mozzi__utils_8h_source.html", null ], - [ "MozziGuts.cpp", "_mozzi_guts_8cpp_source.html", null ], + [ "MozziConfigValues.h", "_mozzi_config_values_8h.html", "_mozzi_config_values_8h" ], [ "MozziGuts.h", "_mozzi_guts_8h_source.html", null ], + [ "MozziGuts.hpp", "_mozzi_guts_8hpp_source.html", null ], [ "MozziGuts_impl_AVR.hpp", "_mozzi_guts__impl___a_v_r_8hpp_source.html", null ], [ "MozziGuts_impl_ESP32.hpp", "_mozzi_guts__impl___e_s_p32_8hpp_source.html", null ], [ "MozziGuts_impl_ESP8266.hpp", "_mozzi_guts__impl___e_s_p8266_8hpp_source.html", null ], + [ "MozziGuts_impl_MBED.hpp", "_mozzi_guts__impl___m_b_e_d_8hpp_source.html", null ], + [ "MozziGuts_impl_RENESAS.hpp", "_mozzi_guts__impl___r_e_n_e_s_a_s_8hpp_source.html", null ], + [ "MozziGuts_impl_RENESAS_ADC.hpp", "_mozzi_guts__impl___r_e_n_e_s_a_s___a_d_c_8hpp_source.html", null ], + [ "MozziGuts_impl_RENESAS_analog.hpp", "_mozzi_guts__impl___r_e_n_e_s_a_s__analog_8hpp_source.html", null ], [ "MozziGuts_impl_RP2040.hpp", "_mozzi_guts__impl___r_p2040_8hpp_source.html", null ], [ "MozziGuts_impl_SAMD.hpp", "_mozzi_guts__impl___s_a_m_d_8hpp_source.html", null ], [ "MozziGuts_impl_STM32.hpp", "_mozzi_guts__impl___s_t_m32_8hpp_source.html", null ], + [ "MozziGuts_impl_STM32duino.hpp", "_mozzi_guts__impl___s_t_m32duino_8hpp_source.html", null ], + [ "MozziGuts_impl_STM32duino_analog.hpp", "_mozzi_guts__impl___s_t_m32duino__analog_8hpp_source.html", null ], [ "MozziGuts_impl_TEENSY.hpp", "_mozzi_guts__impl___t_e_e_n_s_y_8hpp_source.html", null ], [ "MozziGuts_impl_template.hpp", "_mozzi_guts__impl__template_8hpp_source.html", null ], + [ "MozziHeadersOnly.h", "_mozzi_headers_only_8h.html", "_mozzi_headers_only_8h" ], [ "mult16x16.h", "mult16x16_8h_source.html", null ], [ "mult16x8.h", "mult16x8_8h_source.html", null ], [ "mult32x16.h", "mult32x16_8h_source.html", null ], @@ -78,16 +96,16 @@ var files_dup = [ "sin1024_int8.py", "sin1024__int8_8py_source.html", null ], [ "sin8192_uint8.py", "sin8192__uint8_8py_source.html", null ], [ "sin_multi_levels_int8.py", "sin__multi__levels__int8_8py_source.html", null ], + [ "Skeleton_Multi_Unit2.cpp", "_skeleton___multi___unit2_8cpp_source.html", null ], [ "Smooth.h", "_smooth_8h_source.html", null ], - [ "sounddata.h", "sounddata_8h_source.html", null ], [ "Stack.h", "_stack_8h_source.html", null ], [ "StateVariable.h", "_state_variable_8h_source.html", null ], [ "table_generator_template.py", "table__generator__template_8py_source.html", null ], [ "teensyPinMap.h", "teensy_pin_map_8h_source.html", null ], [ "triangle.py", "triangle_8py_source.html", null ], - [ "triangle512_uint8.h", "triangle512__uint8_8h_source.html", null ], - [ "twi_nonblock.cpp", "twi__nonblock_8cpp_source.html", null ], [ "twi_nonblock.h", "twi__nonblock_8h_source.html", null ], + [ "twi_nonblock.hpp", "twi__nonblock_8hpp_source.html", null ], + [ "twi_nonblock_HeadersOnly.h", "twi__nonblock___headers_only_8h.html", "twi__nonblock___headers_only_8h" ], [ "umpah_huff.h", "umpah__huff_8h_source.html", null ], [ "WaveFolder.h", "_wave_folder_8h_source.html", null ], [ "WavePacket.h", "_wave_packet_8h_source.html", null ], diff --git a/extras/doc/html/float2mozzi_8py_source.html b/extras/doc/html/float2mozzi_8py_source.html index 416103745..9202229f4 100644 --- a/extras/doc/html/float2mozzi_8py_source.html +++ b/extras/doc/html/float2mozzi_8py_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: float2mozzi.py Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,59 @@
float2mozzi.py
-
1 
2 
3 import sys, array, os, textwrap, math
4 
5  if len(sys.argv) != 5:
6  print 'Usage: float2mozzi.py <infile outfile tablename samplerate>'
7  sys.exit(1)
8 
9 [infile, outfile, tablename, samplerate] = sys.argv[1:]
10 
11 def float2mozzi(infile, outfile, tablename,samplerate):
12  fin = open(os.path.expanduser(infile), "rb")
13  print "opened " + infile
14  valuesetad = os.path.getsize(os.path.expanduser(infile))/4
15 
16 
17  valuesfromfile = array.array('f')
18  try:
19  valuesfromfile.fromfile(fin,valuesetad)
20  finally:
21  fin.close()
22 
23  values=valuesfromfile.tolist()
24 
27  fout = open(os.path.expanduser(outfile), "w")
28  fout.write('#ifndef ' + tablename + '_H_' + '\n')
29  fout.write('#define ' + tablename + '_H_' + '\n \n')
30  fout.write('#include <Arduino.h>'+'\n')
31  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
32  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
33  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
34  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
35  try:
36  for num in values:
37  outstring += str(math.trunc((num*256)+0.5)) + ", "
38 
40  finally:
41  outstring += "};"
42  outstring = textwrap.fill(outstring, 80)
43  fout.write(outstring)
44  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
45  fout.close()
46  print "wrote " + outfile
47 
48 float2mozzi(infile, outfile, tablename, samplerate)
+
1 
+
2 
+
3 import sys, array, os, textwrap, math
+
4 
+
5  if len(sys.argv) != 5:
+
6  print 'Usage: float2mozzi.py <infile outfile tablename samplerate>'
+
7  sys.exit(1)
+
8 
+
9 [infile, outfile, tablename, samplerate] = sys.argv[1:]
+
10 
+
11 def float2mozzi(infile, outfile, tablename,samplerate):
+
12  fin = open(os.path.expanduser(infile), "rb")
+
13  print "opened " + infile
+
14  valuesetad = os.path.getsize(os.path.expanduser(infile))/4
+
15 
+
16 
+
17  valuesfromfile = array.array('f')
+
18  try:
+
19  valuesfromfile.fromfile(fin,valuesetad)
+
20  finally:
+
21  fin.close()
+
22 
+
23  values=valuesfromfile.tolist()
+
24 
+
27  fout = open(os.path.expanduser(outfile), "w")
+
28  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
29  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
30  fout.write('#include <Arduino.h>'+'\n')
+
31  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
32  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
+
33  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
+
34  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
+
35  try:
+
36  for num in values:
+
37  outstring += str(math.trunc((num*256)+0.5)) + ", "
+
38 
+
40  finally:
+
41  outstring += "};"
+
42  outstring = textwrap.fill(outstring, 80)
+
43  fout.write(outstring)
+
44  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
+
45  fout.close()
+
46  print "wrote " + outfile
+
47 
+
48 float2mozzi(infile, outfile, tablename, samplerate)
+
diff --git a/extras/doc/html/float2mozzi__uint8_8py_source.html b/extras/doc/html/float2mozzi__uint8_8py_source.html index 0f5c40b28..dc2ba6adc 100644 --- a/extras/doc/html/float2mozzi__uint8_8py_source.html +++ b/extras/doc/html/float2mozzi__uint8_8py_source.html @@ -1,9 +1,9 @@ - + - + Mozzi: float2mozzi_uint8.py Source File @@ -13,10 +13,6 @@ - @@ -43,7 +39,7 @@
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@
@@ -103,16 +99,53 @@
float2mozzi_uint8.py
-
1 
2 
3 import sys, array, os, textwrap, math
4 
5 def float2mozzi_uint8(infile, outfile, tablename,samplerate):
6  fin = open(os.path.expanduser(infile), "rb")
7  print "opened " + infile
8  valuesetad = os.path.getsize(os.path.expanduser(infile))/4
9 
10 
11  valuesfromfile = array.array('f')
12  try:
13  valuesfromfile.fromfile(fin,valuesetad)
14  finally:
15  fin.close()
16 
17  values=valuesfromfile.tolist()
18 
21  fout = open(os.path.expanduser(outfile), "w")
22  fout.write('#ifndef ' + tablename + '_H_' + '\n')
23  fout.write('#define ' + tablename + '_H_' + '\n \n')
24  fout.write('#include <Arduino.h>'+'\n')
25  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
26  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
27  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
28  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
29  try:
30  for num in values:
31  outstring += str(math.trunc((num*256)+0.5)) + ", "
32 
34  finally:
35  outstring += "};"
36  outstring = textwrap.fill(outstring, 80)
37  fout.write(outstring)
38  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
39  fout.close()
40  print "wrote " + outfile
41 
42 float2mozzi_uint8(infile, outfile, tablename, samplerate)
+
1 
+
2 
+
3 import sys, array, os, textwrap, math
+
4 
+
5 def float2mozzi_uint8(infile, outfile, tablename,samplerate):
+
6  fin = open(os.path.expanduser(infile), "rb")
+
7  print "opened " + infile
+
8  valuesetad = os.path.getsize(os.path.expanduser(infile))/4
+
9 
+
10 
+
11  valuesfromfile = array.array('f')
+
12  try:
+
13  valuesfromfile.fromfile(fin,valuesetad)
+
14  finally:
+
15  fin.close()
+
16 
+
17  values=valuesfromfile.tolist()
+
18 
+
21  fout = open(os.path.expanduser(outfile), "w")
+
22  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
23  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
24  fout.write('#include <Arduino.h>'+'\n')
+
25  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
26  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
+
27  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
+
28  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
+
29  try:
+
30  for num in values:
+
31  outstring += str(math.trunc((num*256)+0.5)) + ", "
+
32 
+
34  finally:
+
35  outstring += "};"
+
36  outstring = textwrap.fill(outstring, 80)
+
37  fout.write(outstring)
+
38  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
+
39  fout.close()
+
40  print "wrote " + outfile
+
41 
+
42 float2mozzi_uint8(infile, outfile, tablename, samplerate)
+
diff --git a/extras/doc/html/functions.html b/extras/doc/html/functions.html index 45ad4d041..a73ae1180 100644 --- a/extras/doc/html/functions.html +++ b/extras/doc/html/functions.html @@ -1,9 +1,9 @@ - + - + Mozzi: Class Members @@ -13,10 +13,6 @@ - @@ -37,13 +33,13 @@ Logo
Mozzi -  version v1.1.0 +  version v2.0
sound synthesis library for Arduino
- @@ -52,7 +48,7 @@ onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> - +
@@ -61,10 +57,10 @@ - + @@ -80,7 +76,7 @@ @@ -128,9 +124,7 @@

- a -