diff --git a/.github/workflows/compile_examples.yml b/.github/workflows/compile_examples.yml index 85f803cc2..918f82a64 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: | @@ -88,10 +92,23 @@ 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 + - 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 - 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 - name: Compile examples uses: arduino/compile-sketches@v1 @@ -109,8 +126,10 @@ 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 - name: Save sketches report as workflow artifact uses: actions/upload-artifact@v4 diff --git a/ADSR.h b/ADSR.h index 17607d47c..5f2388cf0 100644 --- a/ADSR.h +++ b/ADSR.h @@ -1,22 +1,18 @@ /* * 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. * */ #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" @@ -27,13 +23,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 -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. +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. @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 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 +274,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 +287,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 +300,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 +315,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 +335,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/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/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/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/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/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/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/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/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/AudioConfigSTM32duino.h b/AudioConfigSTM32duino.h deleted file mode 100644 index 4494f76b2..000000000 --- a/AudioConfigSTM32duino.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef AUDIOCONFIGSTM32_H -#define AUDIOCONFIGSTM32_H - -#if not IS_STM32DUINO() -#error This header should be included for STM32 (stm32duino.com core), 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 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 -#endif -#endif - -#define AUDIO_BIAS ((uint16_t) 1<<(AUDIO_BITS-1)) - -#endif // #ifndef AUDIOCONFIGSTM32_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/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/AudioDelay.h b/AudioDelay.h index 5eaa50760..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. * */ @@ -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..ad1ea53d2 100644 --- a/AudioDelayFeedback.h +++ b/AudioDelayFeedback.h @@ -1,22 +1,18 @@ /* * 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. * */ #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" @@ -49,8 +45,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 +54,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 +196,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 +208,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 +220,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/AudioOutput.h b/AudioOutput.h index 8ad297844..46581d098 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -1,6 +1,20 @@ -/** @file AudioOutput +/* + * AudioOutput.h * - * Platform independent audio output and adding support for new platforms or output methods. + * 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 */ + +/** @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: * @@ -10,110 +24,75 @@ * * 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. * - * 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_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(). * + * @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 -#define AUDIOOUTPUT - -#include "MozziGuts.h" +#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 * than 16 bits). */ #define AudioOutputStorage_t int -#if IS_AVR() && ((AUDIO_MODE == STANDARD_PLUS) || (AUDIO_MODE == STANDARD)) -#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 +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))); } -#if (AUDIO_CHANNELS == STEREO) -#define AudioOutput StereoOutput -#if (STEREO_HACK == true) -#define AudioOutput_t void -#else -#define AudioOutput_t StereoOutput -#endif +struct MonoOutput; +struct StereoOutput; + +#if MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO) +typedef StereoOutput AudioOutput; #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. - */ -#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. +/** 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 EXTERNAL_AUDIO_OUTPUT. + * You will not usually use or encounter this definition, unless using @ref external_audio output mode. */ -#define AudioOutput MonoOutput +typedef MonoOutput AudioOutput; #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 . */ -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 (AUDIO_CHANNELS != 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_config.h."))) { return _l; }; +#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 +/** 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 - AudioOutputStorage_t l() const { return _l; }; - AudioOutputStorage_t r() const { return _r; }; - /** @see MonoOutput::clip(). Clips both channels. */ - StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; }; - - /** @see 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 */ - static inline StereoOutput from8Bit(int16_t l, int16_t r) { return fromNBit(8, l, r); } - /** @see MonoOutput::from16Bit(), stereo variant */ - static inline StereoOutput from16Bit(int16_t l, int16_t r) { return fromNBit(16, l, r); } - /** @see 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: @@ -126,21 +105,23 @@ 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 { + /** Default constructor. Does not initialize the sample! */ + MonoOutput() {}; /** Construct an audio frame from raw values (zero-centered) */ - MonoOutput(AudioOutputStorage_t l=0) : _l(l) {}; -#if (AUDIO_CHANNELS > 1) + 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 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); }; -#else - /** Conversion to int operator. */ - inline operator AudioOutput_t() const { return _l; }; + StereoOutput portable() const __attribute__((deprecated("Sketch generates mono output, but Mozzi is configured for stereo. Check MOZZI_AUDIO_CHANNELS setting."))); // Note: defintion below #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 @@ -151,18 +132,23 @@ 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. */ + /** 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+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. * - * 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)); } @@ -170,16 +156,60 @@ 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 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 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() 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::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+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: + AudioOutputStorage_t _l; + AudioOutputStorage_t _r; +}; + +#if MOZZI_AUDIO_CHANNELS > 1 +StereoOutput MonoOutput::portable() const { return StereoOutput(_l, _l); }; +#endif -/** When setting EXTERNAL_AUDIO_OUTPUT to true, implement this function to take care of writing samples to the hardware. */ +#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); -#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. */ +#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(); #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. */ @@ -195,7 +225,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; @@ -212,8 +244,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/AutoMap.h b/AutoMap.h index ff9aef13f..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. * */ @@ -13,14 +15,13 @@ #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" +/** @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/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 a773e922b..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. * */ @@ -33,7 +34,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/EventDelay.h b/EventDelay.h index 168b31677..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. * */ @@ -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/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 053c62443..49be01847 100644 --- a/IntegerType.h +++ b/IntegerType.h @@ -1,6 +1,22 @@ +/* + * 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_ +#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/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/Line.h b/Line.h index f433907d3..fabdfbb27 100644 --- a/Line.h +++ b/Line.h @@ -1,22 +1,21 @@ /* * 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_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include + +#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, @@ -33,12 +32,15 @@ represent fractional numbers. Google "fixed point arithmetic" if this is new to you. */ + + + 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 @@ -112,7 +114,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: @@ -181,7 +183,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: @@ -253,7 +255,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: @@ -315,6 +317,174 @@ class Line } }; + +/* UFix specialisation */ +template +class Line> +{ +private: + typedef UFix internal_type; + internal_type current_value; + SFix 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()) { + auto 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) { + auto 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; + SFix 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()) { + auto 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) { + auto 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. 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 702441e32..f855039a2 100644 --- a/MetaOscil.h +++ b/MetaOscil.h @@ -4,17 +4,19 @@ * 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 -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif +#include #include "Oscil.h" #include "mozzi_fixmath.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 new file mode 100644 index 000000000..6b19ff5c2 --- /dev/null +++ b/Mozzi.h @@ -0,0 +1,35 @@ +/* + * Mozzi.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. + * + */ + + +/** @page basic_info Getting Started + * + * You are currently looking at the Mozzi API documentation. It is the most comprehensive source of all functions and + * classes available in Mozzi, but not necesarrily the best starting point for learning about Mozzi. For getting + * started, it is recommended to browse through the tutorials at https://sensorium.github.io/Mozzi/learn/ . + */ + +/** @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/MozziConfigValues.h b/MozziConfigValues.h new file mode 100644 index 000000000..47116847c --- /dev/null +++ b/MozziConfigValues.h @@ -0,0 +1,54 @@ +/* + * 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 +#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_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_NONE 201 +#define MOZZI_AUDIO_INPUT_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 +#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/MozziGuts.h b/MozziGuts.h index f3dad8a46..75528fb7f 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -1,23 +1,24 @@ /* * 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. * */ #ifndef MOZZIGUTS_H_ #define MOZZIGUTS_H_ -//#define F_CPU 8000000 // testing +#include "Arduino.h" -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.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" @@ -27,220 +28,12 @@ #include #endif -#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 - -#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() -#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_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 -#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 +#include "internal/config_checks_generic.h" +#include "mozzi_analog.h" #include "AudioOutput.h" +// TODO Mozzi 2.0: These typedef probably obsolete? // common numeric types typedef unsigned char uchar; typedef unsigned int uint; @@ -258,25 +51,20 @@ 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 +The bones of every Mozzi sketch. + +@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. -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, +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. @@ -286,7 +74,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); @@ -301,34 +89,30 @@ 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. */ -void stopMozzi(); - - -/** @ingroup core -Obsolete function, use stopMozzi() instead. -*/ -void pauseMozzi(); +on which one(s) are required for other tasks. -//TB2017-19 -/** @ingroup core -Obsolete function, use startMozzi() instead. -Restores Mozzi audio and control interrupts, if they have been temporarily -disabled with pauseMozzi(). +@note This function is not actually implemented on all platforms. */ -void unPauseMozzi(); +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 -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. + +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 @@ -342,7 +126,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 @@ -354,14 +138,21 @@ are called. */ void audioHook(); +/** @ingroup analog + +See getAudioInput(). The template parameter specifies the desired value range in bits. */ +template uint16_t getAudioInput(); + +/** @ingroup analog +See getAudioInput(). Equivalent to getAudioInput<16>(). */ +template inline uint16_t getAudioInput16() { return getAudioInput<16>(); } /** @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 @@ -369,19 +160,28 @@ 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 (USE_AUDIO_INPUT == true) -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) +inline uint16_t getAudioInput() { return getAudioInput(); }; +#else +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 /** @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. */ @@ -392,13 +192,17 @@ 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()? */ unsigned long mozziMicros(); +#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..afb122d23 --- /dev/null +++ b/MozziHeadersOnly.h @@ -0,0 +1,27 @@ +/* + * MozziHeadersOnly.h + * + * This file is part of Mozzi. + * + * 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. + * + */ + +/** @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/Oscil.h b/Oscil.h index 5bfe47c8b..b5253a9b1 100644 --- a/Oscil.h +++ b/Oscil.h @@ -3,24 +3,23 @@ * * 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_ -#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 "FixMath.h" #include "mozzi_pgmspace.h" #ifdef OSCIL_DITHER_PHASE @@ -42,9 +41,9 @@ 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 -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 +@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. @todo Use conditional compilation to optimise setFreq() variations for different table sizes. @@ -154,6 +153,34 @@ 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 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(SFix<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 @@ -183,6 +210,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 @@ -207,6 +249,20 @@ class Oscil } } + /** 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. + @param frequency in UFix<24,8> fixed-point number format. + */ + template + inline + void setFreq(UFix<24,8,RANGE> 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 +286,38 @@ class Oscil phase_increment_fractional = ((uint32_t)frequency) / (UPDATE_RATE/NUM_TABLE_CELLS); } } + + + /** 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 UFix<16,16> fixed-point number format. + */ + template + inline + void setFreq(UFix<16,16,RANGE> frequency) + { + setFreq_Q16n16(frequency.asRaw()); + } + + + + /** 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 SFix<16,16> fixed-point number format. + */ + template + inline + void setFreq(SFix frequency) + { + setFreq_Q16n16(UFix<16,16>(frequency).asRaw()); + } + /* inline void setFreqMidi(int8_t note_num) { 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 a28e5b9b3..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 @@ -128,11 +126,11 @@ class PDResonant byte amp; int freq; - Phasor aBaseCounter; - Phasor aResonanceFreqCounter; + Phasor aBaseCounter; + Phasor aResonanceFreqCounter; - Oscil aOsc; - ADSR aAmpEnv; - ADSR kResonantFreqEnv; + Oscil aOsc; + ADSR aAmpEnv; + ADSR kResonantFreqEnv; }; diff --git a/Phasor.h b/Phasor.h index fd4ad31b1..dcf4b0f61 100644 --- a/Phasor.h +++ b/Phasor.h @@ -1,22 +1,18 @@ /* * 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. * */ #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 @@ -36,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/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 5bcdc23d9..9ffaf331b 100644 --- a/README.md +++ b/README.md @@ -18,78 +18,106 @@ passing or external synths. *** -## Features -- 16384 Hz sample rate, or experimental 32768 Hz rate. -- 8 bit or 14 bit audio output modes on a bare Arduino, up to 16 bit using an external DAC. +## Features +- Available for a wide and growing range of MCUs, with and without inbuilt DACs: Arduino Uno R3 and R4, STM32, Teensy, ESP8266, ESP32, Raspberry Pi Pico, and more. +- Configurable sample rate, usually in powers of two (16384 Hz, or 32768 Hz). - Variable control rate from 64 Hz upwards. +- Various inbuilt output modes, including 16 bit output to an external DAC. +- Allows interfacing to custom output routines, with examples for playing audio on external DAC modules, and even bluetooth. - Useful basic audio toolkit: oscillators, samples, lines, envelopes, scheduling, filtering. - Fast ADC and other cpu-efficient code utilities to help keep audio running smoothly. - Example sketches for easy modification. - Readymade wavetables and a script to convert your own soundfiles for Mozzi. -- Usable on several platforms: Arduino, STM32, ESP, Teensy. - Mozzi is designed to be easy to use, open source and extendable. *** -## Installation -Use the "code" button on Mozzi's Github page to download a ZIP file of the latest developing code. Import this into Arduino, following the instructions from the [Arduino libraries guide](http://arduino.cc/en/Guide/Libraries). - -*In the Arduino IDE, navigate to Sketch > Include Library > Add .ZIP Library. At the top of the drop down list, select the option to "Add .ZIP Library".* - -(Note: the files in the "releases" section on Github are now legacy. The development code is recommended.) - -*** - -## Quick Start -To hear Mozzi, connect a 3.5mm audio jack with the centre wire to the PWM output -on Digital Pin 9 on the Arduino, and the ground to the Ground on the Arduino. -Use this as a line out which you can plug into your computer and listen to with -a sound program like [Audacity](http://audacity.sourceforge.net/). -Try some examples from the __File > Examples > Mozzi__ menu. - -Below is a list of the Digital Pins used by Mozzi for STANDARD_PLUS mode PWM audio out on different boards. -Feedback about others is welcome. - -Model | Pin | Tested ------ | --- | ------ -Arduino Uno | 9 | yes -Arduino Uno R4 | A0 | yes -Arduino Duemilanove | 9 | yes -Arduino Nano | 9 | yes -Arduino Nano 33 Iot | A0 | yes -Arduino Pro Mini | 9 | yes -Arduino Leonardo | 9 | yes -Arduino Mega | 11 | yes -Arduino MBED (only the Giga has been tested, see "Hardware specific notes", below) | A13 | no -Arduino Giga | A13 (jack) | 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 | - -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 -ESP8266 *see details* | GPIO2 | yes -RP2040 | 0 | yes - -For details about HIFI mode, read the [Mozzi core module documentation](http://sensorium.github.io/Mozzi/doc/html/group__core.html#gae99eb43cb29bb03d862ae829999916c4/). +## Installation +The easiest installation option nowadays is to install Mozzi via the Library Manager in your Arduino application: +_Arduino➞Sketch➞Include Library➞Library Manager_ type "Mozzi" into the search field, then click "install". + +For other installation methods (e.g. the development version), see the [Download page](https://sensorium.github.io/Mozzi/download). + +## Quick Start +To hear Mozzi, wire a 3.5mm audio jack with the centre to the audio out pin for your Arduino as shown in the table below, and the shield to GND on the Arduino. +Plug into your computer and listen with a sound program like [Audacity](https://audacity.sourceforge.net/). (Or connect any other high-impedance input, like an active speaker) +Try some examples from the __File > Examples > Mozzi__ menu. + +For more about audio output, including high quality output modes [Mozzi Output tutorial](https://sensorium.github.io/Mozzi/learn/output/). + +### A note for users coming from Mozzi 1.x +Mozzi 2.0 brings a lot of changes under the hood, and is not 100% source compatible with earlier versions of Mozzi. Most sketches should continue to compile, but with +a lot of warnings. A few others will no longer work. See [Porting to Mozzi 2.0](https://sensorium.github.io/Mozzi/learn/porting/) for what to change. +If desparate, there is still a "Mozzi_1" branch in the git repository, but this will not get any new development. + +## Supported boards, output modes and default pins +Table is not necessarily complete. *Abbreviations explained below the table.* The default output mode is framed with a border in each row. +If stereo is supported, in a mode, the cell has a red/blue background, and (where applicable) the second pin number is given in parentheses (+X). +Check the [hardware section of the API-documentation](https://sensorium.github.io/Mozzi/doc/html/hardware.html) for platform specific notes and (pin) configuration options. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Board or family / Output mode PWM-1 PWM-2 PDM inbuilt DAC I2S DAC (native)
ATmega328/168: Uno (R3), Nano, Pro Mini, Duemilanove, Leonardo, etc. 9 (+10) 9, 10 - - -
ATmega32U4: Teensy, Teensy2, 2++ B5/B6 correspond to pins 14/15 in ArduinoB5 (+B6)B5, B6 - - -
ATmega2560: Arduino Mega, Freetronics EtherMega, etc. 11 (+12)11, 12 - - -
ATmega1284: Sanguino 13 (+12)13, 12 - - -
Teensy3.x - note: DAC Pin number depends on model: A14, A12, or A21 - - - DAC -
Teensy4.x A8 (+A9) - - - -
LGT8F328P: "Register clone" of the ATmega328, uses the same code in Mozzi 9 (+10) 9, 10 - - -
SAMD: Arduino Nano 33 Iot, Adafruit Playground Express, Gemma M0 etc. - - - A0/speaker -
Renesas Arduino Core: Arduino Uno R4 - - - A0 -
Arduino MBED Core: Arduino Giga (only model tested so far in this family) - - SERIAL2TXA13 (+A12) -
STM32 maple core: Various STM32F1 and STM32F4 boards, "Blue/Black Pill" PB8 (+PB9)PB8, PB9 - - -
STM32duino (STM official) core: Huge range of STM32Fx boards PA8 (+PA8)PA8, PA9 - - -
ESP8266: ESP-01, Wemos D1 mini, etc. note: Beware of erratic pin labels - - GPIO2 - yes
ESP32: note: Beware of vastly different pin labels across board variants - - yes GPIO25 (+GPIO26)yes
RP2040: Raspberry Pi Pico and friends 0 (+1) 0, 1 - - yes
+ + + - PWM-1: 1-pin PWM mode (`MOZZI_OUTPUT_PWM`) + - PWM-2: 2-pin PWM mode (`MOZZI_OUTPUT_2PIN_PWM`) + - PDM: Pulse density modulation, may be either `MOZZI_OUTPUT_PDM_VIA_SERIAL` or `MOZZI_OUTPUT_PDM_VIA_I2S` + - inbuilt DAC: `MOZZI_OUTPUT_INTERNAL_DAC` + - I2S DAC (native): native support for externally connected I2S DACs (`MOZZI_OUTPUT_I2S_DAC`). Since this requires several, often + configurable pins, and is never the default option, no pin numbers are shown in this table. + - **All** platforms also support "external" output modes (`MOZZI_OUTPUT_EXTERNAL_TIMED` or `MOZZI_OUTPUT_EXTERNAL_CUSTOM`), which allow + for connecting DACs or other external circuitry. + *** -## Using Mozzi -Here's a template for an empty Mozzi sketch: - +## Using Mozzi +Here's a template for an empty Mozzi sketch: -``` -#include // at the top of your sketch +{% highlight c++ %} +#include // at the top of your sketch void setup() { startMozzi(); @@ -99,65 +127,51 @@ void updateControl(){ // your control code } -int updateAudio(){ - // your audio code which returns an int between -244 and 243 +AudioOutput_t updateAudio(){ + MonoOutput::from16Bit( [my_cool_sample] ); } void loop() { audioHook(); } -``` +{% endhighlight %} -There's a detailed example explaining the different parts [here](http://sensorium.github.io/Mozzi/learn/a-simple-sketch/). +There's a detailed example explaining the different parts [here](https://sensorium.github.io/Mozzi/learn/a-simple-sketch/). -*** ## Documentation -There's documentation in the doc folder in the Mozzi download and [online](http://sensorium.github.io/Mozzi/doc/html/index.html). -There is practical help on the [learn](http://sensorium.github.io/Mozzi/learn/) page on the Mozzi site. +For getting started, browse the practical help on the [learn](https://sensorium.github.io/Mozzi/learn/) page on the Mozzi site. +API reference documentation is available in the doc folder in the Mozzi download and [online](http://sensorium.github.io/Mozzi/doc/html/index.html). Start or look up a topic on the [users forum](https://groups.google.com/forum/#!forum/mozzi-users/). Also, feel free to submit any issues on the [GitHub Mozzi site](https://github.com/sensorium/Mozzi/issues/). Look for code and usage changes [here](extras/NEWS.txt). +For hardware specific details, including supported features, caveats, and hardware-dependent configuration options, +refer to the [Hardware Section of the API-Documentation](https://sensorium.github.io/Mozzi/doc/html/hardware.html). -*** - -## Caveats and Workarounds - -#### AVR - -* 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`. +## Compatibiliy issues -* `analogRead()` is replaced by `mozziAnalogRead()`, which works in the background instead of blocking the processor. +* In most setups, Mozzi claims one or two hardware timers. This may result in incompatibilities with certain libraries, and / or the ability to use timer-based functions such as `analogWrite()`. As the details on this + differ a lot between the supported boards, read up on the details - and available workarounds - in the [ardware Section of the API-Documentation](https://sensorium.github.io/Mozzi/doc/html/hardware.html). -* 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*. +* There is also an example on emulating `analogWrite()` on any digitial pin in *Mozzi>examples>11.Communication>Sinewave_PWM_pins_HIFI*. +* The timers can be made available with `stopMozzi()`, which stops audio interrupts, until you call `startMozzi()`. -#### Last Resort -The timers can be made available with `stopMozzi()`, which stops audio interrupts, until you call `startMozzi()`. +* Note that it is of utmost importance to write non-blocking code, such that the + audio buffer never runs low. Hints on how to do this, including why, and how you + should avoid using `delay()`, `analogRead()`, and how to make your code run faster, + can be found at [on the learn pages](https://sensorium.github.io/Mozzi/learn/hints/). -*** - -## Tweaking Arduino for Faster Audio Code - -If you need your synth to run faster on AVR architectures, Arduino versions above 1.5 can be tweaked to optimise compiled code for speed instead of small size. -Find Arduino’s platform.txt (on OSX you can find it by searching in Users/your_name/Library/Arduino15). Search and replace -Os with -O2. Save. +## Extending Mozzi -It’s explained more thoroughly (for Windows) [here](http://www.instructables.com/id/Arduino-IDE-16x-compiler-optimisations-faster-code/?ALLSTEPS). - -If you still need more speed, Arduino 1.0.5 produces slightly faster code. - -*** - -## Using external chips to produce the sound +### Using external chips to produce the sound External chips (DAC) can also be used on any platform which does not support natively the I2S protocol using an user defined `audioOutput` function. This can allow a greater audio quality over the native ways to output the sound (PWM for AVR Arduinos and STM32 and 12 bit DAC for Teensy 3.*). Examples are provided for the MCP492X DAC (12 bit on SPI) and for the (PT8211) 16 bit stereo DAC using SPI port to emulate the I2S protocol. The latter should be compatible with any DAC using I2S. -*** +### Extendig the library itself If you enjoy using Mozzi for a project, or have extended it, we would be pleased to hear about it and provide support wherever possible. Contribute @@ -186,202 +200,19 @@ and fixed point version of the filter on [dave's blog of art and programming](ht State Variable filter pseudocode at [musicdsp.org](http://www.musicdsp.org/showone.php?id=23) and [here](http://www.musicdsp.org/showone.php?id=142) 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 - -### 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 - -### 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` - -### 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 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.* *** ## 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 may distribute *your own* source code which merely *uses* the Mozzi-API under any licence that you wish. -You are free to: - - Share — copy and redistribute the material in any medium or format - - Adapt — remix, transform, and build upon the material +- 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." -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. +- Note that using third-party libraries/code - including as shown in some of the Mozzi examples - may introduce additional restrictions. diff --git a/Readme_Mozzi_2_0.md b/Readme_Mozzi_2_0.md new file mode 100644 index 000000000..d2667b202 --- /dev/null +++ b/Readme_Mozzi_2_0.md @@ -0,0 +1,44 @@ +Porting to Mozzi 2.0 + +// 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) + +audio modes mapping + + - 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 + +further + - USE_AUDIO_INPUT: MOZZI_AUDIO_INPUT + - IS_STM32() -> IS_STM32MAPLE() + +simple renames: + - AUDIO_RATE: MOZZI_AUDIO_RATE + - CONTROL_RATE: MOZZI_CONTROL_RATE + +all new + - MOZZI_ANALOG_READS -> allows to disable, explicitly + - 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 + - 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 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 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" + - New sketches should include "Mozzi.h", rather than "MozziGuts.h", thereby documenting, they have been written for Mozzi 2.0+ diff --git a/ResonantFilter.h b/ResonantFilter.h index 072c3e7a0..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. * */ @@ -86,7 +85,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 +107,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/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 74a2f2eab..30a2d60ef 100644 --- a/Sample.h +++ b/Sample.h @@ -1,18 +1,18 @@ /* * 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. * */ #ifndef SAMPLE_H_ #define SAMPLE_H_ -#include "MozziGuts.h" +#include "MozziHeadersOnly.h" #include "mozzi_fixmath.h" #include "mozzi_pgmspace.h" @@ -34,9 +34,9 @@ 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 -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 +@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. @section int8_t2mozzi Converting soundfiles for Mozzi. 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 c5bc62280..34d22a459 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. * */ @@ -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. @@ -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. 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 3ee78f396..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. * */ @@ -85,7 +84,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/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 4fed43da5..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. * */ @@ -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}; @@ -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); } @@ -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..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 @@ -32,7 +33,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/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/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..22acf93a4 --- /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 16384 +//#define MOZZI_PWM_RATE 32768 + + +// 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..2017f61bf --- /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 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_mono.h b/config/config_example_rp2040_i2s_pt8211_mono.h new file mode 100644 index 000000000..ed1611ae7 --- /dev/null +++ b/config/config_example_rp2040_i2s_pt8211_mono.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 in mono 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/config/mozzi_config_documentation.h b/config/mozzi_config_documentation.h new file mode 100644 index 000000000..fc5b1c9f0 --- /dev/null +++ b/config/mozzi_config_documentation.h @@ -0,0 +1,298 @@ +#ifdef FOR_DOXYGEN_ONLY +/** @file */ + +/*! @defgroup config Mozzi Configuration options */ + +/** @ingroup config + * @page config_main 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 + * 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. 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 +*/ + +/** @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. + * 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_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 + * + * @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). + * + * 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. + * 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 @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. + * - 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 FOR_DOXYGEN_ONLY + +/** @ingroup config + * @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 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 + * 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 + * @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 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? + */ +#define MOZZI_AUDIO_RATE FOR_DOXYGEN_ONLY + + +/** @ingroup config + * @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 MOZZI_CONTROL_RATE is detected, apply that with a warning. +*/ +#define MOZZI_CONTROL_RATE FOR_DOXYGEN_ONLY + + +/** @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 + * 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(). It is thus quite recommended _not_ to depend on mozziAnalogRead() when disabling this. + * + * 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. + * + * 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 FOR_DOXYGEN_ONLY + + +/** @ingroup config + * @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_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). + * 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: @ref getAudioInput() @ref MOZZI_AUDIO_INPUT_PIN +*/ +#define MOZZI_AUDIO_INPUT FOR_DOXYGEN_ONLY + + +/** @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 FOR_DOXYGEN_ONLY + + +/** @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 + * 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. + * + * 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 + * + * 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. +*/ +#define MOZZI_AUDIO_BITS_PER_CHANNEL FOR_DOXYGEN_ONLY + + +/** @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. + * 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_1_LOW [...] + * #define MOZZI_AUDIO_PIN_1_LOW_REGISTER [the matching OCR] + * @endcode + * + * @see config/known_16bit_timers.h + * */ +#define MOZZI_AUDIO_PIN_1 FOR_DOXYGEN_ONLY + + +/***************************************** ADVANCED SETTTINGS -- External audio output ****************************************** + * + * The settings in the following section applies to MOZZI_OUTPUT_EXTERNAL_TIMED, and MOZZI_OUTPUT_EXTERNAL_CUSTOM, only. + * +********************************************************************************************************************************/ + +/** @ingroup audio_output + * + * @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 . + * + * 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_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. + * + * 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 +*/ + + +/** @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 . + * 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 maximum of 16 bits on + * some 8 bit boards! + */ +#define MOZZI_AUDIO_BITS FOR_DOXYGEN_ONLY + +#endif diff --git a/examples/01.Basics/Control_Gain/Control_Gain.ino b/examples/01.Basics/Control_Gain/Control_Gain.ino index 2316d2600..fadc6aa02 100644 --- a/examples/01.Basics/Control_Gain/Control_Gain.ino +++ b/examples/01.Basics/Control_Gain/Control_Gain.ino @@ -8,21 +8,23 @@ 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 +#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); +Oscil aSin(SIN2048_DATA); // control variable, use the smallest data size you can for anything used in audio byte gain = 255; @@ -40,7 +42,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 27b2d4a80..a0dedeb42 100644 --- a/examples/01.Basics/Sinewave/Sinewave.ino +++ b/examples/01.Basics/Sinewave/Sinewave.ino @@ -8,27 +8,26 @@ 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. */ -#include +#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 } @@ -38,7 +37,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 2dd1b8301..9573334c0 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 @@ -33,23 +27,28 @@ 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 +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM + +#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); +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 } @@ -57,7 +56,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 1bbc7fc23..6a13ee446 100644 --- a/examples/01.Basics/Skeleton/Skeleton.ino +++ b/examples/01.Basics/Skeleton/Skeleton.ino @@ -1,15 +1,16 @@ -#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() { // 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/Skeleton_Multi/Skeleton_Multi.ino b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino new file mode 100644 index 000000000..9d7264b1b --- /dev/null +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi.ino @@ -0,0 +1,30 @@ +/* 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 + +void setup() { + startMozzi(); +} + +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..4687b88b7 --- /dev/null +++ b/examples/01.Basics/Skeleton_Multi/Skeleton_Multi_Unit2.cpp @@ -0,0 +1,7 @@ +#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/examples/01.Basics/Table_Resolution/Table_Resolution.ino b/examples/01.Basics/Table_Resolution/Table_Resolution.ino index 7a5852b61..8bca80d38 100644 --- a/examples/01.Basics/Table_Resolution/Table_Resolution.ino +++ b/examples/01.Basics/Table_Resolution/Table_Resolution.ino @@ -1,20 +1,26 @@ /* 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. */ -#include +#define MOZZI_CONTROL_RATE 64 +#include #include #include #include @@ -25,15 +31,13 @@ #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 -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; @@ -43,11 +47,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); } @@ -86,7 +90,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 62a838be9..e3402c0fd 100644 --- a/examples/01.Basics/Vibrato/Vibrato.ino +++ b/examples/01.Basics/Vibrato/Vibrato.ino @@ -7,30 +7,35 @@ 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 +#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 +//#include +#include // Fixed point arithmetics -Oscil aCos(COS2048_DATA); -Oscil aVibrato(COS2048_DATA); +Oscil aCos(COS2048_DATA); +Oscil aVibrato(COS2048_DATA); -const byte intensity = 255; +//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(CONTROL_RATE); + startMozzi(); aCos.setFreq(mtof(84.f)); aVibrato.setFreq(15.f); } @@ -39,10 +44,10 @@ void setup(){ void updateControl(){ } - -AudioOutput_t updateAudio(){ - Q15n16 vibrato = (Q15n16) intensity * aVibrato.next(); - return MonoOutput::from8Bit(aCos.phMod(vibrato)); // phase modulation to modulate frequency +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(){ 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..ae711d161 --- /dev/null +++ b/examples/01.Basics/Vibrato_Midi_Note/Vibrato_Midi_Note.ino @@ -0,0 +1,66 @@ +/* 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 + + 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 +#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); + +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 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 UFix 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(UFix<16, 16>(10)); // frequency of the modulation +} + + +void updateControl() { + 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. + 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(); +} 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..2163e7a0b 100644 --- a/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino +++ b/examples/02.Control/Control_Echo_Theremin/Control_Echo_Theremin.ino @@ -1,38 +1,40 @@ /* 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. */ -#include +#define MOZZI_CONTROL_RATE 64 +#include #include // oscillator template #include // sine table for oscillator #include #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 +43,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 @@ -57,7 +59,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)); @@ -66,7 +68,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 aef17e329..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,41 +12,42 @@ 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 +#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 +76,7 @@ void setup(){ v1=v2=v3=v4=v5=v6=v7=v8=127; - startMozzi(CONTROL_RATE); + startMozzi(); } void loop(){ @@ -94,7 +95,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 73d47211c..a93267a53 100644 --- a/examples/02.Control/Control_Tremelo/Control_Tremelo.ino +++ b/examples/02.Control/Control_Tremelo/Control_Tremelo.ino @@ -12,28 +12,29 @@ 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 +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable +#include #include #include #include #include #include -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable - // audio oscillator -Oscil aSig(TRIANGLE_VALVE_2048_DATA); +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,18 +42,18 @@ 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, MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE); // divide of literals should get optimised away } -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 05a8a6a07..9db063bba 100644 --- a/examples/02.Control/EventDelay/EventDelay.ino +++ b/examples/02.Control/EventDelay/EventDelay.ino @@ -11,24 +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: - 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 +#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); +Oscil aSin(SIN8192_DATA); // for scheduling audio gain changes EventDelay kGainChangeDelay; @@ -36,9 +37,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 } @@ -50,7 +51,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 33b4551c4..3295a4748 100644 --- a/examples/02.Control/Line_Gliss/Line_Gliss.ino +++ b/examples/02.Control/Line_Gliss/Line_Gliss.ino @@ -16,25 +16,26 @@ 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 +#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); +Oscil aSaw(SAW8192_DATA); // use: Line lineName Line aGliss; @@ -42,8 +43,8 @@ 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 control_steps_per_gliss = CONTROL_RATE / 4; +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 int counter = 0; @@ -53,7 +54,7 @@ byte gliss_offset_max = 36; void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -86,7 +87,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 8ba18f9c7..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 @@ -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 @@ -48,16 +41,22 @@ 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 + Copyright 2012-2024 Tim Barrass and the Mozzi Team - Tim Barrass 2012, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#define MOZZI_AUDIO_RATE 32768 + +#include #include // for smooth transitions #include // oscillator template #include // saw table for oscillator @@ -66,8 +65,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; @@ -76,8 +75,8 @@ 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 control_steps_per_gliss = CONTROL_RATE / 4; +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 int counter = 0; @@ -137,7 +136,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 a63cad2e5..a49bbafb3 100644 --- a/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino +++ b/examples/02.Control/Metronome_SampleHuffman/Metronome_SampleHuffman.ino @@ -1,22 +1,24 @@ -/* 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 +#include #include #include #include @@ -74,7 +76,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 1c1937ce6..651656111 100644 --- a/examples/02.Control/Stop_Start/Stop_Start.ino +++ b/examples/02.Control/Stop_Start/Stop_Start.ino @@ -12,20 +12,22 @@ 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 +#include #include #include // sine table for oscillator -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); #define STOP_PIN 4 @@ -48,7 +50,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..3d425c237 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,15 +28,19 @@ 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_ANALOG_READ_RESOLUTION 10 // code below assumes readings to be in the classic 10-bit (0-1023) range +#include #include #include #include @@ -103,7 +107,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 55a15d229..7dfcdb78a 100644 --- a/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino +++ b/examples/03.Sensors/Knob_LightLevel_FMsynth/Knob_LightLevel_FMsynth.ino @@ -24,16 +24,18 @@ 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 +#include #include // oscillator #include // table for Oscils to play #include // maps unpredictable inputs to a range @@ -52,8 +54,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() @@ -68,7 +70,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 +83,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 = "); @@ -97,7 +99,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 294b9e70a..cacc3dbae 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,16 +27,19 @@ 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 +#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 #include @@ -62,9 +65,9 @@ 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 kIntensityMod(COS2048_DATA); +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); +Oscil kIntensityMod(COS2048_DATA); int mod_ratio = 5; // brightness (harmonics) long fm_intensity; // carries control info from updateControl to updateAudio @@ -129,7 +132,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 0d321f871..d307a3d2f 100644 --- a/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino +++ b/examples/03.Sensors/Light_Temperature_Detuned/Light_Temperature_Detuned.ino @@ -21,16 +21,18 @@ 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 +#include #include #include #include @@ -40,20 +42,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; @@ -102,8 +104,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; @@ -152,7 +154,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 ab0543274..68e42820d 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,46 +20,47 @@ 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 +#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 #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); -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 +74,7 @@ float downnotes[NUM_VOICES] = { void setup(){ - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -95,8 +96,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; @@ -161,7 +162,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 9ac767c52..4df41cf70 100644 --- a/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino +++ b/examples/03.Sensors/Piezo_Frequency/Piezo_Frequency.ino @@ -17,38 +17,41 @@ - 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 +// increase the rate of updateControl from the default of 64, to catch the piezo's rapid transients +#define MOZZI_CONTROL_RATE 128 +#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 -Oscil aSin(SIN2048_DATA); +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 + Serial.begin(115200); // set up the Serial output so we can look at the piezo values + startMozzi(); // :)) uses the control rate defined above } 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 @@ -56,8 +59,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); @@ -69,7 +70,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 4e3fba4ca..64e6deb21 100644 --- a/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino +++ b/examples/03.Sensors/Piezo_SampleScrubber/Piezo_SampleScrubber.ino @@ -19,16 +19,18 @@ - 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 +#include #include // Sample template #include "blahblah4b_int8.h" #include @@ -41,13 +43,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 / CONTROL_RATE; +const unsigned int AUDIO_STEPS_PER_CONTROL = MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE; void setup(){ @@ -59,7 +61,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 @@ -70,7 +72,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_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/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino index 96a26bdf6..32099c822 100644 --- a/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino +++ b/examples/03.Sensors/Piezo_SampleTrigger/Piezo_SampleTrigger.ino @@ -22,17 +22,18 @@ - 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 +#include #include // Sample template #include // a converted audio sample included in the Mozzi download @@ -41,7 +42,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; @@ -55,7 +56,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 +65,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 = "); @@ -84,7 +85,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 8663bef1e..417fd8f55 100644 --- a/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino +++ b/examples/03.Sensors/Piezo_Switch_Pitch/Piezo_Switch_Pitch.ino @@ -23,16 +23,18 @@ 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 +#include #include // Sample template #include // a converted audio sample included in the Mozzi download @@ -42,7 +44,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 @@ -79,7 +81,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 = "); @@ -104,7 +106,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 0bb38942b..e5578dd96 100644 --- a/examples/03.Sensors/RCpoll/RCpoll.ino +++ b/examples/03.Sensors/RCpoll/RCpoll.ino @@ -30,30 +30,33 @@ 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 -#include + 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 #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); +Oscil aSin(SIN2048_DATA); RCpoll sensor; void setup(){ //Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches Serial.begin(115200); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -65,7 +68,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 33c9a40b8..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,16 +18,18 @@ 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 +#include #include // oscillator template #include // sine table for oscillator #include @@ -35,7 +37,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(){ @@ -70,7 +72,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 4db03e90b..50b091004 100644 --- a/examples/03.Sensors/Volume_Knob/Volume_Knob.ino +++ b/examples/03.Sensors/Volume_Knob/Volume_Knob.ino @@ -22,21 +22,23 @@ / 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 +#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); +Oscil aSin(SIN2048_DATA); const char INPUT_PIN = 0; // set the input for the knob to analog pin 0 @@ -53,11 +55,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 = "); @@ -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 47f4c9da6..a4e2f84b6 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,16 +27,18 @@ 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 +#include #include // oscillator template #include // sine table for oscillator @@ -44,7 +46,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; @@ -56,11 +58,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 +67,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 = "); @@ -82,7 +81,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 0abfdfbcd..1327aa2dc 100644 --- a/examples/04.Audio_Input/Audio_Input/Audio_Input.ino +++ b/examples/04.Audio_Input/Audio_Input/Audio_Input.ino @@ -1,24 +1,32 @@ /* 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. 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 +#include +#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD +#define MOZZI_AUDIO_INPUT_PIN 0 + +#include void setup(){ startMozzi(); @@ -29,7 +37,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 585ac01b0..be409af44 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 @@ -15,15 +17,22 @@ 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 +#include +#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD +#define MOZZI_AUDIO_INPUT_PIN 0 + +#include #include #define KNOB_PIN 1 @@ -38,13 +47,12 @@ 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); } -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 3f15f5f62..5623c3f48 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. @@ -20,16 +18,22 @@ 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 + Copyright 2013-2024 Tim Barrass and the Mozzi Team - Tim Barrass 2013, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +#include +#define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_STANDARD +#define MOZZI_AUDIO_INPUT_PIN 0 + +#include void setup() { @@ -43,14 +47,14 @@ void setup() { void updateControl(){ for (int i=1;i +#include #include int sensorPin = A0; @@ -32,15 +33,15 @@ void setup() { void updateControl(){ - // read the value from the sensor: - int sensorValue = mozziAnalogRead(sensorPin); + // read the value from the sensor in 10 bit resolution: + int sensorValue = mozziAnalogRead<10>(sensorPin); Serial.print(sensorValue); Serial.print(" Filtered = "); Serial.println(dcFiltered.next(sensorValue)); } -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 0d5229f8a..6068a2ca1 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 @@ -16,41 +16,43 @@ 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. */ -#include +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable +#include #include #include // sine table for oscillator -#include +#include #include #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); +Oscil aSin0(SIN2048_DATA); +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 = AUDIO_RATE / 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, @@ -61,29 +63,31 @@ Smooth aSmooth(smoothness); // to smooth frequency for aSin1 void setup(){ - aSin0.setFreq(660.f); - aSin1.setFreq(220.f); - startMozzi(CONTROL_RATE); + aSin0.setFreq(660); + aSin1.setFreq(220); + startMozzi(); } -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(){ - 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); + aInterpolate.set(freq0, AUDIO_STEPS_PER_CONTROL); } -AudioOutput_t updateAudio(){ - Q16n16 interpolatedFreq = aInterpolate.next(); // get the next linear interpolated freq - aSin0.setFreq_Q16n16(interpolatedFreq); +AudioOutput updateAudio(){ + auto 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. } diff --git a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino index 11a4d08a3..d21df6ecf 100644 --- a/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino +++ b/examples/05.Control_Filters/MIDI_portamento/MIDI_portamento.ino @@ -12,17 +12,21 @@ (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 -#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 #include // sine table for oscillator @@ -33,16 +37,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); +Oscil aSin(SIN2048_DATA); // envelope generator -ADSR envelope; +ADSR envelope; -Portamento aPortamento; +Portamento aPortamento; #define LED 13 @@ -77,7 +78,7 @@ void setup() { aPortamento.setTime(300u); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -88,7 +89,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 060c35f07..716ae0810 100644 --- a/examples/05.Control_Filters/RollingAverage/RollingAverage.ino +++ b/examples/05.Control_Filters/RollingAverage/RollingAverage.ino @@ -10,16 +10,18 @@ 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 +#include #include // oscillator template #include // sine table for oscillator #include @@ -27,8 +29,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 @@ -42,7 +44,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"); @@ -55,7 +57,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 1c805fb98..0c03eae21 100644 --- a/examples/05.Control_Filters/Smooth/Smooth.ino +++ b/examples/05.Control_Filters/Smooth/Smooth.ino @@ -9,25 +9,26 @@ 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. */ -#include +#define MOZZI_CONTROL_RATE 128 +#include #include // oscillator template #include // sine table for oscillator #include #include #include -#define CONTROL_RATE 128 - -Oscil aSin(SIN2048_DATA); +Oscil aSin(SIN2048_DATA); // for scheduling audio gain changes EventDelay kGainChangeDelay; @@ -47,7 +48,7 @@ void setup(){ aSin.setFreq(330); // set the frequency kGainChangeDelay.set(gainChangeMsec); kSmoothOnOff.set(smoothOnOffMsec); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -74,7 +75,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 c4c98c725..9de8eb81e 100644 --- a/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino +++ b/examples/05.Control_Filters/Smooth_Frequency/Smooth_Frequency.ino @@ -7,27 +7,28 @@ 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 +// this is a high value to avoid zipper noise +#define MOZZI_CONTROL_RATE 1280 +#include #include // oscillator template #include // sine table for oscillator #include #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); +Oscil aSin(SIN2048_DATA); // for scheduling freq changes EventDelay kFreqChangeDelay; @@ -39,8 +40,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(); } @@ -60,7 +61,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 fabdf37b4..10cd33694 100644 --- a/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino +++ b/examples/05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino @@ -20,16 +20,18 @@ 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 +#include #include // oscillator template #include #include // SINe table for oscillator @@ -37,9 +39,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; @@ -49,7 +51,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; @@ -69,7 +71,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); @@ -108,7 +110,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 66d08e053..312e0fe7a 100644 --- a/examples/06.Synthesis/AMsynth/AMsynth.ino +++ b/examples/06.Synthesis/AMsynth/AMsynth.ino @@ -11,101 +11,99 @@ 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. */ -#include + +#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 -#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable // 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; +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 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); +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; - 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_t 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(); } diff --git a/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino b/examples/06.Synthesis/AMsynth_HIFI/AMsynth_HIFI.ino index 2b70710a9..cfe01f8cc 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 @@ -37,99 +30,100 @@ 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 + +#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); -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; +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 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 +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_t 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(); } 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..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,16 +9,18 @@ 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 +#include #include #include // oscillator template #include // sine table for oscillator @@ -26,7 +28,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() { @@ -41,7 +43,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 4c076a005..e6fdfc1a8 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) @@ -20,48 +20,56 @@ 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 +#include #include #include #include #include -#include // for Q16n16 fixed-point fractional number type +#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) -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 +77,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,40 +118,45 @@ 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; */ } } -AudioOutput_t updateAudio(){ +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() + @@ -151,6 +164,26 @@ AudioOutput_t updateAudio(){ aCos5.next() + aCos5b.next() + aCos6.next() + aCos6b.next();// + // aCos7.next() + aCos7b.next(); + return MonoOutput::fromAlmostNBit(12, asig); +*/ - 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); + } diff --git a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino index c7b8d41a6..fdeb7bf19 100644 --- a/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino +++ b/examples/06.Synthesis/Difference_Tone/Difference_Tone.ino @@ -3,21 +3,25 @@ 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 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 +#include #include #include #include @@ -25,9 +29,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; @@ -40,7 +44,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 } @@ -59,7 +63,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/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 +} diff --git a/examples/06.Synthesis/FMsynth/FMsynth.ino b/examples/06.Synthesis/FMsynth/FMsynth.ino index b450fb552..bde18a0a2 100644 --- a/examples/06.Synthesis/FMsynth/FMsynth.ino +++ b/examples/06.Synthesis/FMsynth/FMsynth.ino @@ -13,16 +13,19 @@ 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 +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable +#include #include #include // table for Oscils to play #include @@ -30,11 +33,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 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. @@ -60,7 +61,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 +69,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){ @@ -109,7 +110,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 7b6c4b65b..dc765db74 100644 --- a/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino +++ b/examples/06.Synthesis/FMsynth_32k_HIFI/FMsynth_32k_HIFI.ino @@ -3,24 +3,17 @@ 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. - 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 @@ -40,108 +33,102 @@ 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 + Copyright 2012-2024 Tim Barrass and the Mozzi Team - Tim Barrass 2012-13, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +#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 -#include // table for Oscils to play +#include // table for Oscils to play #include -#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); -// 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... +Oscil aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); +Oscil kModIndex(COS2048_DATA); -Q8n8 mod_index;// = float_to_Q8n8(2.0f); // constant version -Q16n16 deviation; +UFix<0, 16> mod_index; +UFix<8, 16> deviation; // 8 so that we do not exceed 32bits in updateAudio -Q16n16 carrier_freq, mod_freq; +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. -// 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 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); - startMozzi(CONTROL_RATE); -} +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 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 setup() { + kNoteChangeDelay.set(768); + kModIndex.setFreq(.768f); // sync with kNoteChangeDelay + startMozzi(); } -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 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. - // 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); } -AudioOutput_t 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 +AudioOutput updateAudio(){ +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 new file mode 100644 index 000000000..0001c27ae --- /dev/null +++ b/examples/06.Synthesis/FMsynth_FixMath/FMsynth_FixMath.ino @@ -0,0 +1,108 @@ +/* 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. + + 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 + + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + 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 +#include // table for Oscils to play +#include +#include +#include +#include + + + +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 = 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(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 +// 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 @@ -60,30 +64,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}; - - -// use #define for CONTROL_RATE, not a constant -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable +MetaOscil BL_aSq {&aSq90, &aSq101, &aSq122, &aSq138, &aSq154, &aSq174, &aSq210, &aSq264, &aSq327, &aSq431, &aSq546, &aSq744, &aSq1170, &aSq1638, &aSq2730, &aSq8192}; int freq = 10; @@ -95,7 +95,7 @@ void setup() { // Cutoff frequencies can also be set or changed individually. BL_aSq.setCutoffFreq(3000, 14); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -109,7 +109,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 05452a34f..4ed204934 100644 --- a/examples/06.Synthesis/PDresonant/PDresonant.ino +++ b/examples/06.Synthesis/PDresonant/PDresonant.ino @@ -17,18 +17,20 @@ (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 -#include +#include // for fake midi #include @@ -69,7 +71,7 @@ void setup(){ //MIDI.setHandleNoteOff(HandleNoteOff); // open MOZZI (: - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -120,19 +122,19 @@ 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(); } -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 dd9c07370..2501deb3f 100644 --- a/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino +++ b/examples/06.Synthesis/PWM_Phasing/PWM_Phasing.ino @@ -12,20 +12,22 @@ 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 +#include #include -Phasor aPhasor1; -Phasor aPhasor2; +Phasor aPhasor1; +Phasor aPhasor2; float freq = 55.f; @@ -40,7 +42,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 c4ca20993..773468d66 100644 --- a/examples/06.Synthesis/WaveFolder/WaveFolder.ino +++ b/examples/06.Synthesis/WaveFolder/WaveFolder.ino @@ -7,25 +7,27 @@ 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. */ -#include +#include #include // oscillator template #include // sine table for oscillator #include // saw table for oscillator #include -Oscil aSin(SIN2048_DATA); // audio oscillator -Oscil kBias(SIN2048_DATA); // LFO changing the bias -Oscil kGain(SAW512_DATA); // Gain oscillator +Oscil aSin(SIN2048_DATA); // audio 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 +42,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 MOZZI_AUDIO_RATE) + startMozzi(); } void updateControl() { @@ -49,7 +51,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 7558a4c1a..bad7f8ebf 100644 --- a/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino +++ b/examples/06.Synthesis/WavePacket_Double/WavePacket_Double.ino @@ -20,16 +20,18 @@ 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 +#include #include #include #include @@ -52,14 +54,14 @@ 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 } -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 323c50d17..f78dee11a 100644 --- a/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino +++ b/examples/06.Synthesis/WavePacket_Sample/WavePacket_Sample.ino @@ -23,15 +23,18 @@ 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 #include #include #include @@ -59,14 +62,14 @@ 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); } -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 60c0b80ca..7011aaa82 100644 --- a/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino +++ b/examples/06.Synthesis/WavePacket_Single/WavePacket_Single.ino @@ -20,15 +20,18 @@ 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 #include #include #include @@ -52,14 +55,14 @@ 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))); } -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 f2fe31236..2051b5894 100644 --- a/examples/06.Synthesis/Waveshaper/Waveshaper.ino +++ b/examples/06.Synthesis/Waveshaper/Waveshaper.ino @@ -2,37 +2,40 @@ 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 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 +#include #include #include #include #include #include #include +#include #include #include #include #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 @@ -43,12 +46,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(){ @@ -57,7 +59,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(){ @@ -88,16 +90,16 @@ 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); } -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 839a70b8a..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 @@ -1,25 +1,27 @@ /* 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 CONTROL_RATE, - which is more efficient, but AUDIO_RATE updates shown in this example + Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, + 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 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 +#include #include #include #include @@ -27,12 +29,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; @@ -98,7 +100,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 518f852ef..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 @@ -1,28 +1,30 @@ /* 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 CONTROL_RATE, - which is more efficient, but AUDIO_RATE updates shown in this example + Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, + 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 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 +#include #include #include #include @@ -30,12 +32,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; @@ -101,7 +103,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 112fecfcf..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 @@ -1,23 +1,25 @@ /* 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 CONTROL_RATE, - which is more efficient, but AUDIO_RATE updates shown in this example + Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE, + 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 +#include #include #include #include @@ -25,15 +27,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; @@ -171,7 +173,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 30f27aab3..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 @@ -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. @@ -8,10 +8,19 @@ 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. */ -#include +#define MOZZI_CONTROL_RATE 128 // faster than usual to help smooth MOZZI_CONTROL_RATE adsr interpolation (next()) +#include #include #include #include @@ -19,14 +28,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);; +Oscil <8192, MOZZI_AUDIO_RATE> aOscil(SIN8192_DATA);; // for triggering the envelope EventDelay noteDelay; -ADSR envelope; +ADSR envelope; boolean note_is_on = true; byte gain; @@ -36,7 +43,7 @@ void setup(){ Serial.begin(115200); randSeed(); // fresh random noteDelay.set(2000); // 2 second countdown - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -97,7 +104,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 72a7b6c25..7578be9d5 100644 --- a/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino +++ b/examples/07.Envelopes/Ead_Envelope/Ead_Envelope.ino @@ -1,39 +1,43 @@ -/* 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. */ -#include +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable +#include #include // oscillator template #include // recorded audio wavetable #include // exponential attack decay #include #include -#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable - -Oscil aNoise(BROWNNOISE8192_DATA); +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; 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(CONTROL_RATE); + startMozzi(); kDelay.start(1000); } @@ -54,7 +58,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 3dd6f9cf2..f7626cff4 100644 --- a/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino +++ b/examples/07.Envelopes/Phasemod_Envelope/Phasemod_Envelope.ino @@ -5,33 +5,34 @@ 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. */ -#include +#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 aEnvelop(ENVELOP2048_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); void setup() { - startMozzi(CONTROL_RATE); + startMozzi(); aCarrier.setFreq(220); kModFreq1.setFreq(1.78f); kModFreq2.setFreq(0.1757f); @@ -45,7 +46,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 cc89bd066..15c69cd64 100644 --- a/examples/08.Samples/Sample/Sample.ino +++ b/examples/08.Samples/Sample/Sample.ino @@ -8,22 +8,24 @@ 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 +#include #include // Sample template #include #include // use: Sample SampleName (wavetable) -Sample aSample(BURROUGHS1_18649_DATA); +Sample aSample(BURROUGHS1_18649_DATA); // for scheduling sample start EventDelay kTriggerDelay; @@ -31,7 +33,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 } @@ -43,7 +45,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 de8d4ab93..b76c57eb7 100644 --- a/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino +++ b/examples/08.Samples/SampleHuffman_Umpah/SampleHuffman_Umpah.ino @@ -35,13 +35,18 @@ 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 +#include #include #include "umpah_huff.h" @@ -57,7 +62,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(umpah.next()); } 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/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino b/examples/08.Samples/Sample_Loop_Points/Sample_Loop_Points.ino index 4c674ea23..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,25 +11,27 @@ 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. */ -#include +#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); +Sample aSample(ABOMB_DATA); // for scheduling changes EventDelay kTriggerDelay; @@ -39,14 +41,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(); } @@ -99,7 +101,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 d8e02f575..84826c80c 100644 --- a/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino +++ b/examples/08.Samples/Sample_Scrub/Sample_Scrub.ino @@ -8,14 +8,18 @@ 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 +#include #include // Sample template #include #include @@ -23,13 +27,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 / 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 @@ -50,8 +54,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); @@ -67,7 +71,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 00854ccec..ae34db505 100644 --- a/examples/08.Samples/Samples/Samples.ino +++ b/examples/08.Samples/Samples/Samples.ino @@ -9,16 +9,18 @@ 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 +#include #include // Sample template #include // wavetable data #include // wavetable data @@ -27,9 +29,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; @@ -39,7 +41,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 } @@ -79,7 +81,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 2d2e4e4ab..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,16 +13,18 @@ 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 +#include #include #include #include // for rand() @@ -42,15 +44,15 @@ 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; -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) @@ -76,7 +78,7 @@ void setup(){ for (int i=0;i +#include #include #include @@ -16,7 +24,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; @@ -26,7 +34,7 @@ boolean using_sin = true; void setup(){ startMozzi(); - kSwapTablesDelay.set(1000); // 1 second countdown, within resolution of CONTROL_RATE + kSwapTablesDelay.set(1000); // 1 second countdown, within resolution of MOZZI_CONTROL_RATE aOscil.setFreq(440.f); } @@ -45,7 +53,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aOscil.next()); } diff --git a/examples/09.Delays/AudioDelay/AudioDelay.ino b/examples/09.Delays/AudioDelay/AudioDelay.ino index e651eb60a..1f3255ee4 100644 --- a/examples/09.Delays/AudioDelay/AudioDelay.ino +++ b/examples/09.Delays/AudioDelay/AudioDelay.ino @@ -7,26 +7,27 @@ 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 +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable +#include #include #include // wavetable #include // wavetable #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 aTriangle(TRIANGLE_ANALOGUE512_DATA); +Oscil kFreq(COS2048_DATA); AudioDelay <256> aDel; int del_samps; @@ -34,7 +35,7 @@ int del_samps; void setup(){ aTriangle.setFreq(mtof(60.f)); kFreq.setFreq(.63f); - startMozzi(CONTROL_RATE); + startMozzi(); } void loop(){ @@ -45,7 +46,7 @@ void updateControl(){ del_samps = 128+kFreq.next(); } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ char asig = aDel.next(aTriangle.next(), del_samps); return MonoOutput::from8Bit(asig); } diff --git a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino index 250922569..ced34152d 100644 --- a/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino +++ b/examples/09.Delays/AudioDelayFeedback/AudioDelayFeedback.ino @@ -7,26 +7,27 @@ 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. */ -#include +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable +#include #include #include // wavetable #include // wavetable #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 aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator +Oscil kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples AudioDelayFeedback <128> aDel; @@ -34,7 +35,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 @@ -56,7 +57,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, (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 diff --git a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino index 431e4a3f1..715e62c7b 100644 --- a/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino +++ b/examples/09.Delays/AudioDelayFeedbackAllpass/AudioDelayFeedbackAllpass.ino @@ -9,16 +9,19 @@ 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. */ -#include +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable +#include #include #include #include // exponential attack decay @@ -26,11 +29,9 @@ #include #include -#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable - -Oscil aNoise(WHITENOISE8192_DATA); // audio noise +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,10 +40,10 @@ 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); + aNoise.setFreq((float)MOZZI_AUDIO_RATE/WHITENOISE8192_SAMPLERATE); kDelay.start(1000); } @@ -69,7 +70,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from8Bit(aDel.next((gain*aNoise.next())>>8)); } diff --git a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino index aed092e1b..a452807bd 100644 --- a/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino +++ b/examples/09.Delays/AudioDelayFeedbackX2/AudioDelayFeedbackX2.ino @@ -8,29 +8,30 @@ 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. */ -#include +#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable +#include #include #include // wavetable for audio #include // wavetable for delay sweep #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 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 +50,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(); } @@ -62,7 +63,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 d41276f72..1d047832b 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 @@ -38,26 +30,31 @@ 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 + Copyright 2013-2024 Tim Barrass and the Mozzi Team - Tim Barrass 2012-13, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +#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 #include // wavetable #include // wavetable #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 aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator +Oscil kDelSamps(TRIANGLE512_DATA); // for modulating delay time, measured in audio samples AudioDelayFeedback <128> aDel; @@ -66,7 +63,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 @@ -85,7 +82,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 e264c6671..4558c3319 100644 --- a/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino +++ b/examples/09.Delays/ReverbTank_HIFI/ReverbTank_HIFI.ino @@ -13,16 +13,19 @@ 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. */ -#include +#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth +#include #include #include #include @@ -30,15 +33,13 @@ 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 aEnvelop(ENVELOP2048_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); void setup(){ @@ -49,7 +50,7 @@ void setup(){ aModWidth.setFreq(2.52434f); aEnvelop.setFreq(9.0f); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -59,7 +60,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 20e73e694..3d7055b6b 100644 --- a/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino +++ b/examples/09.Delays/ReverbTank_STANDARD/ReverbTank_STANDARD.ino @@ -13,16 +13,19 @@ 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. */ -#include +#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth +#include #include #include #include @@ -30,15 +33,13 @@ 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 aEnvelop(ENVELOP2048_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); void setup(){ @@ -49,7 +50,7 @@ void setup(){ aModWidth.setFreq(2.52434f); aEnvelop.setFreq(9.0f); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -59,7 +60,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 cab4e77e3..04ad5ea99 100644 --- a/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino +++ b/examples/10.Audio_Filters/LowPassFilterX2/LowPassFilterX2.ino @@ -7,26 +7,28 @@ 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 +#include #include #include // recorded audio wavetable #include // for filter modulation #include #include // for rand() -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 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 LowPassFilter lpf1; // can be changed to HighPassFilter, BandPassFilter or NotchFilter LowPassFilter lpf2; @@ -53,7 +55,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 06fb110df..5f1726eef 100644 --- a/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino +++ b/examples/10.Audio_Filters/MultiResonantFilter/MultiResonantFilter.ino @@ -13,26 +13,27 @@ 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 +#include #include #include // recorded audio wavetable #include // for filter modulation #include #include -Oscil aCrunchySound(CHUM9_DATA); -Oscil kFilterMod(COS2048_DATA); -Oscil kFilterMod2(COS2048_DATA); +Oscil aCrunchySound(CHUM9_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,17 +57,17 @@ 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 } - // 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); } -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. { @@ -84,4 +85,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 77b775c0e..c0ec4241c 100644 --- a/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino +++ b/examples/10.Audio_Filters/ResonantFilter/ResonantFilter.ino @@ -11,24 +11,26 @@ 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 +#include #include #include // recorded audio wavetable #include // for filter modulation #include #include -Oscil aCrunchySound(CHUM9_DATA); -Oscil kFilterMod(COS2048_DATA); +Oscil aCrunchySound(CHUM9_DATA); +Oscil kFilterMod(COS2048_DATA); //Different types of filters available LowPassFilter rf; // Equivalent to ResonantFilter @@ -49,15 +51,15 @@ 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 + // 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_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 19a7f048a..de6bd858e 100644 --- a/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino +++ b/examples/10.Audio_Filters/ResonantFilter16/ResonantFilter16.ino @@ -13,25 +13,27 @@ 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 +#include #include #include // recorded audio wavetable #include // for filter modulation #include #include -Oscil aCrunchySound(CHUM9_DATA); -Oscil kFilterMod(COS2048_DATA); -Oscil kFilterMod2(COS2048_DATA); +Oscil aCrunchySound(CHUM9_DATA); +Oscil kFilterMod(COS2048_DATA); +Oscil kFilterMod2(COS2048_DATA); //Different types of filters available LowPassFilter16 rf; // Equivalent to ResonantFilter @@ -55,15 +57,15 @@ 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 + // 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_t updateAudio(){ - AudioOutput_t asig = rf.next(aCrunchySound.next()); +AudioOutput updateAudio(){ + AudioOutput 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 8db1a6d57..ca65731c3 100644 --- a/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino +++ b/examples/10.Audio_Filters/StateVariableFilter/StateVariableFilter.ino @@ -7,24 +7,26 @@ 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 +#include #include #include #include // for filter modulation #include #include // for rand() -Oscil aNoise(WHITENOISE8192_DATA); // audio noise -Oscil kFilterMod(COS2048_DATA); +Oscil aNoise(WHITENOISE8192_DATA); // audio noise +Oscil kFilterMod(COS2048_DATA); StateVariable svf; // can be LOWPASS, BANDPASS, HIGHPASS or NOTCH @@ -32,7 +34,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); @@ -41,7 +43,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; @@ -49,7 +51,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 cb23712b4..c07f10dde 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 @@ -34,27 +28,32 @@ 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 + Copyright 2012-2024 Tim Barrass and the Mozzi Team - Tim Barrass 2012, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM + +#include #include #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); } @@ -64,7 +63,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 24513f1a4..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,17 +10,21 @@ 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 -#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 #include @@ -29,14 +33,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); +Oscil aSin(SIN2048_DATA); // envelope generator -ADSR envelope; +ADSR envelope; #define LED 13 // shows if MIDI is being recieved @@ -64,7 +65,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(); } @@ -74,7 +75,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 27ecb18ac..179fa2da3 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 @@ -16,16 +16,24 @@ 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 #include // oscillator template #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 @@ -44,7 +52,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 208341260..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 @@ -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 @@ -48,16 +42,21 @@ 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 + Copyright 2013-2024 Tim Barrass and the Mozzi Team - Tim Barrass 2012-13, CC by-nc-sa. + 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 +//#define MOZZI_AUDIO_RATE 32768 -#include +#include #include // oscillator template #include // sine table for oscillator @@ -69,12 +68,12 @@ 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); +Oscil aSin(SIN2048_DATA); void updateRGB(byte r, byte g, byte b){ @@ -100,7 +99,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 } @@ -111,7 +110,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 216a7ae5d..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,31 +12,32 @@ 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 -#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 #include #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); +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 +64,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(); } @@ -73,7 +74,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 aedd5935a..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,28 +9,27 @@ 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. */ -#include +#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 +Oscil aSin(SIN2048_DATA); +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; @@ -193,7 +192,7 @@ void updateControl(){ } -AudioOutput_t updateAudio(){ +AudioOutput updateAudio(){ return MonoOutput::from16Bit(aSin.next()*gain); } 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 3bc9df8e2..38b9da0b7 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 @@ -23,12 +25,21 @@ 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 +#define MOZZI_CONTROL_RATE 128 +#include #include #include #include @@ -36,8 +47,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) @@ -57,10 +66,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; @@ -111,7 +120,7 @@ void setup() { kBOffsetTime.start(rand(200)); kCFOffsetTime.start(rand(200)); kLevelOffsetTime.start(rand(200)); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -215,7 +224,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 ed1b0c41e..28938b564 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 @@ -24,27 +26,30 @@ 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 +#define MOZZI_CONTROL_RATE 128 -#include +#include #include // Sample template #include // table for Sample #include #include #include // for fixed-point fractional numbers -#define CONTROL_RATE 128 - // 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; @@ -66,13 +71,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; @@ -97,7 +102,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 eefecd0ff..153a12c04 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 @@ -21,59 +23,67 @@ | 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 + +#include +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM +#define MOZZI_CONTROL_RATE 128 + +#include #include #include -#include "triangle512_uint8.h" +#include #include #include #include -#include // for fixed-point fractional numbers - -#define CONTROL_RATE 128 +#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)CONTROL_RATE * GLISS_SECONDS)) +//#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); -Oscil aCos1(SIN8192_DATA); +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; +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); @@ -83,12 +93,11 @@ void setup() { kTriggerDelay0.start(0); // start trigger before polling in updateControl() kTriggerDelay1.start((int)((GLISS_SECONDS * 1000.f) / 2.f)); - startMozzi(CONTROL_RATE); + startMozzi(); } - -void updateControl() { - +void updateControl() +{ if (kTriggerDelay0.ready()) { kGliss0.set(NOTE_START_FIXEDPOINT, NOTE_END_FIXEDPOINT, CONTROL_STEPS_PER_GLISS); kVol0.setPhase(0); @@ -96,39 +105,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 + auto gliss0 = kGliss0.next(); // fixed point + auto gliss1 = kGliss1.next(); // fixed point - Q16n16 gliss1 = kGliss1.next(); // fixed point - float freq1 = Q16n16_to_float(Q16n16_mtof(gliss1)); // convert fixed point to floating point + aCos0.setFreq(mtof(gliss0)); + aCos1.setFreq(mtof(gliss1)); - aCos0.setFreq(freq0); - aCos1.setFreq(freq1); + v0 = toSFraction(kVol0.next()); // convert as a pure fractionnal between -1 and 1 + v1 = toSFraction(kVol1.next()); - v0 = kVol0.next(); - v1 = kVol1.next(); - // Serial.print((byte)v0); Serial.print("\t"); Serial.println((byte)v1); - - // square for perceptual volume - v0 *= v0; - v1 *= v1; + // square for perceptual volume (also makes it positive...) + v0 = v0 * v0; + v1 = v1 * v1; } -AudioOutput_t updateAudio() { - long asig = ((v0 * aCos0.next()) >> 8) + - ((v1 * aCos1.next()) >> 8); - return AudioOutput::fromNBit(17, asig); +AudioOutput updateAudio() { + 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 8812bb118..000000000 --- a/examples/12.Misc/Shepard_Tone_HIFI/triangle512_uint8.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef TRIANGLE512_H_ -#define TRIANGLE512_H_ - -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif -#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_ */ diff --git a/examples/12.Misc/Stereo/Stereo.ino b/examples/12.Misc/Stereo/Stereo.ino new file mode 100644 index 000000000..52d10b13d --- /dev/null +++ b/examples/12.Misc/Stereo/Stereo.ino @@ -0,0 +1,60 @@ +/* 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 +// 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 +#include // table for oscillator + +// use: Oscil oscilName (wavetable) +Oscil aNoise(PINKNOISE8192_DATA); + +//Phasor for panning +Phasor kPan; // outputs an unsigned long 0-max 32 bit positive number +unsigned int pan; // convey pan from updateControl() to updateAudioStereo(); + + +void setup(){ + aNoise.setFreq(2.111f); // set the frequency with an unsigned int or a float + kPan.setFreq(0.25f); // take 4 seconds to move left-right + startMozzi(); // :) + Serial.begin(115200); +} + + +void updateControl(){ + pan = kPan.next()>>16; + Serial.println(pan); +} + +AudioOutput updateAudio(){ + int asig = aNoise.next(); + return StereoOutput::fromNBit(24, (long)pan*asig, (long)(65535-pan)*asig); +} + + +void loop(){ + audioHook(); // required here +} diff --git a/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino b/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino deleted file mode 100644 index 1bcc71484..000000000 --- a/examples/12.Misc/Stereo_Hack/Stereo_Hack.ino +++ /dev/null @@ -1,49 +0,0 @@ -/* Example crudely panning noise to test stereo output hack, - * using Mozzi sonification library. - * - * Tests stereo output. This requires #define AUDIO_CHANNELS STEREO in mozzi_config.h - * - * Circuit: Audio outputs on digital pins 9 and 10. - * - * Mozzi help/discussion/announcements: - * https://groups.google.com/forum/#!forum/mozzi-users - * - * Tim Barrass 2012. - * This example code is in the public domain. - */ - -#include -#include // for controlling panning position -#include // oscil for audio sig -#include // table for oscillator - -// use: Oscil oscilName (wavetable) -Oscil aNoise(PINKNOISE8192_DATA); - -//Phasor for panning -Phasor kPan; // outputs an unsigned long 0-max 32 bit positive number -unsigned int pan; // convey pan from updateControl() to updateAudioStereo(); - - -void setup(){ - aNoise.setFreq(2.111f); // set the frequency with an unsigned int or a float - kPan.setFreq(0.25f); // take 4 seconds to move left-right - startMozzi(); // :) - Serial.begin(115200); -} - - -void updateControl(){ - pan = kPan.next()>>16; - Serial.println(pan); -} - -AudioOutput_t updateAudio(){ - int asig = aNoise.next(); - return StereoOutput::fromNBit(24, (long)pan*asig, (long)(65535-pan)*asig); -} - - -void loop(){ - audioHook(); // required here -} diff --git a/examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino similarity index 55% rename from examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino rename to examples/12.Misc/Stereo_Pan/Stereo_Pan.ino index b6943face..c320f9660 100644 --- a/examples/12.Misc/Stereo_Hack_Pan/Stereo_Hack_Pan.ino +++ b/examples/12.Misc/Stereo_Pan/Stereo_Pan.ino @@ -1,29 +1,37 @@ /* 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! - Mozzi documentation/API - https://sensorium.github.io/Mozzi/doc/html/index.html + Circuit: Audio outputs on digital pins 9 and 10 (on classic Arduino). - 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 2017. - This example code is in the public domain. + Mozzi help/discussion/announcements: + https://groups.google.com/forum/#!forum/mozzi-users + + 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. */ -#include +// 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 #include // sine table for pan oscillator // use: Oscil oscilName (wavetable) -Oscil aNoise(PINKNOISE8192_DATA); +Oscil aNoise(PINKNOISE8192_DATA); -Oscil kPan(SIN2048_DATA); +Oscil kPan(SIN2048_DATA); byte ampA, ampB; // convey amplitudes from updateControl() to updateAudioStereo(); @@ -49,7 +57,7 @@ void updateControl() } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { int asig = aNoise.next(); return StereoOutput::from16Bit(asig*ampA, asig*ampB); } @@ -57,4 +65,4 @@ AudioOutput_t updateAudio() { void loop() { audioHook(); // required here -} \ No newline at end of file +} 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..cf5adab0e --- /dev/null +++ b/examples/13.External_Audio_Output/ESP32_Bluetooth/ESP32_Bluetooth.ino @@ -0,0 +1,127 @@ + +/* 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 + + 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: +#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(); +} 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..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 @@ -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: @@ -25,11 +23,25 @@ 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. */ -#include +// 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 +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable + +#include #include #include // table for Oscils to play #include @@ -39,13 +51,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 aCarrier(COS2048_DATA); +Oscil aModulator(COS2048_DATA); +Oscil kModIndex(COS2048_DATA); Q8n8 mod_index; @@ -78,7 +87,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); @@ -91,7 +100,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) { @@ -132,7 +141,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 463515201..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 @@ -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: @@ -40,30 +37,34 @@ - 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 2020-2024 T. Combriat and the Mozzi Team - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +// 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 +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable + +#include #include #include // table for Oscils to play #include #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 aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); @@ -71,7 +72,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 +80,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; @@ -100,7 +100,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(); } @@ -115,7 +115,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 996d94101..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 @@ -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: @@ -20,29 +16,34 @@ 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 + Copyright 2020-2024 T. Combriat and the Mozzi Team - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +// 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 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 aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); +Oscil kEnv2(COS2048_DATA); @@ -50,11 +51,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 +63,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()); @@ -86,7 +82,7 @@ void setup() { aCos2.setFreq(220.f); kEnv1.setFreq(0.25f); kEnv2.setFreq(0.30f); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -100,7 +96,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 3658191a0..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 @@ -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: @@ -20,29 +15,31 @@ 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 +#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO +#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable -#include +#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 aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); +Oscil kEnv2(COS2048_DATA); @@ -50,7 +47,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 +56,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()); @@ -81,7 +77,7 @@ void setup() { kEnv1.setFreq(0.25f); kEnv2.setFreq(0.30f); - startMozzi(CONTROL_RATE); + startMozzi(); } @@ -95,7 +91,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 3979db190..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 @@ -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. @@ -32,39 +29,40 @@ 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 + Copyright 2020-2024 T. Combriat and the Mozzi Team - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +#define MOZZI_AUDIO_BITS 6 +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable + +#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); // 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++) { @@ -76,7 +74,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 } @@ -86,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/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..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 @@ -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. @@ -37,37 +34,36 @@ 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 + Copyright 2020-2024 T. Combriat and the Mozzi Team - Tim Barrass 2012, CC by-nc-sa. - T. Combriat 2020, CC by-nc-sa. + Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later. */ -#include +#include "MozziConfigValues.h" // for named option values +#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED +#define MOZZI_AUDIO_BITS 8 +#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable + +#include #include // oscillator template #include // sine table for oscillator #include // needed for the shift register // 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); // 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); @@ -79,7 +75,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 } @@ -89,7 +85,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 2182c3bfd..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 @@ -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: @@ -22,31 +16,36 @@ 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 +#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 MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable + +#include #include #include // table for Oscils to play #include #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 kEnv2(COS2048_DATA); +Oscil aCos1(COS2048_DATA); +Oscil aCos2(COS2048_DATA); +Oscil kEnv1(COS2048_DATA); +Oscil kEnv2(COS2048_DATA); @@ -60,8 +59,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. @@ -80,7 +79,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(); } @@ -94,7 +93,7 @@ void updateControl() { } -AudioOutput_t updateAudio() { +AudioOutput updateAudio() { return StereoOutput::fromNBit(12, aCos1.next() * env1, aCos2.next() * env2); } diff --git a/extras/NEWS.txt b/extras/NEWS.txt index 9aec0b01b..0c36f811c 100644 --- a/extras/NEWS.txt +++ b/extras/NEWS.txt @@ -3,7 +3,18 @@ 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 +- This release is *not* 100% source compatible to earlier versions of Mozzi. Most sketches will continue to compile, + but with warnings. Some will need adjustments to keep working. See https://sensorium.github.io/Mozzi/learn/porting/ . + If porting is not an option, install an earlier (1.x) version of Mozzi, or use the "Mozzi_1" branch in git. +- Now depends on FixMath library for enhanced fixed point arithmetic (which is actually spin-off originating in the Mozzi project) +- 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. + There is no longer a central mozzi_config.h file, but rather config options can be customized using + #defines at the top of a sketch. +- Changed licence to LGPL version 2.1 or later + +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 @@ -239,7 +250,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 @@ -382,7 +393,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/devscripts/mozzi_compile_examples.sh b/extras/devscripts/mozzi_compile_examples.sh old mode 100644 new mode 100755 diff --git a/extras/devscripts/mozzi_compile_examples_hifi.sh b/extras/devscripts/mozzi_compile_examples_hifi.sh old mode 100644 new mode 100755 diff --git a/extras/devscripts/mozzi_copy_extra_sounds.sh b/extras/devscripts/mozzi_copy_extra_sounds.sh old mode 100644 new mode 100755 diff --git a/extras/devscripts/mozzi_generate_examples_page_buttons.sh b/extras/devscripts/mozzi_generate_examples_page_buttons.sh old mode 100644 new mode 100755 diff --git a/extras/devscripts/mozzi_generate_page.sh b/extras/devscripts/mozzi_generate_page.sh old mode 100644 new mode 100755 diff --git a/extras/devscripts/mozzi_release_step1.sh b/extras/devscripts/mozzi_release_step1.sh old mode 100644 new mode 100755 index adf063a09..1e0b6ca9a --- 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 old mode 100644 new mode 100755 index b9196031e..d971587e7 --- 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/extras/devscripts/update_version.sh b/extras/devscripts/update_version.sh old mode 100644 new mode 100755 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..af8e51df6 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 @@ -1,9 +1,9 @@ - + - + Mozzi: 01.Basics/Vibrato/Vibrato.ino @@ -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,17 +99,66 @@
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.
*/
#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();
}
+

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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,92 @@
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.
*/
#include <MozziGuts.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
#define CONTROL_RATE 64
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, AUDIO_RATE> aSin0(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin1(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin2(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, 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_t updateAudio(){
return MonoOutput::almostNBit(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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,77 @@
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.
*/
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/triangle_valve_2048_int8.h>
#include <tables/sin2048_int8.h>
#include <Line.h>
#include <mozzi_midi.h>
#define CONTROL_RATE 64 // Hz, powers of 2 are most reliable
// audio oscillator
Oscil<TRIANGLE_VALVE_2048_NUM_CELLS, AUDIO_RATE> aSig(TRIANGLE_VALVE_2048_DATA);
// control oscillator for tremelo
Oscil<SIN2048_NUM_CELLS, 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(CONTROL_RATE);
}
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
}
AudioOutput_t 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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,72 @@
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.
*/
#include <MozziGuts.h>
#include <Oscil.h> // oscillator template
#include <tables/sin8192_int8.h> // sine table for oscillator
#include <EventDelay.h>
#define CONTROL_RATE 64
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SIN8192_NUM_CELLS, AUDIO_RATE> aSin(SIN8192_DATA);
// for scheduling audio gain changes
EventDelay kGainChangeDelay;
char gain = 1;
void setup(){
startMozzi(CONTROL_RATE);
aSin.setFreq(330); // set the frequency
kGainChangeDelay.set(1000); // 1 second countdown, within resolution of CONTROL_RATE
}
void updateControl(){
if(kGainChangeDelay.ready()){
gain = 1-gain; // flip 0/1
kGainChangeDelay.start();
}
}
AudioOutput_t 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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,104 @@
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 <MozziGuts.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_t 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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,129 @@
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_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
+
+
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
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,11 @@
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 <MozziGuts.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_t updateAudio(){
return 0;
}
void loop(){
audioHook();
}
+

This example demonstrates the DCFilter class.

+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,96 @@
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.
*/
#include <MozziGuts.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>
#define CONTROL_RATE 128
Oscil <SIN2048_NUM_CELLS, 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(CONTROL_RATE);
}
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_t 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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,11 @@
05.Control_Filters/Teensy_USB_MIDI_portamento/Teensy_USB_MIDI_portamento.ino
-


- This example demonstrates the Portamento class.

+

This example demonstrates the Portamento class.

- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,131 @@
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 <MozziGuts.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, AUDIO_RATE> aSin(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aTremelo(SIN2048_DATA);
Oscil <SIN2048_NUM_CELLS, 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)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_t 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
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,132 @@
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) (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.com/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.
*/
#include <MozziGuts.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, AUDIO_RATE> aSq90(SQUARE_MAX_90_AT_16384_512_DATA);
Oscil <SQUARE_MAX_101_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq101(SQUARE_MAX_101_AT_16384_512_DATA);
Oscil <SQUARE_MAX_122_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq122(SQUARE_MAX_122_AT_16384_512_DATA);
Oscil <SQUARE_MAX_138_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq138(SQUARE_MAX_138_AT_16384_512_DATA);
Oscil <SQUARE_MAX_154_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq154(SQUARE_MAX_154_AT_16384_512_DATA);
Oscil <SQUARE_MAX_174_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq174(SQUARE_MAX_174_AT_16384_512_DATA);
Oscil <SQUARE_MAX_210_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq210(SQUARE_MAX_210_AT_16384_512_DATA);
Oscil <SQUARE_MAX_264_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq264(SQUARE_MAX_264_AT_16384_512_DATA);
Oscil <SQUARE_MAX_327_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq327(SQUARE_MAX_327_AT_16384_512_DATA);
Oscil <SQUARE_MAX_431_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq431(SQUARE_MAX_431_AT_16384_512_DATA);
Oscil <SQUARE_MAX_546_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq546(SQUARE_MAX_546_AT_16384_512_DATA);
Oscil <SQUARE_MAX_744_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq744(SQUARE_MAX_744_AT_16384_512_DATA);
Oscil <SQUARE_MAX_910_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq910(SQUARE_MAX_910_AT_16384_512_DATA);
Oscil <SQUARE_MAX_1170_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq1170(SQUARE_MAX_1170_AT_16384_512_DATA);
Oscil <SQUARE_MAX_1638_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq1638(SQUARE_MAX_1638_AT_16384_512_DATA);
Oscil <SQUARE_MAX_2730_AT_16384_512_NUM_CELLS, AUDIO_RATE> aSq2730(SQUARE_MAX_2730_AT_16384_512_DATA);
Oscil <SQUARE_MAX_8192_AT_16384_512_NUM_CELLS, 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, AUDIO_RATE, 16> 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;
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(CONTROL_RATE);
}
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_t 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
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,65 @@
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 <MozziGuts.h>
#include <Phasor.h>
Phasor <AUDIO_RATE> aPhasor1;
Phasor <AUDIO_RATE> aPhasor2;
float freq = 55.f;
void setup(){
aPhasor1.setFreq(freq);
aPhasor2.setFreq(freq+0.2f);
startMozzi(); // :)
}
void updateControl(){
}
AudioOutput_t 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
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,11 @@
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.

- - - + @@ -80,7 +76,7 @@
@@ -104,15 +100,89 @@

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_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_t 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
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,11 @@
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 <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
}
+

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

+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,11 @@
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.

+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,79 @@
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
*/
#include <MozziGuts.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>
#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable
Oscil<BROWNNOISE8192_NUM_CELLS, AUDIO_RATE> aNoise(BROWNNOISE8192_DATA);
EventDelay kDelay; // for triggering envelope start
Ead kEnvelope(CONTROL_RATE); // resolution will be CONTROL_RATE
int gain;
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);
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_t 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
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,66 @@
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 <MozziGuts.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, 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 CONTROL_RATE
}
void updateControl(){
if(kTriggerDelay.ready()){
aSample.start();
kTriggerDelay.start();
}
}
AudioOutput_t 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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,83 @@
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 <MozziGuts.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_t 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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,63 @@
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.
*/
#include <MozziGuts.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
#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable
Oscil<TRIANGLE_ANALOGUE512_NUM_CELLS, AUDIO_RATE> aTriangle(TRIANGLE_ANALOGUE512_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kFreq(COS2048_DATA);
AudioDelay <256> aDel;
int del_samps;
void setup(){
aTriangle.setFreq(mtof(60.f));
kFreq.setFreq(.63f);
startMozzi(CONTROL_RATE);
}
void loop(){
audioHook();
}
void updateControl(){
del_samps = 128+kFreq.next();
}
AudioOutput_t 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);
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,81 @@
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.
*/
#include <MozziGuts.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
#define CONTROL_RATE 128 // Hz, powers of 2 are most reliable
Oscil<TRIANGLE_ANALOGUE512_NUM_CELLS, AUDIO_RATE> aTriangle(TRIANGLE_ANALOGUE512_DATA); // audio oscillator
Oscil<TRIANGLE512_NUM_CELLS, 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(CONTROL_RATE);
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_t 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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,87 @@
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.
*/
#include <MozziGuts.h>
#include <ReverbTank.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <tables/envelop2048_uint8.h>
ReverbTank reverb;
#define CONTROL_RATE 640 // quite fast, keeps modulation smooth
// Synth from PhaseMod_Envelope example
Oscil <COS8192_NUM_CELLS, AUDIO_RATE> aCarrier(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, AUDIO_RATE> aModulator(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, AUDIO_RATE> aModWidth(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, CONTROL_RATE> kModFreq1(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, CONTROL_RATE> kModFreq2(COS8192_DATA);
Oscil <ENVELOP2048_NUM_CELLS, 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(CONTROL_RATE);
}
void updateControl(){
// synth control
aModulator.setFreq(277.0f + 0.4313f*kModFreq1.next() + kModFreq2.next());
}
AudioOutput_t 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();
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -104,15 +100,98 @@

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
+
+
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
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -104,15 +100,81 @@

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
+
+
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);
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,76 @@
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 <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);
//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(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
byte cutoff_freq = 100 + kFilterMod.next()/2;
rf.setCutoffFreqAndResonance(cutoff_freq, resonance);
}
AudioOutput_t 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);
+
}
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,11 @@
11.Audio_Filters/StateVariableFilter/StateVariableFilter.ino
-


- This example demonstrates the StateVariable class.

+

This example demonstrates the StateVariable class.

- - - + @@ -80,7 +76,7 @@
@@ -103,42 +99,450 @@
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 #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  * 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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,23 +99,138 @@
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 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
-
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_
- - - + @@ -80,7 +76,7 @@
@@ -103,30 +99,415 @@
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 #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  * 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_
- - - + @@ -80,7 +76,7 @@
@@ -103,45 +99,257 @@
AudioOutput.h
-
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 /*
+
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
- - - + @@ -80,7 +76,7 @@
@@ -103,23 +99,87 @@
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 #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  * 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_
- - - + @@ -80,7 +76,7 @@
@@ -103,22 +99,94 @@
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 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  * 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
- - - + @@ -80,7 +76,7 @@
@@ -103,19 +99,76 @@
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
- - - + @@ -80,7 +76,7 @@
@@ -103,18 +99,104 @@
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 /** 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  * 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 };
- - - + @@ -80,7 +76,7 @@
@@ -103,18 +99,48 @@
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_
- - - + @@ -80,7 +76,7 @@
@@ -103,19 +99,99 @@
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
- - - + @@ -80,7 +76,7 @@
@@ -103,29 +99,182 @@
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 CONTROL_RATE or 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:35
-
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:44
-
#define Q8n24_FIX1
1 in Q8n24 format
Definition: mozzi_fixmath.h:64
-
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,22 +99,103 @@
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)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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,19 +99,59 @@
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,57 @@
IntegerType.h
-
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 /*
+
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,37 +99,503 @@
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 #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  * 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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,29 @@
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_ */
+
- - - + @@ -80,7 +76,7 @@
@@ -103,37 +99,243 @@
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 #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  * 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 */
- - - + @@ -80,7 +76,7 @@
@@ -103,25 +99,113 @@
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -100,23 +96,25 @@
-
IntegerType< BYTES > Member List
+
Mozzi.h File Reference
-

This is the complete list of members for IntegerType< BYTES >, including all inherited members.

- - - -
signed_type typedef (defined in IntegerType< BYTES >)IntegerType< BYTES >
unsigned_type typedef (defined in IntegerType< BYTES >)IntegerType< BYTES >
+

This is the main include file in Mozzi. +More...

+
#include "MozziGuts.h"
+
+

Go to the source code of this file.

+

Detailed Description

+

This is the main include file in Mozzi.

+

Almost all sketches using Mozzi will want to include this file exactly once.

+

Should your sketch require Mozzi Core Functions 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 MozziHeadersOnly instead. (Failing to heed this advice will lead to "duplicate definition" errors.)

+ +

Definition in file Mozzi.h.

+
- - - + @@ -80,7 +76,7 @@
@@ -103,41 +99,218 @@
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 //#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()
-
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()
+
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 The bones of every Mozzi sketch.
+
57 
+
58 @ingroup core
+
59 Sets up the timers for audio and control rate processes, storing the timer
+
60 registers so they can be restored when Mozzi stops. startMozzi() goes in your sketch's
+
61 setup() routine.
+
62 
+
63 This function intializes the timer(s) needed to move audio samples to the output according to the
+
64 configured @ref MOZZI_AUDIO_MODE .
+
65 
+
66 @param control_rate_hz Sets how often updateControl() is called. It must be a power of 2.
+
67 If no parameter is provided, control_rate_hz is set to MOZZI_CONTROL_RATE,
+
68 which has a default value of 64 (you can re-\#define it in your sketch).
+
69 The practical upper limit for control rate depends on how busy the processor is,
+
70 and you might need to do some tests to find the best setting.
+
71 
+
72 @note startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(),
+
73 which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack).
+
74 They are all called automatically and hidden away because it keeps things simple for a STANDARD_PLUS set up,
+
75 but if it turns out to be confusing, they might need to become visible again.
+
76 */
+
77 void startMozzi(int control_rate_hz = MOZZI_CONTROL_RATE);
+
78 
+
79 
+
80 
+
81 /** @ingroup core
+
82 Stops audio and control interrupts and restores the timers to the values they
+
83 had before Mozzi was started. This could be useful when using sensor libraries
+
84 which depend on the same timers as Mozzi.
+
85 
+
86 A potentially better option for resolving timer conflicts involves using
+
87 non-blocking methods, such as demonstrated by the twowire_nonblock code in the
+
88 forked version of Mozzi on github, so sound production can continue while
+
89 reading sensors.
+
90 
+
91 As it is, stopMozzi restores all the Timers used by Mozzi to their previous
+
92 settings. Another scenario which could be easily hacked in MozziGuts.hpp could
+
93 involve individually saving and restoring particular Timer registers depending
+
94 on which one(s) are required for other tasks.
+
95 
+
96 @note This function is not actually implemented on all platforms.
+
97 */
+
98 void stopMozzi();
+
99 
+
100 
+ +
102 AudioOutput_t updateAudio();
+
103 #else
+
104 /** @ingroup core
+
105 This is where you put your audio code. updateAudio() has to keep up with the
+
106 MOZZI_AUDIO_RATE of 16384 or 32768 Hz, so to keep things running smoothly, avoid doing any
+
107 calculations here which could be done in setup() or updateControl().
+
108 @return an audio sample.
+
109 
+
110 While is possible (in mono sketches) to return a plain unscaled int, it is generally best to return
+
111 auto-scaled samples using MonoOutput::from8Bit(), MonoOutput::from16Bit(), MonoOutput::fromNbit(), or
+
112 their StereoOutput equivalents.
+
113 */
+
114 AudioOutput updateAudio();
+
115 #endif
+
116 
+
117 /** @ingroup core
+
118 This is where you put your control code. You need updateControl() somewhere in
+
119 your sketch, even if it's empty. updateControl() is called at the control rate
+
120 you set in startMozzi(). To save processor load, avoid any calculations here
+
121 which could be done in setup().
+
122 */
+
123 void updateControl();
+
124 
+
125 
+
126 /** @ingroup core
+
127 This is required in Arduino's loop(). If there is room in Mozzi's output buffer,
+
128 audioHook() calls updateAudio() once and puts the result into the output
+
129 buffer. Also, if \@ref MOZZI_AUDIO_INPUT is enabled in the config,
+
130 audioHook() takes care of moving audio input from the input buffer so it can be
+
131 accessed with getAudioInput() in your updateAudio() routine.
+
132 If other functions are called in loop() along with audioHook(), see if
+
133 they can be called less often by moving them into updateControl(),
+
134 to save processing power. Otherwise it may be most efficient to
+
135 calculate a block of samples at a time by putting audioHook() in a loop of its
+
136 own, rather than calculating only 1 sample for each time your other functions
+
137 are called.
+
138 */
+
139 void audioHook();
+
140 
+
141 /** @ingroup analog
+
142 
+
143 See getAudioInput(). The template parameter specifies the desired value range in bits. */
+
144 template<byte RES> uint16_t getAudioInput();
+
145 
+
146 /** @ingroup analog
+
147 
+
148 See getAudioInput(). Equivalent to getAudioInput<16>(). */
+
149 template<byte RES> inline uint16_t getAudioInput16() { return getAudioInput<16>(); }
+
150 
+
151 /** @ingroup analog
+
152 This returns audio input from the input buffer, if
+
153 \@ref MOZZI_AUDIO_INPUT is enabled in the config (see also the related option MOZZI_AUDIO_INPUT_PIN).
+
154 
+
155 The audio signal needs to be in the range 0 to VCC volts (i.e. 5 volts on Arduino Uno R3).
+
156 Circuits and discussions about biasing a signal
+
157 in the middle of this range can be found at
+
158 http://electronics.stackexchange.com/questions/14404/dc-biasing-audio-signal
+
159 and
+
160 http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/ .
+
161 A circuit and instructions for amplifying and biasing a microphone signal can be found at
+
162 http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS
+
163 
+
164 @note The value range returned by this function follows the same rules as detailed in the documentation
+
165  for mozziAnalogRead(): For portable code, define MOZZI_ANALGO_READ_RESOLUTION at the top of your
+
166  sketch, or use the templated version of this function.
+
167 
+
168 @return audio data from the input buffer
+
169 */
+
170 #if defined(FOR_DOXYGEN_ONLY) || (!MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE))
+
171 #if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION)
+
172 inline uint16_t getAudioInput() { return getAudioInput<MOZZI_ANALOG_READ_RESOLUTION>(); };
+
173 #else
+
174 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>(); };
+
175 #endif
+
176 #endif
+
177 
+
178 
+
179 /** @ingroup core
+
180 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
+
181 and also it is synchronized with the currently processed audio sample (which, due to the audio
+
182 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
+
183 audioTicks() is updated each time an audio sample
+
184 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
+
185 16384 Hz).
+
186 @return the number of audio ticks since the program began.
+
187 */
+
188 unsigned long audioTicks();
+
189 
+
190 
+
191 
+
192 /** @ingroup core
+
193 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
+
194 and also it is synchronized with the currently processed audio sample (which, due to the audio
+
195 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
+
196 audioTicks() is updated each time an audio sample
+
197 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
+
198 16384 Hz).
+
199 @return the approximate number of microseconds since the program began.
+
200 @todo incorporate mozziMicros() in a more accurate EventDelay()?
+
201 */
+
202 unsigned long mozziMicros();
+
203 
+
204 #ifndef _MOZZI_HEADER_ONLY
+
205 #include "internal/MozziGuts.hpp"
+
206 #endif
+
207 
+
208 #endif /* MOZZIGUTS_H_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,21 +99,457 @@
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 "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_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 }
- - - + @@ -80,7 +76,7 @@
@@ -103,25 +99,188 @@
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 ////// 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_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
- - - + @@ -80,7 +76,7 @@
@@ -103,23 +99,167 @@
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 ////// 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_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
- - - + @@ -80,7 +76,7 @@
@@ -103,18 +99,298 @@
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 
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_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
- - - + @@ -80,7 +76,7 @@
@@ -103,20 +99,164 @@
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 ////// 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_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
- - - + @@ -80,7 +76,7 @@
@@ -103,22 +99,177 @@
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 ////// 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_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
- - - + @@ -80,7 +76,7 @@
@@ -103,23 +99,138 @@
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 // 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_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
- - - + @@ -80,7 +76,7 @@
@@ -103,18 +99,194 @@
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 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.
+Go to the documentation of this file.
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 /** @file MozziGuts_impl_template.hpp Template for implementation of new ports
+
13  *
+
14  * README!
+
15  * This file is meant to be used as a template when adding support for a new platform. Please read these instructions, first.
+
16  *
+
17  * Files involved:
+
18  * 1. Modify hardware_defines.h, adding a macro to detect your target platform
+
19  * 2. Modify MozziGuts.cpp to include MozziGuts_impl_YOURPLATFORM.hpp
+
20  * 3. Modify internal/config_checks_generic.h to include internal/config_checks_YOURPLATFORM.h
+
21  * 4. Copy this file to MozziGuts_impl_YOURPLATFORM.hpp and adjust as necessary, same for internal/config_checks_template.h
+
22  * (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,
+
23  * instead of steps 2-3.).
+
24  * Some platforms may need small modifications to other files as well, e.g. mozzi_pgmspace.h
+
25  *
+
26  * How to implement MozziGuts_impl_YOURPLATFORM.hpp:
+
27  * - Follow the NOTEs provided in this file
+
28  * - Read the doc at the top of AudioOutput.h for a better understanding of the basic audio output framework
+
29  * - 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)
+
30  * - Wait for more documentation to arrive
+
31  * - Ask when in doubt
+
32  * - Don't forget to provide a PR when done (it does not have to be perfect; e.g. many ports skip analog input, initially)
+
33  */
+
34 
+
35 // The main point of this check is to document, what platform & variants this implementation file is for.
+
36 #if !(IS_MYPLATFORM())
+
37 # error "Wrong implementation included for this platform"
+
38 #endif
+
39 // Add platform specific includes and declarations, here
+
40 
+
41 //#include <my_hardware_header.h>
+
42 
+
43 // In order to allow simple yet efficient user configuration, the entire contents of this file are compiled in the same translation unit
+
44 // as (the main file of) the user sketch. To avoid name clashes, we encapsulate everyghing in a namespace.
+
45 // 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
+
46 // worry about it. However, there may be a few situations, where you have to "leave" the MozziPrivate namespace. This includes:
+
47 // - When you include a further (hardware-dependent library). Consider gathering all includes at the top of this file, instead.
+
48 // - When you provide definitions for special names, importantly for ISR-functions. If these would be placed in the namespace, the linker would not
+
49 // recognize them as the definition of the intended ISR-vector. See MozziGuts_impl_AVR.hpp for examples.
+
50 
+
51 namespace MozziPrivate {
+
52 
+
53 ////// BEGIN analog input code ////////
+
54 
+
55 #if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_STANDARD)
+
56 /** NOTE: This section deals with implementing (fast) asynchronous analog reads, which form the backbone of mozziAnalogRead(), but also of MOZZI_AUDIO_INPUT (if enabled).
+
57  *
+
58  * 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
+
59  * in your platform configuration checks:
+
60  *
+
61  * // analog reads shall be enabled by default on platforms that support it
+
62  * #if not defined(MOZZI_ANALOG_READ)
+
63  * #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
+
64  * #endif
+
65  *
+
66  * Also, of course, remove the #error line, below
+
67  */
+
68 #error not yet implemented
+
69 
+
70 // Insert here code to read the result of the latest asynchronous conversion, when it is finished.
+
71 // You can also provide this as a function returning unsigned int, should it be more complex on your platform
+
72 #define getADCReading() GET_MY_PLATFORM_ADC_REGISTER
+
73 
+
74 /** NOTE: On "pins" vs. "channels" vs. "indices"
+
75  * "Pin" is the pin number as would usually be specified by the user in mozziAnalogRead().
+
76  * "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.
+
77  * In other words, this is an internal representation of "pin".
+
78  * "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
+
79  * same as "channel" (e.g. on AVR), however, on platforms where ADC-capable "channels" are not numbered sequentially starting from 0, the channel needs
+
80  * to be converted to a suitable index.
+
81  *
+
82  * In summary, the semantics are roughly
+
83  * mozziAnalogRead(pin) -> _ADCimplementation_(channel) -> analog_readings[index]
+
84  * Implement adcPinToChannelNum() and channelNumToIndex() to perform the appropriate mapping.
+
85  */
+
86 // NOTE: Theoretically, adcPinToChannelNum is public API for historical reasons, thus cannot be replaced by a define
+
87 #define channelNumToIndex(channel) channel
+ +
89  return pin;
+
90 }
+
91 
+
92 /** NOTE: Code needed to trigger a conversion on a new channel */
+ +
94 }
+
95 
+
96 /** 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
+
97  * adcStartConversion(), and simply call adcStartConversion(previous_channel), here. */
+ +
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) {
+ +
105  // insert further custom code
+
106 }
+
107 
+
108 /* NOTE: Most platforms call a specific function/ISR when conversion is complete. Provide this function, here.
+
109  * From inside its body, simply call advanceADCStep(). E.g.:
+
110 void stm32_adc_eoc_handler() {
+
111  advanceADCStep();
+
112 }
+
113 */
+
114 
+
115 /** 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.
+
116  * This particular function is not super important, so may be ok to leave empty, at least, if the ADC is fast enough by default. */
+ +
118 }
+
119 
+
120 #endif
+
121 
+
122 ////// END analog input code ////////
+
123 
+
124 ////// BEGIN audio output code //////
+
125 /* 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,
+
126  * 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
+
127  * running smoothly. */
+
128 //#define LOOP_YIELD yield();
+
129 
+
130 /* NOTE: On some platforms, what can be called in the ISR used to output the sound is limited.
+
131  * This define can be used, for instance, to output the sound in audioHook() instead to overcome
+
132  * this limitation (see MozziGuts_impl_MBED.hpp). It can also be used if something needs to be called in audioHook() regarding
+
133  * analog reads for instance. */
+
134 //#define AUDIO_HOOK_HOOK
+
135 
+
136 /* 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
+
137  * two modes MOZZI_OUTPUT_PWM, and MOZZI_OUTPUT_INTERNAL_DAC (should your port happen to support these two).
+
138  *
+
139  * Keep in mind that you probably want to support MOZZI_OUTPUT_EXTERNAL_TIMED, and MOZZI_OUTPUT_EXTERNAL_CUSTOM, too, which is usually very
+
140  * 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
+
141  * timer is set up to call defaultAudioOutput() at MOZZI_AUDIO_RATE. For MOZZI_OUTPUT_EXTERNAL_CUSTOM, nothing else will be needed. */
+
142 
+
143 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_INTERNAL_DAC) // just an example!
+
144 /** 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. */
+
145 inline void audioOutput(const AudioOutput f) {
+
146  // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_1_PIN, f.l()+MOZZI_AUDIO_BIAS);
+
147 # if (MOZZI_AUDIO_CHANNELS > 1)
+
148  // e.g. analogWrite(MOZZI_AUDIO_CHANNEL_2_PIN, f.r()+MOZZI_AUDIO_BIAS);
+
149 # endif
+
150 }
+
151 #endif
+
152 
+
153 static void startAudio() {
+
154  // Add here code to get audio output going. This usually involves:
+
155  // 1) setting up some DAC mechanism (e.g. setting up a PWM pin with appropriate resolution
+
156  // 2a) setting up a timer to call defaultAudioOutput() at MOZZI_AUDIO_RATE
+
157  // OR 2b) setting up a buffered output queue such as I2S (see ESP32 / ESP8266 for examples for this setup)
+
158 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
+
159  // [...]
+
160 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
+
161  // [...]
+
162 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED)
+
163  // remember that the user may configure MOZZI_OUTPUT_EXTERNAL_TIMED, in which case, you'll want to provide step 2a), and only that.
+
164 #endif
+
165 }
+
166 
+
167 void stopMozzi() {
+
168  // Add here code to pause whatever mechanism moves audio samples to the output
+
169 }
+
170 ////// END audio output code //////
+
171 
+
172 //// BEGIN Random seeding ////////
+
173 void MozziRandPrivate::autoSeed() {
+
174  // Add here code to initialize the values of MozziRandPrivate::x, MozziRandPrivate::y, and MozziRandPrivate::z to some random values
+
175  // This doesn't need to be crypographically safe. If nothing better is available, e.g. try reading an internal temperature sensor
+
176  // in order to get some noise. It also doesn't have to be fast.
+
177  // It *should* however ensure that rand() sequences will differ across reboots, after randSeed() has been called.
+
178  // x, y, and z are already initialized to non-zero, when this function is called.
+
179  // It's ok to leave this unimplemented, initially.
+
180 #warning Automatic random seeding is not implemented on this platform
+
181 }
+
182 //// END Random seeding ////////
+
183 
+
184 } // namespace MozziPrivate
- - - + @@ -80,7 +76,7 @@
@@ -103,36 +99,424 @@
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 #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  * 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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,19 +99,76 @@
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>
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 /*
+
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
- - - + @@ -80,7 +76,7 @@
@@ -103,26 +99,146 @@
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 <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
-
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
+
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 };
- - - + @@ -80,7 +76,7 @@
@@ -103,25 +99,126 @@
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 #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  * 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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,24 +99,116 @@
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)
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
-
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
-
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,19 +99,76 @@
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
- - - + @@ -80,7 +76,7 @@
@@ -103,31 +99,250 @@
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 (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.
-
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
-
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
+
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,23 +99,143 @@
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
- - - + @@ -80,7 +76,7 @@
@@ -103,19 +99,223 @@
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
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 /*
+
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
- - - + @@ -80,7 +76,7 @@
@@ -103,24 +99,158 @@
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
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 /*
+
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
- - - + @@ -80,7 +76,7 @@
@@ -103,38 +99,337 @@
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 "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
-
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:45
-
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,21 +99,170 @@
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
- - - + @@ -80,7 +76,7 @@
@@ -103,24 +99,440 @@
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 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
-
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
-
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,20 +99,63 @@
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 };
- - - + @@ -80,7 +76,7 @@
@@ -103,26 +99,200 @@
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 (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
-
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
-
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
-
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,24 +99,140 @@
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
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
+
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
- - - + @@ -80,7 +76,7 @@
@@ -103,33 +99,204 @@
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 <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
-
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
-
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
-
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
+
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
- - - + @@ -80,7 +76,7 @@
@@ -103,21 +99,52 @@
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, 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
-
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
- - - + @@ -80,7 +76,7 @@
@@ -103,21 +99,113 @@
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_ */
- - - + @@ -80,7 +76,7 @@
@@ -104,75 +100,68 @@
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
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 NMozziPrivateInternal
 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
 CMidiToFreqPrivateInternal
 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
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,147 @@
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 # 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_ */"
+
- - - + @@ -80,7 +76,7 @@
@@ -98,21 +94,18 @@
-
+
-
Shepard_Tone_HIFI Directory Reference
+
Getting Started
-
+

You are currently looking at the Mozzi API documentation.

+

It is the most comprehensive source of all functions and classes available in Mozzi, but not necesarrily the best starting point for learning about Mozzi. For getting started, it is recommended to browse through the tutorials at https://sensorium.github.io/Mozzi/learn/ .

+
+ - - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,1220 @@
blahblah4b_int8.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_ */
- - - + @@ -80,7 +76,7 @@
@@ -102,62 +98,45 @@
-
char2mozzi.py File Reference
+
char2mozzi.py File Reference
-

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.

- - - - -

-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>="">

+

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.

-
+
+ + + +

+Functions

+def char2mozzi.char2mozzi (infile, outfile, tablename, samplerate)
 
+ - - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,58 @@
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('#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)
+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,78 @@
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('#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 
+
- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -109,11 +105,25 @@
-

A simple ADSR envelope generator. +

A simple ADSR envelope generator. More...

#include <ADSR.h>

- +

Detailed Description

+

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
+
+ + +
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().
+ + + +

Definition at line 41 of file ADSR.h.

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

Public Member Functions

@@ -121,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...
 

@@ -199,28 +209,14 @@ bool 

adsr_playing
 
-

Detailed Description

-

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
- - - -
CONTROL_UPDATE_RATEThe frequency of control updates. Ordinarily this will be 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.
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 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(), greatly reducing the amount of processing required compared to calling next() in updateAudio().
-
-
- -

Definition at line 45 of file ADSR.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

-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,10 +235,10 @@

-

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 165 of file ADSR.h.

+

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,9 +267,9 @@

-

Start the release phase of the ADSR.

+

Start the release phase of the ADSR.

-

Definition at line 192 of file ADSR.h.

+

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>
@@ -303,15 +299,15 @@

-

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).
-

Definition at line 180 of file ADSR.h.

+

Definition at line 176 of file ADSR.h.

@@ -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 @@
@@ -343,7 +339,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.

@@ -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
@@ -392,7 +388,7 @@

Definition at line 253 of file ADSR.h.

+

Definition at line 249 of file ADSR.h.

@@ -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
@@ -455,7 +451,7 @@

Definition at line 415 of file ADSR.h.

+

Definition at line 411 of file ADSR.h.

@@ -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
@@ -493,7 +489,7 @@

Definition at line 202 of file ADSR.h.

+

Definition at line 198 of file ADSR.h.

@@ -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,8 +519,8 @@

-

Set the attack time of the ADSR in milliseconds.

-

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

Parameters
+

Set the attack time of the ADSR in milliseconds.

+

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

Parameters
msecthe unsigned int attack time in milliseconds.
@@ -532,7 +528,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.

@@ -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>
@@ -562,15 +558,15 @@

-

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.
-

Definition at line 366 of file ADSR.h.

+

Definition at line 362 of file ADSR.h.

@@ -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
@@ -608,7 +604,7 @@

Definition at line 213 of file ADSR.h.

+

Definition at line 209 of file ADSR.h.

@@ -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.
- + @@ -574,15 +570,15 @@

-

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

+

Set delay time expressed in samples.

Parameters

@@ -638,8 +634,8 @@

-

Set the decay time of the ADSR in milliseconds.

-

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

Parameters
+

Set the decay time of the ADSR in milliseconds.

+

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

Parameters
msecthe unsigned int decay time in milliseconds.
@@ -647,7 +643,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.

@@ -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>
- + @@ -498,15 +494,15 @@

-

Set delay time expressed in samples.

+

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

Parameters

@@ -677,15 +673,15 @@

-

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.
-

Definition at line 376 of file ADSR.h.

+

Definition at line 372 of file ADSR.h.

@@ -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>
- + +
@@ -748,7 +744,7 @@

Definition at line 270 of file ADSR.h.

+

Definition at line 266 of file ADSR.h.

@@ -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
@@ -786,7 +782,7 @@

Definition at line 234 of file ADSR.h.

+

Definition at line 230 of file ADSR.h.

@@ -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,8 +812,8 @@

-

Set the release time of the ADSR in milliseconds.

-

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

Parameters
+

Set the release time of the ADSR in milliseconds.

+

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

Parameters
msecthe unsigned int release time in milliseconds.
@@ -825,7 +821,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.

@@ -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>
- + @@ -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,15 +851,15 @@

-

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.
-

Definition at line 396 of file ADSR.h.

+

Definition at line 392 of file ADSR.h.

@@ -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>
@@ -61,10 +57,10 @@
@@ -893,7 +889,7 @@

-

Set the sustain level of the ADSR.

+

Set the sustain level of the ADSR.

Parameters
@@ -901,7 +897,7 @@

Definition at line 224 of file ADSR.h.

+

Definition at line 220 of file ADSR.h.

@@ -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 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.
@@ -940,7 +936,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.

@@ -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>
@@ -61,10 +57,10 @@
@@ -970,15 +966,15 @@

-

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.
-

Definition at line 386 of file ADSR.h.

+

Definition at line 382 of file ADSR.h.

@@ -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>
@@ -1030,8 +1026,8 @@

-

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
+

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
@@ -1042,7 +1038,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.

@@ -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.
decay_msthe new decay time in milliseconds.
@@ -61,10 +57,10 @@
@@ -1071,23 +1067,17 @@

-

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 132 of file ADSR.h.

+

Definition at line 128 of file ADSR.h.

- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -114,13 +110,8 @@

set(unsigned int delaytime_cells)AudioDelay< NUM_BUFFER_SAMPLES, T >inline
- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -111,18 +107,21 @@ 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 >

+ +

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

@@ -130,43 +129,29 @@
 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...
 
-

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()

-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 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.
+ 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>
@@ -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 @@
@@ -365,14 +350,8 @@

-
    - - -
+ 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.png b/extras/doc/html/class_audio_delay.png deleted file mode 100644 index 4c1d909ff..000000000 Binary files a/extras/doc/html/class_audio_delay.png and /dev/null differ diff --git a/extras/doc/html/class_audio_delay_feedback-members.html b/extras/doc/html/class_audio_delay_feedback-members.html index cbd448652..4eae9545d 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 @@ - @@ -37,13 +33,13 @@

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -123,13 +119,8 @@

writeFeedback(int8_t input)AudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >inline
- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -111,7 +107,21 @@ More...

#include <AudioDelayFeedback.h>

- +

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 36 of file AudioDelayFeedback.h.

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

Public Member Functions

@@ -119,63 +129,49 @@
 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...
 
-

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 +201,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 +249,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.

@@ -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 75 of file AudioDelayFeedback.h.

+

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 92 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 117 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 186 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 196 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)
- +
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 228 of file AudioDelayFeedback.h.

@@ -539,17 +535,17 @@

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.

- -

◆ setDelayTimeCells() [3/3]

+ +

◆ setDelayTimeCells() [3/3]

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

void AudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >::setDelayTimeCells

(float uint16_t  delaytime_cells)
- +
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 204 of file AudioDelayFeedback.h.

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

Definition at line 242 of file AudioDelayFeedback.h.

+

Definition at line 238 of file AudioDelayFeedback.h.

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

Definition at line 150 of file AudioDelayFeedback.h.

+

Definition at line 146 of file AudioDelayFeedback.h.

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

Definition at line 174 of file AudioDelayFeedback.h.

+

Definition at line 170 of file AudioDelayFeedback.h.

@@ -745,20 +741,14 @@

Definition at line 162 of file AudioDelayFeedback.h.

+

Definition at line 158 of file AudioDelayFeedback.h.

- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -110,13 +106,8 @@

next()CapPoll< SENSOR_PIN, SEND_PIN >inline
- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,12 +103,19 @@
-


-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>

- +

Detailed Description

+

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.

+ +

Definition at line 23 of file CapPoll.h.

+
- +

Public Member Functions

@@ -120,19 +123,10 @@
 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...
 
-

Detailed Description

-

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.

- -

Definition at line 12 of file CapPoll.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

@@ -159,22 +153,16 @@

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.

- -

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)"/> - +
- + @@ -80,7 +76,7 @@ - -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -111,7 +107,20 @@ More...

#include <CircularBuffer.h>

- +

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 27 of file CircularBuffer.h.

+ + +

Public Member Functions

@@ -133,30 +142,14 @@
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.

-
+ - -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -106,21 +102,16 @@

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
- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,8 +103,7 @@
- - - - - - - - - - - - - - -

-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...
 
+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
@@ -154,34 +132,38 @@

Definition at line 29 of file ControlDelay.h.

-

Member Function Documentation

- -

◆ next() [1/2]

+
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

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...
 
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...
 
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]

-
-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>
@@ -61,10 +57,10 @@
- + @@ -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)
- + @@ -320,14 +306,8 @@

- + 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 a83748c2f..277da8db7 100644 Binary files a/extras/doc/html/class_control_delay.png and b/extras/doc/html/class_control_delay.png differ diff --git a/extras/doc/html/class_d_cfilter-members.html b/extras/doc/html/class_d_cfilter-members.html index 524f99ea0..ff801230c 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 @@ - @@ -37,13 +33,13 @@

@@ -61,10 +57,10 @@
void AudioDelay< NUM_BUFFER_SAMPLES, T >::set void AudioDelay< NUM_BUFFER_SAMPLES, int >::set ( unsigned int  delaytime_cells)
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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -110,13 +106,8 @@
next(int x)DCfilterinline
- -
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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,30 +103,26 @@
-


-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.

+

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.

+
- + - +

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...
 
-

Detailed Description

-


-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.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ DCfilter()

@@ -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.
@@ -209,14 +199,8 @@

-
    - - -
+ diff --git a/extras/doc/html/class_ead-members.html b/extras/doc/html/class_ead-members.html index ac1ecfb18..1bf1aedcf 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 @@ - @@ -37,13 +33,13 @@

@@ -61,10 +57,10 @@
xthe value to filter
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)"/> - +

- + @@ -80,7 +76,7 @@
@@ -115,13 +111,8 @@

start(unsigned int attack_ms, unsigned int decay_ms)Eadinline
- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -111,37 +107,37 @@ More...

#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 ?
+ +

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...
 
-

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 ?
- -

Definition at line 29 of file Ead.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Ead()

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

Parameters
- +
update_rateUsually this will be CONTROL_RATE or 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,26 +391,20 @@

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.

- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -115,13 +111,8 @@ ticks (defined in EventDelay)EventDelayprotected
- - - + @@ -80,7 +76,7 @@
@@ -120,26 +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.

+ +

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...
 

@@ -151,13 +153,7 @@ unsigned long 

ticks
 
-

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.

- -

Definition at line 20 of file EventDelay.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ EventDelay()

@@ -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.
@@ -330,14 +326,8 @@

-
    - - -
+ diff --git a/extras/doc/html/class_int_map-members.html b/extras/doc/html/class_int_map-members.html index 8142868a1..b0dee6753 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 @@ - @@ -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 @@
@@ -110,13 +106,8 @@ operator()(int n) constIntMapinline
- - - + @@ -80,7 +76,7 @@
@@ -111,22 +107,22 @@ More...

#include <IntMap.h>

- +

Detailed Description

+

A faster version of Arduino's map() function.

+

This uses ints instead of longs internally and does some of the maths at compile time.

+ +

Definition at line 19 of file IntMap.h.

+
- + - +

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...
 
-

Detailed Description

-

A faster version of Arduino's map() function.

-

This uses ints instead of longs internally and does some of the maths at compile time.

- -

Definition at line 18 of file IntMap.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ IntMap()

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

Definition at line 27 of file IntMap.h.

+

Definition at line 28 of file IntMap.h.

@@ -222,20 +218,14 @@

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.

- - - + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@ set(T startvalue, T targetvalue, T num_steps)Line< T >inline
- - - + @@ -80,7 +76,7 @@
@@ -111,47 +107,47 @@ More...

#include <Line.h>

- +

Detailed Description

+

template<class T>
+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
+
+ +
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.
+ +

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...
 
-

Detailed Description

-

template<class T>
-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
- - -
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.
- -

Definition at line 37 of file Line.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Line()

-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 47 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 58 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 73 of file Line.h.

+

Definition at line 104 of file Line.h.

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

-template<class T>
+template<class T >
@@ -339,30 +337,22 @@

-

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 85 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 102 of file Line.h.

+

Definition at line 75 of file Line.h.

- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -100,27 +96,22 @@
-
RollingStat< T, WINDOW_LENGTH > Member List
+
Line< SFix< NI, NF > > Member List
-

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

+

This is the complete list of members for Line< SFix< NI, NF > >, including all inherited members.

- - - - - - + + + + + +
getMean() constRollingStat< T, WINDOW_LENGTH >inline
getStandardDeviation() constRollingStat< T, WINDOW_LENGTH >inline
getVariance() constRollingStat< T, WINDOW_LENGTH >inline
RollingStat()RollingStat< T, WINDOW_LENGTH >inline
update(T x)RollingStat< T, WINDOW_LENGTH >inline
update(int8_t x)RollingStat< T, WINDOW_LENGTH >inline
Line()Line< SFix< NI, NF > >inline
next()Line< SFix< NI, NF > >inline
set(internal_type value)Line< SFix< NI, NF > >inline
set(internal_type targetvalue, UFix< _NI, 0 > num_steps)Line< SFix< NI, NF > >inline
set(internal_type targetvalue, T num_steps)Line< SFix< NI, NF > >inline
set(internal_type startvalue, internal_type targetvalue, T num_steps)Line< SFix< NI, NF > >inline
- - - + @@ -80,7 +76,7 @@
@@ -100,28 +96,22 @@
-
AutoMap Member List
+
Line< UFix< NI, NF > > Member List
-

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

+

This is the complete list of members for Line< UFix< NI, NF > >, including all inherited members.

- - - - - - - + + + + + +
AutoMap(int min_expected, int max_expected, int map_to_min, int map_to_max)AutoMapinline
AutoRange(int min_expected, int max_expected)AutoRange< int >inline
getMax()AutoRange< int >inline
getMin()AutoRange< int >inline
getRange()AutoRange< int >inline
next(int n)AutoMapinline
operator()(int n)AutoMapinline
Line()Line< UFix< NI, NF > >inline
next()Line< UFix< NI, NF > >inline
set(internal_type value)Line< UFix< NI, NF > >inline
set(internal_type targetvalue, UFix< _NI, 0 > num_steps)Line< UFix< NI, NF > >inline
set(internal_type targetvalue, T num_steps)Line< UFix< NI, NF > >inline
set(internal_type startvalue, internal_type targetvalue, T num_steps)Line< UFix< NI, NF > >inline
- - - + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@ set(unsigned char startvalue, unsigned char targetvalue, unsigned char num_steps)Line< unsigned char >inline
- - - + @@ -80,7 +76,7 @@
-
Line< unsigned char > Class Template Reference
+
Line< unsigned char > Class Reference
- +

Detailed Description

+
+

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...
 
-

Detailed Description

-

template<>
-class Line< unsigned char >

- - -

Definition at line 112 of file Line.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Line()

@@ -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 122 of file Line.h.

+

Definition at line 124 of file Line.h.

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

Returns
the next value.

-

Definition at line 133 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 147 of file Line.h.

+

Definition at line 172 of file Line.h.

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

Definition at line 159 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, - - - - - unsigned char  - num_steps  - - + value) - ) - @@ -316,30 +311,22 @@

-

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 170 of file Line.h.

+

Definition at line 149 of file Line.h.

- - - + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@ set(unsigned int startvalue, unsigned int targetvalue, unsigned int num_steps)Line< unsigned int >inline
- - - + @@ -80,7 +76,7 @@
-
Line< unsigned int > Class Template Reference
+
Line< unsigned int > Class Reference
- +

Detailed Description

+
+

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...
 
-

Detailed Description

-

template<>
-class Line< unsigned int >

- - -

Definition at line 181 of file Line.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Line()

@@ -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 191 of file Line.h.

+

Definition at line 193 of file Line.h.

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

Returns
the next value.
-

Definition at line 202 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 216 of file Line.h.

+

Definition at line 242 of file Line.h.

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

Definition at line 228 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, - - - - - unsigned int  - num_steps  - - + value) - ) - @@ -316,30 +311,22 @@

-

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 240 of file Line.h.

+

Definition at line 218 of file Line.h.

- - - + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@ set(unsigned long startvalue, unsigned long targetvalue, unsigned long num_steps)Line< unsigned long >inline
- - - + @@ -80,7 +76,7 @@
-
Line< unsigned long > Class Template Reference
+
Line< unsigned long > Class Reference
- +

Detailed Description

+
+

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...
 
-

Detailed Description

-

template<>
-class Line< unsigned long >

- - -

Definition at line 253 of file Line.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Line()

@@ -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 263 of file Line.h.

+

Definition at line 265 of file Line.h.

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

Returns
the next value.
-

Definition at line 274 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 288 of file Line.h.

+

Definition at line 313 of file Line.h.

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

Definition at line 300 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, - - - - - unsigned long  - num_steps  - - + value) - ) - @@ -316,30 +311,22 @@

-

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 311 of file Line.h.

+

Definition at line 290 of file Line.h.

- - - + @@ -80,7 +76,7 @@
@@ -128,13 +124,8 @@ setTable(const int8_t *TABLE_NAME, byte rank)MetaOscil< NUM_TABLE_CELLS, UPDATE_RATE, N_OSCIL >inline
- - - + @@ -80,7 +76,7 @@
@@ -107,83 +103,83 @@
-

MetaOscil is a wrapper for several Oscil. +

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

#include <MetaOscil.h>

- +

Detailed Description

+

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.

+ +

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...
 
-

Detailed Description

-

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.

- -

Definition at line 29 of file MetaOscil.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ MetaOscil()

@@ -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 36 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 201 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 112 of file MetaOscil.h.

+

Definition at line 114 of file MetaOscil.h.

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

Returns
the next sample.
-

Definition at line 91 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 208 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 123 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 82 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 69 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 101 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 106 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 214 of file MetaOscil.h.

+

Definition at line 216 of file MetaOscil.h.

@@ -877,29 +873,23 @@

-

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 96 of file MetaOscil.h.

+

Definition at line 98 of file MetaOscil.h.

- - - + @@ -80,7 +76,7 @@
@@ -118,13 +114,8 @@ ticks (defined in EventDelay)EventDelayprotected
- - - + @@ -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,32 +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.

+ +

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...
 

@@ -157,13 +159,7 @@ unsigned long 

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()

@@ -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,20 +361,14 @@

Definition at line 51 of file Metronome.h.

+

Definition at line 52 of file Metronome.h.

- - - + @@ -80,7 +76,7 @@
@@ -100,24 +96,21 @@
-
RollingAverage< T, WINDOW_LENGTH > Member List
+
MidiToFreqPrivate Member List
-

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

+

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

- - - + + + + +
add(T input) (defined in RollingAverage< T, WINDOW_LENGTH >)RollingAverage< T, WINDOW_LENGTH >inlineprotected
next(T input)RollingAverage< T, WINDOW_LENGTH >inline
RollingAverage()RollingAverage< T, WINDOW_LENGTH >inline
mtof(uint8_t)MidiToFreqPrivatefriend
mtof(int)MidiToFreqPrivatefriend
mtof(UFix< NI, 0, RANGE >)MidiToFreqPrivatefriend
mtof(SFix< NI, 0, RANGE >)MidiToFreqPrivatefriend
Q16n16_mtof(Q16n16)MidiToFreqPrivatefriend
- - - + @@ -80,7 +76,7 @@
@@ -100,26 +96,21 @@
-
AutoRange< T > Member List
+
MozziPrivate::MidiToFreq Member List
-

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

+

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

- - - - - + + + + +
AutoRange(T min_expected, T max_expected)AutoRange< T >inline
getMax()AutoRange< T >inline
getMin()AutoRange< T >inline
getRange()AutoRange< T >inline
next(T n)AutoRange< T >inline
mtof(uint8_t)MozziPrivate::MidiToFreqfriend
mtof(int)MozziPrivate::MidiToFreqfriend
mtof(UFix< NI, 0, RANGE >)MozziPrivate::MidiToFreqfriend
mtof(SFix< NI, 0, RANGE >)MozziPrivate::MidiToFreqfriend
Q16n16_mtof(Q16n16)MozziPrivate::MidiToFreqfriend
- - - + @@ -80,7 +76,7 @@
@@ -106,40 +102,35 @@

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
- - - + @@ -80,7 +76,7 @@
@@ -121,36 +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.

+ +

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 

@@ -171,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  @@ -204,18 +207,10 @@ 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
 
-

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()

@@ -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 (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.
-

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 (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,26 +489,20 @@

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.

- - - + @@ -80,7 +76,7 @@
@@ -107,29 +103,30 @@

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, 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, 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
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
- - - + @@ -80,7 +76,7 @@
@@ -107,80 +103,101 @@
-


-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>

- +

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 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

+ +

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 (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...
 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...
 
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, 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...
 
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...
 
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...
 
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]

@@ -210,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 72 of file Oscil.h.

+

Definition at line 71 of file Oscil.h.

@@ -245,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 82 of file Oscil.h.

+

Definition at line 81 of file Oscil.h.

@@ -287,12 +304,12 @@

Returns
the sample at the given table index.
-

Definition at line 245 of file Oscil.h.

+

Definition at line 333 of file Oscil.h.

- -

◆ getPhaseFractional()

+ +

◆ getPhaseFractional()

@@ -303,7 +320,7 @@

- + @@ -316,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 132 of file Oscil.h.

+

Definition at line 131 of file Oscil.h.

@@ -351,12 +368,12 @@

Returns
the next sample.
-

Definition at line 90 of file Oscil.h.

+

Definition at line 89 of file Oscil.h.

- -

◆ phaseIncFromFreq()

+ +

◆ phaseIncFromFreq()

@@ -367,7 +384,7 @@

unsigned long Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::getPhaseFractional uint32_t Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::getPhaseFractional ( )
- + @@ -381,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

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 +407,12 @@

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

Definition at line 262 of file Oscil.h.

+

Definition at line 350 of file Oscil.h.

-

◆ phMod()

+

◆ phMod() [1/3]

@@ -429,12 +446,130 @@

Returns
a sample from the table.
-

Definition at line 150 of file Oscil.h.

+

Definition at line 149 of file Oscil.h.

+ +

+
+ +

◆ phMod() [2/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 178 of file Oscil.h.

+ +
+
+ +

◆ phMod() [3/3]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<int8_t NI, int8_t NF, uint8_t RANGE>
+ + + + + +
+ + + + + + + + +
int8_t Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::phMod (SFix< NI, NF, RANGE > 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 164 of file Oscil.h.

+ +
+
+ +

◆ setFreq() [1/6]

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

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 207 of file Oscil.h.

-

◆ setFreq() [1/2]

+

◆ setFreq() [2/6]

@@ -460,24 +595,26 @@

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
+

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 165 of file Oscil.h.

+

Definition at line 192 of file Oscil.h.

- -

◆ setFreq() [2/2]

+ +

◆ setFreq() [3/6]

template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<int8_t NI, int8_t NF, uint64_t RANGE>
- + @@ -497,15 +634,144 @@

-

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 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

@@ -485,7 +622,7 @@

void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq

(float SFix< NI, NF, RANGE >  frequency)
- + +
frequencyto play the wave table.
frequencyin SFix<16,16> fixed-point number format.
+ + + +

Definition at line 316 of file Oscil.h.

+ +
+
+ +

◆ setFreq() [4/6]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<uint64_t RANGE>
+ + + + + +
+ + + + + + + + +
void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq (UFix< 16, 16, RANGE > 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 301 of file Oscil.h.

+ +
+
+ +

◆ setFreq() [5/6]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<uint64_t RANGE>
+ + + + + +
+ + + + + + + + +
void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq (UFix< 24, 8, RANGE > 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 261 of file Oscil.h.

+ +
+
+ +

◆ setFreq() [6/6]

+ +
+
+
+template<uint16_t NUM_TABLE_CELLS, uint16_t UPDATE_RATE>
+
+template<int8_t NI, int8_t NF, uint64_t RANGE>
+ + + + + +
+ + + + + + + + +
void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setFreq (UFix< NI, NF, RANGE > 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 180 of file Oscil.h.

+

Definition at line 221 of file Oscil.h.

@@ -536,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
@@ -546,7 +812,7 @@

Definition at line 220 of file Oscil.h.

+

Definition at line 276 of file Oscil.h.

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

Definition at line 194 of file Oscil.h.

+

Definition at line 236 of file Oscil.h.

@@ -614,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
@@ -622,12 +888,12 @@

Definition at line 112 of file Oscil.h.

+

Definition at line 111 of file Oscil.h.

- -

◆ setPhaseFractional()

+ +

◆ setPhaseFractional()

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

void Oscil< NUM_TABLE_CELLS, UPDATE_RATE >::setPhaseFractional

- + @@ -652,20 +918,20 @@

-

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.
(unsigned long uint32_t  phase)
phasea position in the wavetable.
-

Definition at line 123 of file Oscil.h.

+

Definition at line 122 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 363 of file Oscil.h.

@@ -728,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
@@ -736,20 +1002,14 @@

Definition at line 100 of file Oscil.h.

+

Definition at line 99 of file Oscil.h.

- -

TABLE_NAMEis the name of the array in the table ".h" file you're using.
- - - - - - - -
-
Mozzi -  version v1.1.0 -
-
sound synthesis library for Arduino
-
- - - - - - -
-
- - - - - -
- -
-
-
- -
- -
-
- - -
- -
- -
- -
-
OverSample< T, RESOLUTION_INCREASE_BITS > Class Template Reference
-
-
- -

Enables the resolution of analog inputs to be increased by oversampling and decimation. - More...

- -

#include <OverSample.h>

-
- + Inheritance diagram for OverSample< T, RESOLUTION_INCREASE_BITS >:
-
-
- - - - - - -

-Public Member Functions

next (T input)
 Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;. More...
 
- - - -

-Protected Member Functions

-T add (T input)
 
-

Detailed Description

-

template<class T, const uint8_t RESOLUTION_INCREASE_BITS>
-class OverSample< T, RESOLUTION_INCREASE_BITS >

- -

Enables the resolution of analog inputs to be increased by oversampling and decimation.

-

Noise should be added to the input before it's digitised, then a succession of input readings are summed and finally divided to give a number with greater resolution than the ADC.
-Often, noise in the Arduino system will be enough, but there are other practical methods described in Enhancing ADC Resolution by Oversampling, as well as an explanation of the overall approach.

Template Parameters
- - -
RESOLUTION_INCREASE_BITShow many extra bits of resolution to produce. The window length and the memory it needs increases quickly as the oversampling resolution increases.
-1 bit = 4 unsigned ints (analog input between 0-1023) = 8 uint8_ts, 2 bits = 16 unsigned ints = 32 uint8_ts,
-3 bits = 64 unsigned ints = 128 uint8_ts, More than 3 bits increase in resolution would require either using longs to store the readings, 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?), or the average reading would have to be no more than 128 (for 4 bits increase), because 256 readings would be needed, and the sum of all 256 readings would have to fit into an int. (32767 / 256 = 128). Changing OverSample to use unsigned ints could enable an average reading of 256, but isn't tested properly yet.
-
-
-
Note
The higher the resolution, the more lag there will be. It's almost a RollingAverage filter, with the difference that OverSample doesn't divide by as much as you would for an average.
- -

Definition at line 42 of file OverSample.h.

-

Member Function Documentation

- -

◆ next()

- -
-
-
-template<class T , const uint8_t RESOLUTION_INCREASE_BITS>
- - - - - -
- - - - - - - - -
T OverSample< T, RESOLUTION_INCREASE_BITS >::next (input)
-
-inline
-
- -

Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;.

-
Parameters
- - -
inputan analog input to oversample.
-
-
-
Returns
the higher resolution result.
-
Note
timing 5.7us
- -

Definition at line 53 of file OverSample.h.

- -
-
-
-
- - - - diff --git a/extras/doc/html/class_over_sample.js b/extras/doc/html/class_over_sample.js deleted file mode 100644 index 0f1026db1..000000000 --- a/extras/doc/html/class_over_sample.js +++ /dev/null @@ -1,5 +0,0 @@ -var class_over_sample = -[ - [ "add", "class_over_sample.html#a9c9f4083b726ed046c97a91535486317", null ], - [ "next", "class_over_sample.html#a413ca7de0dbf3d2afafd84aa75857442", null ] -]; \ No newline at end of file diff --git a/extras/doc/html/class_over_sample.png b/extras/doc/html/class_over_sample.png deleted file mode 100644 index ec0853c92..000000000 Binary files a/extras/doc/html/class_over_sample.png and /dev/null differ diff --git a/extras/doc/html/class_p_d_resonant-members.html b/extras/doc/html/class_p_d_resonant-members.html index 7c13a10b5..cda9f8696 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 @@ - @@ -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 @@
@@ -114,13 +110,8 @@ update()PDResonantinline
- - - + @@ -80,7 +76,7 @@
@@ -107,11 +103,16 @@
-

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.

+ +

Definition at line 31 of file PDResonant.h.

+
- + - + - + - + - +

Public Member Functions

@@ -119,27 +120,22 @@
 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...
 
-

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.

- -

Definition at line 33 of file PDResonant.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

@@ -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,22 +345,16 @@

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.

- - - + @@ -80,7 +76,7 @@
@@ -115,13 +111,8 @@ setPhaseInc(uint32_t stepsize)Phasor< UPDATE_RATE >inline
- - - + @@ -80,7 +76,7 @@
@@ -107,49 +103,49 @@
-

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>

- +

Detailed Description

+

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
+
+ +
UPDATE_RATEthe rate at which the Phasor will be updated, usually MOZZI_CONTROL_RATE or MOZZI_AUDIO_RATE.
+

+
+ +

Definition at line 28 of file Phasor.h.

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

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...
 
-

Detailed Description

-

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
- - -
UPDATE_RATEthe rate at which the Phasor will be updated, usually CONTROL_RATE or AUDIO_RATE.
-
-
- -

Definition at line 32 of file Phasor.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Phasor()

@@ -176,9 +172,9 @@

Constructor.

-

"Phasor <AUDIO_RATE> myphasor;" makes a Phasor which updates at AUDIO_RATE.

+

"Phasor <MOZZI_AUDIO_RATE> myphasor;" makes a Phasor which updates at MOZZI_AUDIO_RATE.

-

Definition at line 42 of file Phasor.h.

+

Definition at line 38 of file Phasor.h.

@@ -211,7 +207,7 @@

Returns
the next value.

-

Definition at line 50 of file Phasor.h.

+

Definition at line 46 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.
@@ -250,7 +246,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.

@@ -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 60 of file Phasor.h.

+

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 72 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 83 of file Phasor.h.

+

Definition at line 68 of file Phasor.h.

@@ -391,27 +387,21 @@

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().
-

Definition at line 108 of file Phasor.h.

+

Definition at line 104 of file Phasor.h.

- - - + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@ start(Q16n16 note)Portamento< CONTROL_UPDATE_RATE >inline
- - - + @@ -80,7 +76,7 @@
@@ -111,7 +107,14 @@ More...

#include <Portamento.h>

- +

Detailed Description

+

template<unsigned int CONTROL_UPDATE_RATE>
+class Portamento< CONTROL_UPDATE_RATE >

+ +

A simple portamento (pitch slide from one note to the next) effect, useful for note-based applications.

+ +

Definition at line 22 of file Portamento.h.

+
- + - + - + - +

Public Member Functions

@@ -119,26 +122,19 @@
 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...
 
-

Detailed Description

-

template<unsigned int CONTROL_UPDATE_RATE>
-class Portamento< CONTROL_UPDATE_RATE >

- -

A simple portamento (pitch slide from one note to the next) effect, useful for note-based applications.

- -

Definition at line 22 of file Portamento.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

@@ -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.

- - - + @@ -80,7 +76,7 @@
@@ -110,13 +106,8 @@ RCpoll()RCpoll< SENSOR_PIN >inline
- - - + @@ -80,7 +76,7 @@
@@ -107,12 +103,19 @@
-


-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>

- +

Detailed Description

+

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.

+ +

Definition at line 23 of file RCpoll.h.

+
- +

Public Member Functions

@@ -120,19 +123,10 @@
 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...
 
-

Detailed Description

-

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.

- -

Definition at line 12 of file RCpoll.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

@@ -159,22 +153,16 @@

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.

- - - + @@ -80,7 +76,7 @@
@@ -129,13 +125,8 @@ ucfxmul(su a, typename IntegerType< sizeof(su)+sizeof(su)>::unsigned_type b) (defined in ResonantFilter< FILTER_TYPE, su >)ResonantFilter< FILTER_TYPE, su >inlineprotected
- - - + @@ -80,7 +76,7 @@
@@ -113,7 +109,14 @@ More...

#include <ResonantFilter.h>

- +

Detailed Description

+

template<int8_t FILTER_TYPE, typename su = uint8_t>
+class ResonantFilter< FILTER_TYPE, su >

+ +

A generic resonant filter for audio signals.

+ +

Definition at line 75 of file ResonantFilter.h.

+
- + - + - + - +

Public Member Functions

@@ -121,17 +124,16 @@
 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...
 
+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 

@@ -152,13 +154,13 @@ 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 (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  @@ -179,30 +181,23 @@ AudioOutputStorage_t  +const uint8_t  +const uint8_t  +const su 

@@ -170,7 +172,7 @@ su 

f
 
-IntegerType< sizeof(su)+sizeof(su)>::unsigned_type fb
fb
 
AudioOutputStorage_t buf0
buf1
 
-const uint8_t FX_SHIFT = sizeof(su) << 3
FX_SHIFT
 
-const uint8_t FX_SHIFT_M_1 = FX_SHIFT-1
FX_SHIFT_M_1
 
-const su SHIFTED_1 = (1<<FX_SHIFT)-1
SHIFTED_1
 
-

Detailed Description

-

template<int8_t FILTER_TYPE, typename su = uint8_t>
-class ResonantFilter< FILTER_TYPE, su >

- -

A generic resonant filter for audio signals.

- -

Definition at line 76 of file ResonantFilter.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

-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>
@@ -61,10 +57,10 @@
@@ -266,12 +261,12 @@

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.
-

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>
@@ -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 (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,26 +349,20 @@

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.

- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@

setLoopDelays(int8_t loop1_delay, uint8_t loop2_delay)ReverbTankinline
- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -107,39 +103,37 @@
-


-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.

+

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.

+ +

Definition at line 32 of file ReverbTank.h.

+
- + - + - + - + - +

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...
 
-

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.

-

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.

- -

Definition at line 32 of file ReverbTank.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ ReverbTank()

@@ -392,14 +386,8 @@

-
    - - -
+ diff --git a/extras/doc/html/class_rolling_average.html b/extras/doc/html/class_rolling_average.html deleted file mode 100644 index 6af7a6380..000000000 --- a/extras/doc/html/class_rolling_average.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - - -Mozzi: RollingAverage< T, WINDOW_LENGTH > Class Template Reference - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
-
Mozzi -  version v1.1.0 -
-
sound synthesis library for Arduino
-
- - - - - - -
-
-
- - - -
-
- -
-
-
- -
- -
-
- - -
- -
- -
- -
-
RollingAverage< T, WINDOW_LENGTH > Class Template Reference
-
-
- -

Calculates a running average over a specified number of the most recent readings. - More...

- -

#include <RollingAverage.h>

- - - - - - - - -

-Public Member Functions

 RollingAverage ()
 Constructor. More...
 
next (T input)
 Give the average of the last WINDOW_LENGTH. More...
 
- - - -

-Protected Member Functions

-T add (T input)
 
-

Detailed Description

-

template<class T, int WINDOW_LENGTH>
-class RollingAverage< T, WINDOW_LENGTH >

- -

Calculates a running average over a specified number of the most recent readings.

-

Like Smooth(), this is good for smoothing analog inputs in updateControl().

Template Parameters
- - -
WINDOW_LENGTHthe number of readings to include in the rolling average. It must be a power of two (unless you're averaging floats). The higher the number, the more the readings will be smoothed, but the slower the output will respond to the input.
-
-
- -

Definition at line 37 of file RollingAverage.h.

-

Constructor & Destructor Documentation

- -

◆ RollingAverage()

- -
-
-
-template<class T, int WINDOW_LENGTH>
- - - - - -
- - - - - - - -
RollingAverage< T, WINDOW_LENGTH >::RollingAverage ()
-
-inline
-
- -

Constructor.

-
Template Parameters
- - - -
Tthe type of numbers to average, eg. int, unsigned int, float etc. It will be relatively slow with floating point numbers, as it will use a divide operation for the averaging. Nevertheless, there might be a time when it's useful.
WINDOW_LENGTHthe number of readings to keep track of. It must be a power of two (unless you're averaging floats). The higher the number, the more the readings will be smoothed, but the slower the output will respond to the input.
-
-
-
Note
Watch out for overflows!
- -

Definition at line 51 of file RollingAverage.h.

- -
-
-

Member Function Documentation

- -

◆ next()

- -
-
-
-template<class T, int WINDOW_LENGTH>
- - - - - -
- - - - - - - - -
T RollingAverage< T, WINDOW_LENGTH >::next (input)
-
-inline
-
- -

Give the average of the last WINDOW_LENGTH.

-
Parameters
- - -
inputa control signal such as an analog input which needs smoothing.
-
-
-
Returns
the smoothed result.
-
Note
unsigned int timing 5.7us
- -

Definition at line 64 of file RollingAverage.h.

- -
-
-
-
- - - - diff --git a/extras/doc/html/class_rolling_average.js b/extras/doc/html/class_rolling_average.js deleted file mode 100644 index 1b9015f38..000000000 --- a/extras/doc/html/class_rolling_average.js +++ /dev/null @@ -1,6 +0,0 @@ -var class_rolling_average = -[ - [ "RollingAverage", "class_rolling_average.html#a11cf7b9e1278648b1eb10e5534fe3e29", null ], - [ "add", "class_rolling_average.html#a9c9f4083b726ed046c97a91535486317", null ], - [ "next", "class_rolling_average.html#a23c4b93258faace0c7ee60eb395d2c4b", null ] -]; \ No newline at end of file diff --git a/extras/doc/html/class_rolling_stat.html b/extras/doc/html/class_rolling_stat.html deleted file mode 100644 index 730fc1975..000000000 --- a/extras/doc/html/class_rolling_stat.html +++ /dev/null @@ -1,338 +0,0 @@ - - - - - - - -Mozzi: RollingStat< T, WINDOW_LENGTH > Class Template Reference - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
-
Mozzi -  version v1.1.0 -
-
sound synthesis library for Arduino
-
- - - - - - -
-
-
- - - -
-
- -
-
-
- -
- -
-
- - -
- -
- -
- -
-
RollingStat< T, WINDOW_LENGTH > Class Template Reference
-
-
- -

WARNING: this class is work in progress, don't use it yet. - More...

- -

#include <RollingStat.h>

- - - - - - - - - - - - - - - - - - - - -

-Public Member Functions

RollingStat ()
 Constructor.
 
void update (T x)
 Update the mean and variance given a new input value. More...
 
void update (int8_t x)
 Update the mean and variance given a new input value. More...
 
getMean () const
 Return the mean of the last WINDOW_LENGTH number of inputs. More...
 
getVariance () const
 Return the approximate variance of the last WINDOW_LENGTH number of inputs. More...
 
getStandardDeviation () const
 Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs. More...
 
-

Detailed Description

-

template<class T, int WINDOW_LENGTH>
-class RollingStat< T, WINDOW_LENGTH >

- -

WARNING: this class is work in progress, don't use it yet.

-

Calculates an approximation of the variance and standard deviation for a window of recent inputs.

Template Parameters
- - - -
Tthe type of numbers to use. Choose unsigned int, int , uint8_t, int8_t, or float
WINDOW_LENGTHhow many recent input values to include in the calculations.
-
-
- -

Definition at line 28 of file RollingStat.h.

-

Member Function Documentation

- -

◆ getMean()

- -
-
-
-template<class T , int WINDOW_LENGTH>
- - - - - -
- - - - - - - -
T RollingStat< T, WINDOW_LENGTH >::getMean () const
-
-inline
-
- -

Return the mean of the last WINDOW_LENGTH number of inputs.

-
Returns
mean
- -

Definition at line 61 of file RollingStat.h.

- -
-
- -

◆ getStandardDeviation()

- -
-
-
-template<class T , int WINDOW_LENGTH>
- - - - - -
- - - - - - - -
T RollingStat< T, WINDOW_LENGTH >::getStandardDeviation () const
-
-inline
-
- -

Return the approximate standard deviation of the last WINDOW_LENGTH number of inputs.

-
Returns
standard deviation.
- -

Definition at line 78 of file RollingStat.h.

- -
-
- -

◆ getVariance()

- -
-
-
-template<class T , int WINDOW_LENGTH>
- - - - - -
- - - - - - - -
T RollingStat< T, WINDOW_LENGTH >::getVariance () const
-
-inline
-
- -

Return the approximate variance of the last WINDOW_LENGTH number of inputs.

-
Returns
variance
-
Note
This should really be calculated using WINDOW_LENGTH-1, but sacrificing accuracy for speed we use the power of two value of WINDOW_LENGTH.
- -

Definition at line 71 of file RollingStat.h.

- -
-
- -

◆ update() [1/2]

- -
-
-
-template<class T , int WINDOW_LENGTH>
- - - - - -
- - - - - - - - -
void RollingStat< T, WINDOW_LENGTH >::update (x)
-
-inline
-
- -

Update the mean and variance given a new input value.

-
Parameters
- - -
xthe next input value
-
-
-
Note
timing for unsigned int 10us, int 22us
- -

Definition at line 41 of file RollingStat.h.

- -
-
- -

◆ update() [2/2]

- -
-
-
-template<class T , int WINDOW_LENGTH>
- - - - - -
- - - - - - - - -
void RollingStat< T, WINDOW_LENGTH >::update (int8_t x)
-
-inline
-
- -

Update the mean and variance given a new input value.

-
Parameters
- - -
xthe next input value
-
-
- -

Definition at line 51 of file RollingStat.h.

- -
-
-
-
- - - - diff --git a/extras/doc/html/class_rolling_stat.js b/extras/doc/html/class_rolling_stat.js deleted file mode 100644 index 8e0bcfed3..000000000 --- a/extras/doc/html/class_rolling_stat.js +++ /dev/null @@ -1,9 +0,0 @@ -var class_rolling_stat = -[ - [ "RollingStat", "class_rolling_stat.html#a98c3f767391db80b8ad59ca53c1e6a94", null ], - [ "getMean", "class_rolling_stat.html#a8521a53cde7c5d28ac9c375aaee3a972", null ], - [ "getStandardDeviation", "class_rolling_stat.html#a234ab1d244e4b392056fcaa1fc1e4fc4", null ], - [ "getVariance", "class_rolling_stat.html#a3e7e5f706e3b5ac2496f14b7b639775d", null ], - [ "update", "class_rolling_stat.html#a85750e78ac282caec24408dce6e78201", null ], - [ "update", "class_rolling_stat.html#a6f7b384ab338da5ba10200fbce7f2eb0", null ] -]; \ No newline at end of file diff --git a/extras/doc/html/class_sample-members.html b/extras/doc/html/class_sample-members.html index 5d28bfcc4..81aa7de62 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 @@ - @@ -37,13 +33,13 @@

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)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -126,13 +122,8 @@ start(unsigned int startpos)Sample< NUM_TABLE_CELLS, UPDATE_RATE, INTERP >inline
- - - + @@ -80,7 +76,7 @@
@@ -107,34 +103,51 @@
-

Sample is like Oscil, it plays a wavetable. +

Sample is like Oscil, it plays a wavetable. More...

#include <Sample.h>

- +

Detailed Description

+

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
+
+ + +
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.
+ + +

+int8_t2mozzi

+

Converting soundfiles for Mozzi. There is a python script called int8_t2mozzi.py in the Mozzi/python folder. The script converts raw sound data saved from a program like Audacity. Instructions are in the int8_t2mozzi.py file.

+ +

Definition at line 48 of file Sample.h.

+
- + - + - + - + - + - + - + @@ -149,49 +162,31 @@ - + - + - + - + - + - + - + - +

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 ()
 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...
 
-

Detailed Description

-

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
- - - -
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 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 of cyclic updating in updateControl(), for example, to spread out the processor load.
-
-
-

-int8_t2mozzi

-

Converting soundfiles for Mozzi. There is a python script called int8_t2mozzi.py in the Mozzi/python folder. The script converts raw sound data saved from a program like Audacity. Instructions are in the int8_t2mozzi.py file.

- -

Definition at line 48 of file Sample.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ Sample() [1/2]

@@ -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
@@ -712,14 +706,8 @@

-
    - - -
+ 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 aa42f88df..1b5ed120d 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 @@ - @@ -37,13 +33,13 @@

@@ -61,10 +57,10 @@
TABLE_NAMEis the name of the array in the table ".h" file you're using.
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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@ start()SampleHuffmaninline
- - - + @@ -80,7 +76,7 @@
@@ -111,14 +107,26 @@ More...

#include <SampleHuffman.h>

- +

Detailed Description

+

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.

+

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 50 of file SampleHuffman.h.

+
- + - + @@ -133,19 +141,7 @@

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 ()
 Sets the playhead to the beginning of the sample.
 
-

Detailed Description

-

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.

-

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.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ SampleHuffman()

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

Definition at line 59 of file SampleHuffman.h.

+

Definition at line 60 of file SampleHuffman.h.

@@ -228,20 +224,14 @@

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.

- - - + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@ Smooth()Smooth< T >inline
- - - + @@ -80,7 +76,7 @@
@@ -111,31 +107,12 @@ More...

#include <Smooth.h>

- - - - - - - - - - - - - - - - - -

-Public Member Functions

 Smooth (float smoothness)
 Constructor. More...
 
 Smooth ()
 Constructor. More...
 
next (T in)
 Filters the input and returns the filtered value. More...
 
operator() (T n)
 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...
 

Detailed Description

template<class T>
class Smooth< T >

A simple infinite impulse response low pass filter for smoothing control or audio signals.

-

This algorithm comes from http://en.wikipedia.org/wiki/Low-pass_filter: 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 value to suit.

Template Parameters
+

This algorithm comes from http://en.wikipedia.org/wiki/Low-pass_filter: 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 MOZZI_CONTROL_RATE and you change MOZZI_CONTROL_RATE, you'll need to adjust the smoothness value to suit.

Template Parameters
Tthe type of numbers being smoothed. Watch out for numbers overflowing the internal calculations. Some experimentation is recommended.
@@ -144,7 +121,26 @@
Note
Timing: ~5us for 16 bit types, ~1us for 8 bit types.

Definition at line 35 of file Smooth.h.

-

Constructor & Destructor Documentation

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

+Public Member Functions

 Smooth (float smoothness)
 Constructor. More...
 
 Smooth ()
 Constructor. More...
 
next (T in)
 Filters the input and returns the filtered value. More...
 
operator() (T n)
 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...
 
+

Constructor & Destructor Documentation

◆ Smooth() [1/2]

@@ -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.

@@ -334,14 +330,8 @@

-
    - - -
+ diff --git a/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4-members.html b/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4-members.html new file mode 100644 index 000000000..b553852e1 --- /dev/null +++ b/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4-members.html @@ -0,0 +1,117 @@ + + + + + + + +Mozzi: Member List + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
Mozzi +  version v2.0 +
+
sound synthesis library for Arduino
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Smooth< SFix< NI, NF > > Member List
+
+
+ +

This is the complete list of members for Smooth< SFix< NI, NF > >, including all inherited members.

+ + + + + + + +
next(internal_type in)Smooth< SFix< NI, NF > >inline
operator()(internal_type n) (defined in Smooth< SFix< NI, NF > >)Smooth< SFix< NI, NF > >inline
setSmoothness(float smoothness)Smooth< SFix< NI, NF > >inline
setSmoothness(UFix< 0, _NF > smoothness)Smooth< SFix< NI, NF > >inline
Smooth(T smoothness)Smooth< SFix< NI, NF > >inline
Smooth()Smooth< SFix< NI, NF > >inline
+
+ + + diff --git a/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html b/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html new file mode 100644 index 000000000..36b2fd858 --- /dev/null +++ b/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html @@ -0,0 +1,332 @@ + + + + + + + +Mozzi: Smooth< SFix< NI, NF > > Class Template Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
Mozzi +  version v2.0 +
+
sound synthesis library for Arduino
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
Smooth< SFix< NI, NF > > Class Template Reference
+
+
+

Detailed Description

+

template<int8_t NI, int8_t NF>
+class Smooth< SFix< NI, NF > >

+ + +

Definition at line 352 of file Smooth.h.

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

+Public Member Functions

template<typename T >
 Smooth (T smoothness)
 Constructor. More...
 
 Smooth ()
 Constructor. More...
 
internal_type next (internal_type in)
 Filters the input and returns the filtered value. More...
 
+internal_type operator() (internal_type n)
 
void setSmoothness (float smoothness)
 Sets how much smoothing the filter will apply to its input. More...
 
template<int8_t _NF>
void setSmoothness (UFix< 0, _NF > smoothness)
 Sets how much smoothing the filter will apply to its input. More...
 
+

Constructor & Destructor Documentation

+ +

◆ Smooth() [1/2]

+ +
+
+
+template<int8_t NI, int8_t NF>
+
+template<typename T >
+ + + + + +
+ + + + + + + + +
Smooth< SFix< NI, NF > >::Smooth (smoothness)
+
+inline
+
+ +

Constructor.

+
Parameters
+ + +
smoothnesssets 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.
+
+
+ +

Definition at line 368 of file Smooth.h.

+ +
+
+ +

◆ Smooth() [2/2]

+ +
+
+
+template<int8_t NI, int8_t NF>
+ + + + + +
+ + + + + + + +
Smooth< SFix< NI, NF > >::Smooth ()
+
+inline
+
+ +

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...
+ +

Definition at line 378 of file Smooth.h.

+ +
+
+

Member Function Documentation

+ +

◆ next()

+ +
+
+
+template<int8_t NI, int8_t NF>
+ + + + + +
+ + + + + + + + +
internal_type Smooth< SFix< NI, NF > >::next (internal_type in)
+
+inline
+
+ +

Filters the input and returns the filtered value.

+

You can also use the operator() function, eg. something like mySmoother(input-value).

Parameters
+ + +
inthe signal to be smoothed.
+
+
+
Returns
the filtered signal.
+ +

Definition at line 387 of file Smooth.h.

+ +
+
+ +

◆ setSmoothness() [1/2]

+ +
+
+
+template<int8_t NI, int8_t NF>
+ + + + + +
+ + + + + + + + +
void Smooth< SFix< NI, NF > >::setSmoothness (float smoothness)
+
+inline
+
+ +

Sets how much smoothing the filter will apply to its input.

+
Parameters
+ + +
smoothnesssets 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.
+
+
+ +

Definition at line 407 of file Smooth.h.

+ +
+
+ +

◆ setSmoothness() [2/2]

+ +
+
+
+template<int8_t NI, int8_t NF>
+
+template<int8_t _NF>
+ + + + + +
+ + + + + + + + +
void Smooth< SFix< NI, NF > >::setSmoothness (UFix< 0, _NF > smoothness)
+
+inline
+
+ +

Sets how much smoothing the filter will apply to its input.

+
Parameters
+ + +
smoothnesssets 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.
+
+
+ +

Definition at line 418 of file Smooth.h.

+ +
+
+
+
+ + + diff --git a/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.js b/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.js new file mode 100644 index 000000000..1363475c4 --- /dev/null +++ b/extras/doc/html/class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.js @@ -0,0 +1,9 @@ +var class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4 = +[ + [ "Smooth", "class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#aa28affdd0ec1fb3d2b8519dce1bd62b1", null ], + [ "Smooth", "class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#aa34d3186fcabc7a245c4b47e1f1dc135", null ], + [ "next", "class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#a65d8d8b4cd627d57d8ff601b94edbf20", null ], + [ "operator()", "class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#af7e0f03ad5fc534cb1fb042101f50eb8", null ], + [ "setSmoothness", "class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#a1c440ce813507ccb32bd9a2f19aeb643", null ], + [ "setSmoothness", "class_smooth_3_01_s_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#a6fb0f2216e29f946dfb8befafaf9d5fc", null ] +]; \ No newline at end of file diff --git a/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4-members.html b/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4-members.html new file mode 100644 index 000000000..89e316fa8 --- /dev/null +++ b/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4-members.html @@ -0,0 +1,117 @@ + + + + + + + +Mozzi: Member List + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
Mozzi +  version v2.0 +
+
sound synthesis library for Arduino
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Smooth< UFix< NI, NF > > Member List
+
+
+ +

This is the complete list of members for Smooth< UFix< NI, NF > >, including all inherited members.

+ + + + + + + +
next(internal_type in)Smooth< UFix< NI, NF > >inline
operator()(internal_type n) (defined in Smooth< UFix< NI, NF > >)Smooth< UFix< NI, NF > >inline
setSmoothness(float smoothness)Smooth< UFix< NI, NF > >inline
setSmoothness(UFix< 0, _NF > smoothness)Smooth< UFix< NI, NF > >inline
Smooth(T smoothness)Smooth< UFix< NI, NF > >inline
Smooth()Smooth< UFix< NI, NF > >inline
+
+ + + diff --git a/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html b/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html new file mode 100644 index 000000000..76ac73625 --- /dev/null +++ b/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html @@ -0,0 +1,332 @@ + + + + + + + +Mozzi: Smooth< UFix< NI, NF > > Class Template Reference + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
Mozzi +  version v2.0 +
+
sound synthesis library for Arduino
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
Smooth< UFix< NI, NF > > Class Template Reference
+
+
+

Detailed Description

+

template<int8_t NI, int8_t NF>
+class Smooth< UFix< NI, NF > >

+ + +

Definition at line 274 of file Smooth.h.

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

+Public Member Functions

template<typename T >
 Smooth (T smoothness)
 Constructor. More...
 
 Smooth ()
 Constructor. More...
 
internal_type next (internal_type in)
 Filters the input and returns the filtered value. More...
 
+internal_type operator() (internal_type n)
 
void setSmoothness (float smoothness)
 Sets how much smoothing the filter will apply to its input. More...
 
template<int8_t _NF>
void setSmoothness (UFix< 0, _NF > smoothness)
 Sets how much smoothing the filter will apply to its input. More...
 
+

Constructor & Destructor Documentation

+ +

◆ Smooth() [1/2]

+ +
+
+
+template<int8_t NI, int8_t NF>
+
+template<typename T >
+ + + + + +
+ + + + + + + + +
Smooth< UFix< NI, NF > >::Smooth (smoothness)
+
+inline
+
+ +

Constructor.

+
Parameters
+ + +
smoothnesssets 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.
+
+
+ +

Definition at line 290 of file Smooth.h.

+ +
+
+ +

◆ Smooth() [2/2]

+ +
+
+
+template<int8_t NI, int8_t NF>
+ + + + + +
+ + + + + + + +
Smooth< UFix< NI, NF > >::Smooth ()
+
+inline
+
+ +

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...
+ +

Definition at line 300 of file Smooth.h.

+ +
+
+

Member Function Documentation

+ +

◆ next()

+ +
+
+
+template<int8_t NI, int8_t NF>
+ + + + + +
+ + + + + + + + +
internal_type Smooth< UFix< NI, NF > >::next (internal_type in)
+
+inline
+
+ +

Filters the input and returns the filtered value.

+

You can also use the operator() function, eg. something like mySmoother(input-value).

Parameters
+ + +
inthe signal to be smoothed.
+
+
+
Returns
the filtered signal.
+ +

Definition at line 309 of file Smooth.h.

+ +
+
+ +

◆ setSmoothness() [1/2]

+ +
+
+
+template<int8_t NI, int8_t NF>
+ + + + + +
+ + + + + + + + +
void Smooth< UFix< NI, NF > >::setSmoothness (float smoothness)
+
+inline
+
+ +

Sets how much smoothing the filter will apply to its input.

+
Parameters
+ + +
smoothnesssets 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.
+
+
+ +

Definition at line 329 of file Smooth.h.

+ +
+
+ +

◆ setSmoothness() [2/2]

+ +
+
+
+template<int8_t NI, int8_t NF>
+
+template<int8_t _NF>
+ + + + + +
+ + + + + + + + +
void Smooth< UFix< NI, NF > >::setSmoothness (UFix< 0, _NF > smoothness)
+
+inline
+
+ +

Sets how much smoothing the filter will apply to its input.

+
Parameters
+ + +
smoothnesssets 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.
+
+
+ +

Definition at line 340 of file Smooth.h.

+ +
+
+
+
+ + + diff --git a/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.js b/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.js new file mode 100644 index 000000000..b2c408f32 --- /dev/null +++ b/extras/doc/html/class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.js @@ -0,0 +1,9 @@ +var class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4 = +[ + [ "Smooth", "class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#a2ea0479e484a72f477f8dc56726cf933", null ], + [ "Smooth", "class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#abc93c181f47511887d1275757b3c2c70", null ], + [ "next", "class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#a2981f4eee274902609641c3a9e949576", null ], + [ "operator()", "class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#a7c51b3bf5a40191727c376b4243ce93b", null ], + [ "setSmoothness", "class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#aa4fb9cdb86f67bfc3e310920418329b7", null ], + [ "setSmoothness", "class_smooth_3_01_u_fix_3_01_n_i_00_01_n_f_01_4_01_4.html#a24a2eb8633ce6a2a0da4e527c0186784", null ] +]; \ No newline at end of file diff --git a/extras/doc/html/class_stack-members.html b/extras/doc/html/class_stack-members.html index f88e5990a..071c3b5f0 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 @@ - @@ -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 @@
@@ -111,13 +107,8 @@ Stack()Stack< T, NUM_ITEMS >inline
- - - + @@ -80,7 +76,7 @@
@@ -111,20 +107,6 @@ More...

#include <Stack.h>

- - - - - - - - - - - -

-Public Member Functions

Stack ()
 Constructor.
 
void push (T item)
 Put an item on the stack. More...
 
pop ()
 Get the item on top of the stack. More...
 

Detailed Description

template<class T, int NUM_ITEMS>
class Stack< T, NUM_ITEMS >

@@ -139,7 +121,21 @@

Definition at line 18 of file Stack.h.

-

Member Function Documentation

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

+Public Member Functions

Stack ()
 Constructor.
 
void push (T item)
 Put an item on the stack. More...
 
pop ()
 Get the item on top of the stack. More...
 
+

Member Function Documentation

◆ pop()

@@ -212,14 +208,8 @@

-
    - - -
+ diff --git a/extras/doc/html/class_state_variable-members.html b/extras/doc/html/class_state_variable-members.html index 3e86b2fd8..e298103c3 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 @@ - @@ -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 @@
@@ -112,13 +108,8 @@ StateVariable()StateVariable< FILTER_TYPE >inline
- - - + @@ -80,7 +76,7 @@
@@ -107,37 +103,16 @@
-


-
-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>

- - - - - - - - - - - - - - -

-Public Member Functions

StateVariable ()
 Constructor.
 
void setResonance (Q0n8 resonance)
 Set how resonant the filter will be. More...
 
void setCentreFreq (unsigned int centre_freq)
 Set the centre or corner frequency of the filter. More...
 
int next (int input)
 Calculate the next sample, given an input signal. More...
 

Detailed Description

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;

@@ -150,8 +125,25 @@

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.

-

Member Function Documentation

+

Definition at line 65 of file StateVariable.h.

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

+Public Member Functions

StateVariable ()
 Constructor.
 
void setResonance (Q0n8 resonance)
 Set how resonant the filter will be. More...
 
void setCentreFreq (unsigned int centre_freq)
 Set the centre or corner frequency of the filter. More...
 
int next (int input)
 Calculate the next sample, given an input signal. More...
 
+

Member Function Documentation

◆ next()

@@ -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.

@@ -221,7 +213,7 @@

Parameters
- +
centre_freq20 - 4096 Hz (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.
centre_freq20 - 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.
@@ -229,7 +221,7 @@

-

Definition at line 95 of file StateVariable.h.

+

Definition at line 94 of file StateVariable.h.

@@ -268,20 +260,14 @@

Note
Timing < 500 ns
-

Definition at line 80 of file StateVariable.h.

+

Definition at line 79 of file StateVariable.h.

- - - + @@ -80,7 +76,7 @@
@@ -113,13 +109,8 @@ WaveFolder()WaveFolder< T >inline
- - - + @@ -80,7 +76,7 @@
@@ -111,7 +107,14 @@ More...

#include <WaveFolder.h>

- +

Detailed Description

+

template<typename T = AudioOutputStorage_t>
+class WaveFolder< T >

+ +

A simple wavefolder.

+ +

Definition at line 37 of file WaveFolder.h.

+
- + - + - + - +

Public Member Functions

@@ -119,26 +122,19 @@
 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...
 
-

Detailed Description

-

template<typename T = AudioOutputStorage_t>
-class WaveFolder< T >

- -

A simple wavefolder.

- -

Definition at line 38 of file WaveFolder.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

@@ -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,20 +296,14 @@

Definition at line 60 of file WaveFolder.h.

+

Definition at line 59 of file WaveFolder.h.

- - - + @@ -80,7 +76,7 @@
@@ -114,13 +110,8 @@ WavePacket()WavePacket< ALGORITHM >inline
- - - + @@ -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,9 +117,22 @@ WavePacketSample< ALGORITHM > - -
- + + +

Detailed Description

+

template<int8_t ALGORITHM>
+class WavePacket< ALGORITHM >

+ +

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
+
+ +
ALGORITHMoptions are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
+ + + +

Definition at line 36 of file WavePacket.h.

+ - + - + - + - + - +

Public Member Functions

@@ -132,36 +140,22 @@
 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...
 
-

Detailed Description

-

template<int8_t ALGORITHM>
-class WavePacket< ALGORITHM >

- -


-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
- - -
ALGORITHMoptions are SINGLE or DOUBLE, for a single non-overlapping stream of packets or a double, overlapping stream.
-
-
- -

Definition at line 36 of file WavePacket.h.

-

Member Function Documentation

+

Member Function Documentation

◆ next()

@@ -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.
@@ -368,14 +362,8 @@

-
    - - -
+ diff --git a/extras/doc/html/class_wave_packet_sample-members.html b/extras/doc/html/class_wave_packet_sample-members.html index 2731899f0..f0af04e58 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 @@ - @@ -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 @@
@@ -115,13 +111,8 @@ WavePacket()WavePacket< ALGORITHM >inline
- - - + @@ -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,45 +115,45 @@
-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).

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

Definition at line 23 of file WavePacketSample.h.

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

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...
 
-

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()

@@ -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,20 +392,14 @@

Definition at line 29 of file WavePacketSample.h.

+

Definition at line 30 of file WavePacketSample.h.

- - - + @@ -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
@@ -123,14 +119,8 @@

Definition at line 22 of file WaveShaper.h.

- - @@ -61,10 +57,10 @@
Tthe type of numbers being input to be shaped, chosen to match the table.
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)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -110,13 +106,8 @@ WaveShaper(const int8_t *TABLE_NAME)WaveShaper< char >inline
- - - + @@ -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

+

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...
 
-

Detailed Description

-

template<>
-class WaveShaper< char >

- -

int8_t specialisation of WaveShaper template

- -

Definition at line 29 of file WaveShaper.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ WaveShaper()

@@ -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.

@@ -211,14 +204,8 @@

- + 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 0b134b482..33569d762 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 @@ - @@ -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 @@
@@ -110,13 +106,8 @@ WaveShaper(const int16_t *TABLE_NAME)WaveShaper< int >inline
- - - + @@ -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

+

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...
 
-

Detailed Description

-

template<>
-class WaveShaper< int >

- -

int specialisation of WaveShaper template

- -

Definition at line 65 of file WaveShaper.h.

-

Constructor & Destructor Documentation

+

Constructor & Destructor Documentation

◆ WaveShaper()

@@ -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().

@@ -211,14 +204,8 @@

- + diff --git a/extras/doc/html/classes.html b/extras/doc/html/classes.html index bc87b2379..011df6fc7 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,48 +99,49 @@
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
+
- - - + @@ -80,7 +76,7 @@
@@ -105,14 +101,8 @@
- - - + @@ -80,7 +76,7 @@
@@ -107,19 +103,13 @@

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.
 
- - - + @@ -80,7 +76,7 @@
@@ -100,21 +96,20 @@
-
fromAlmostNBit
+
internal Directory Reference
-

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().

-

(10, oscilA.next() + oscilB.next() + oscilC.next());

-
+ + + + + +

+Files

file  MozziGuts_impl_template.hpp [code]
 Template for implementation of new ports.
 
+ - - - + @@ -80,7 +76,7 @@
@@ -100,19 +96,13 @@
-
07.Envelopes/MultiLine_Envelope/MultiLine_Envelope.ino
+
Skeleton_Multi Directory Reference
-

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

-
+ - - - + @@ -80,7 +76,7 @@
@@ -100,7 +96,7 @@
-
12.Misc Directory Reference
+
01.Basics Directory Reference
@@ -109,14 +105,8 @@
- - - + @@ -80,7 +76,7 @@
@@ -109,14 +105,8 @@
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,16 @@
config Directory Reference
+ + + + +

+Files

file  mozzi_config_documentation.h [code]
 
- - - + @@ -80,7 +76,7 @@
@@ -105,14 +101,8 @@
- - - + @@ -80,7 +76,7 @@
@@ -109,14 +105,8 @@
- - - + @@ -80,7 +76,7 @@
@@ -105,14 +101,8 @@
- - - + @@ -80,7 +76,7 @@
@@ -104,70 +100,63 @@
Here is a list of all examples:
- - - + @@ -80,7 +76,7 @@
@@ -107,108 +103,121 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 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.hppTemplate for implementation of new ports
 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
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,56 @@
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('#if ARDUINO >= 100'+'\n')
31  fout.write('#include "Arduino.h"'+'\n')
32  fout.write('#else'+'\n')
33  fout.write('#include "WProgram.h"'+'\n')
34  fout.write('#endif'+'\n')
35  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
36  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
37  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
38  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
39  try:
40  for num in values:
41  outstring += str(math.trunc((num*256)+0.5)) + ", "
42 
44  finally:
45  outstring += "};"
46  outstring = textwrap.fill(outstring, 80)
47  fout.write(outstring)
48  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
49  fout.close()
50  print "wrote " + outfile
51 
52 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)
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,50 @@
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('#if ARDUINO >= 100'+'\n')
25  fout.write('#include "Arduino.h"'+'\n')
26  fout.write('#else'+'\n')
27  fout.write('#include "WProgram.h"'+'\n')
28  fout.write('#endif'+'\n')
29  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
30  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
31  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
32  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
33  try:
34  for num in values:
35  outstring += str(math.trunc((num*256)+0.5)) + ", "
36 
38  finally:
39  outstring += "};"
40  outstring = textwrap.fill(outstring, 80)
41  fout.write(outstring)
42  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
43  fout.close()
44  print "wrote " + outfile
45 
46 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)
+
- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -108,13 +104,8 @@

- b -

- - - + @@ -80,7 +76,7 @@
@@ -115,13 +111,8 @@

- c -

- - - + @@ -80,7 +76,7 @@
@@ -108,13 +104,8 @@

- d -

- - - + @@ -80,7 +76,7 @@
@@ -111,13 +107,8 @@

- e -

- - - + @@ -80,7 +76,7 @@
@@ -111,22 +107,22 @@

- f -

- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -108,13 +104,8 @@

- b -

- - - + @@ -80,7 +76,7 @@
@@ -115,13 +111,8 @@

- c -

- - - + @@ -80,7 +76,7 @@
@@ -108,13 +104,8 @@

- d -

- - - + @@ -80,7 +76,7 @@
@@ -111,13 +107,8 @@

- e -

- - - + @@ -80,7 +76,7 @@
@@ -111,22 +107,22 @@

- f -

- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -108,13 +104,8 @@

- h -

- - - + @@ -80,7 +76,7 @@
@@ -111,13 +107,8 @@

- i -

- - - + @@ -80,7 +76,7 @@
@@ -104,6 +100,8 @@

- l -

- - - + @@ -80,7 +76,7 @@
@@ -109,18 +105,13 @@

- m -

- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -102,11 +98,11 @@  

- o -

- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -121,13 +117,8 @@

- w -

- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -108,13 +104,8 @@

- h -

- - - + @@ -80,7 +76,7 @@
@@ -111,13 +107,8 @@

- i -

- - - + @@ -80,7 +76,7 @@
@@ -104,6 +100,8 @@

- l -

- - - + @@ -80,7 +76,7 @@
@@ -109,18 +105,16 @@

- m -

- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -102,11 +98,11 @@
Here is a list of all documented class members with links to the class documentation for each member:

- o -

- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -102,6 +98,9 @@
Here is a list of all documented class members with links to the class documentation for each member:

- r -

- - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@ - - - + @@ -80,7 +76,7 @@
@@ -121,13 +117,8 @@

- w -

- - - + @@ -80,7 +76,7 @@
@@ -108,42 +104,53 @@

Efficient analog input functions for sensors and audio. More...

+

Detailed Description

+

Efficient analog input functions for sensors and audio.

+

Helps produce glitch-free audio by allowing analog input functions which normally block processing to be performed in the background.

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

Functions

void setupFastAnalogRead (int8_t speed=FAST_ADC)
 
- This is automatically called in startMozzi. More...
 This is automatically called in startMozzi. More...
 
void disconnectDigitalIn (uint8_t channel_num)
 Prepare an analog input channel by turning off its digital input buffer. More...
 Prepare an analog input channel by turning off its digital input buffer. More...
 
void reconnectDigitalIn (uint8_t channel_num)
 Reconnect the digital input buffer for an analog input channel which has been set for analog input with disconnectDigitalIn(). More...
 Reconnect the digital input buffer for an analog input channel which has been set for analog input with disconnectDigitalIn(). More...
 
void adcDisconnectAllDigitalIns ()
 Prepare all analog input channels by turning off their digital input buffers. More...
 Prepare all analog input channels by turning off their digital input buffers. More...
 
void adcReconnectAllDigitalIns ()
 Reconnect the digital input buffers for analog input channels which have been set for analog input with disconnectDigitalIn().
 Reconnect the digital input buffers for analog input channels which have been set for analog input with disconnectDigitalIn().
 
int mozziAnalogRead (uint8_t pin)
 Reads the analog input of a chosen channel, without blocking other operations from running. More...
 
int getAudioInput ()
 This returns audio input from the input buffer, if #define USE_AUDIO_INPUT true is in the Mozzi/mozzi_config.h file. More...
 
template<byte RES>
uint16_t mozziAnalogRead (uint8_t pin)
 See mozziAnalogRead(). More...
 
uint16_t mozziAnalogRead16 (uint8_t pin)
 See mozziAnalogRead() but always returns the value shifted to 16 bit range. More...
 
template<byte RES>
uint16_t getAudioInput ()
 See getAudioInput(). More...
 
template<byte RES>
uint16_t getAudioInput16 ()
 See getAudioInput(). More...
 
-

Detailed Description

-

Efficient analog input functions for sensors and audio.

-

Helps produce glitch-free audio by allowing analog input functions which normally block processing to be performed in the background.

Function Documentation

◆ adcDisconnectAllDigitalIns()

+ + + @@ -61,10 +57,10 @@
@@ -152,12 +159,17 @@

+inline +

+
void adcDisconnectAllDigitalIns
@@ -166,6 +178,9 @@

+ + + @@ -61,10 +57,10 @@
@@ -175,6 +190,11 @@

+inline +

+
void disconnectDigitalIn
- -

◆ getAudioInput()

+ +

◆ getAudioInput()

+
+template<byte RES>
- + @@ -210,21 +230,59 @@

-

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. 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 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

Returns
audio data from the input buffer
+

See getAudioInput().

+

This returns audio input from the input buffer, if @ref MOZZI_AUDIO_INPUT is enabled in the config (see also the related option MOZZI_AUDIO_INPUT_PIN).

+

The template parameter specifies the desired value range in bits.

+

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 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.
+
Returns
audio data from the input buffer
-

Definition at line 126 of file MozziGuts.cpp.

+

Definition at line 172 of file MozziGuts.h.

- -

◆ mozziAnalogRead()

+ +

◆ getAudioInput16()

+
+template<byte RES>
+

int getAudioInput uint16_t getAudioInput ( )
+ + + + +
- + + + + + +
int mozziAnalogRead uint16_t getAudioInput16 ()
+
+inline
+
+ +

See getAudioInput().

+

Equivalent to getAudioInput<16>().

+ +

Definition at line 149 of file MozziGuts.h.

+ +
+
+ +

◆ mozziAnalogRead()

+ +
+
+
+template<byte RES>
+ + + @@ -233,16 +291,51 @@

-

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.

Parameters
+

See mozziAnalogRead().

+

Reads the analog input of a chosen channel, without blocking other operations from running.

+

The template parameter RES specifies the number of bits to return.

+

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.
+
Parameters

uint16_t mozziAnalogRead ( uint8_t  pin)
pin_or_channelthe analog pin or channel number.
-
Returns
the digitised value of the voltage on the chosen channel, in the range 0-1023. that non-AVR hardware may return a different range, e.g. 0-4095 on STM32 boards.
+
Returns
the digitised value of the voltage on the chosen channel. See the note above regarding the output range!
+ +

Definition at line 174 of file mozzi_analog.h.

+ +
+
+ +

◆ mozziAnalogRead16()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t mozziAnalogRead16 (uint8_t pin)
+
+inline
+
+ +

See mozziAnalogRead() but always returns the value shifted to 16 bit range.

+

THis is exactly equivalent to mozziAnalogRead<16>(pin);

-

Definition at line 109 of file MozziGuts.cpp.

+

Definition at line 152 of file mozzi_analog.h.

@@ -251,6 +344,9 @@

+ + + @@ -61,10 +57,10 @@
@@ -260,9 +356,14 @@

+inline +

+
void reconnectDigitalIn
-

Reconnect the digital input buffer for an analog input channel which has been set for analog input with disconnectDigitalIn().

+

Reconnect the digital input buffer for an analog input channel which has been set for analog input with disconnectDigitalIn().

Parameters
@@ -270,7 +371,7 @@

Definition at line 32 of file mozzi_analog.cpp.

+

Definition at line 99 of file mozzi_analog.h.

@@ -284,37 +385,26 @@

void setupFastAnalogRead

- +
channel_numthe analog input channel you wish to reconnect.
( int8_t speed)speed = FAST_ADC)
-


- This is automatically called in startMozzi.

-

It makes mozziAnalogRead() happen faster than the standard Arduino analogRead(), changing the duration from about 105 in unmodified Arduino to about 16 microseconds for a dependable read with the default speed parameter FAST_ADC. If you want to set on of the faster modes (see params) you can call this after startMozzi(). See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11, and http://www.marulaberry.co.za/index.php/tutorials/code/arduino-adc/

Parameters
+

This is automatically called in startMozzi.

+

It makes mozziAnalogRead() happen faster than the standard Arduino analogRead(), changing the duration from about 105 in unmodified Arduino to about 16 microseconds for a dependable read with the default speed parameter FAST_ADC. If you want to set on of the faster modes (see params) you can call this after startMozzi(). See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11, and http://www.marulaberry.co.za/index.php/tutorials/code/arduino-adc/

Parameters
- +
speedFAST_ADC, FASTER_ADC or FASTEST_ADC. If no parameter is supplied, the default is FAST_ADC, which sets the analog conversion clock predivide rate to 16, giving 1Mhz on a 16MHz board, the fastest rate for which behaviour is defined (~16us per sample). However, divisors of 8 and 4 also show usable results in the graphs in this paper: http://dam.mellis.org/Mellis%20-%20Sensor%20Library%20for%20Arduino%20-%20Paper.pdf, so you can also try FASTER_ADC or FASTEST_ADC for divide rates of 8 or 4, giving times of about 8us or 4us per sample. Beware, reliable results will depend on the sort of input signal you have. Only use FASTER_ADC or FASTEST_ADC if you know what you're doing.
speedFAST_ADC, FASTER_ADC or FASTEST_ADC. If no parameter is supplied, the default is FAST_ADC, which sets the analog conversion clock predivide rate to 16, giving 1Mhz on a 16MHz board, the fastest rate for which behaviour is defined (~16us per sample). However, divisors of 8 and 4 also show usable results in the graphs in this paper: http://dam.mellis.org/Mellis%20-%20Sensor%20Library%20for%20Arduino%20-%20Paper.pdf, so you can also try FASTER_ADC or FASTEST_ADC for divide rates of 8 or 4, giving times of about 8us or 4us per sample. Beware, reliable results will depend on the sort of input signal you have. Only use FASTER_ADC or FASTEST_ADC if you know what you're doing.
-


- This is automatically called in startMozzi.

-

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.

- -

Definition at line 82 of file MozziGuts_impl_AVR.hpp.

- -
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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -100,325 +96,93 @@
-
Core
+
Mozzi Core Functions
- -


- Core definitions and functions. -More...

+

Detailed Description

+

The bones of every Mozzi sketch.

+

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.

+

This function intializes the timer(s) needed to move audio samples to the output according to the configured MOZZI_AUDIO_MODE .

+
Parameters
+ + +
control_rate_hzSets how often updateControl() is called. It must be a power of 2. 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.
+
+
+
Note
startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(), which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack). 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.
+ + + + + + + + + + +

+Files

file  MozziHeadersOnly.h
 This file provides declarations of the Mozzi Core Functions Mozzi functions, but no implementation.
 
file  Mozzi.h
 This is the main include file in Mozzi.
 
file  twi_nonblock_HeadersOnly.h
 This file provides declarations of the Mozzi Core Functions twi_nonblock functions, but no implementation.
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +

Macros

#define AUDIO_MODE   STANDARD_PLUS
 AUDIO_MODE holds the audio mode setting. More...
 
#define AUDIO_RATE   AUDIO_RATE_PLATFORM_DEFAULT
 Holds the audio rate setting. More...
 
#define AUDIO_INPUT_PIN   0
 This sets which analog input channel to use for audio input, if you have uncommented #define USE_AUDIO_INPUT true in mozz_config.h. More...
 
#define AUDIO_CHANNELS   MONO
 This sets allows to change from a single/mono audio output channel to stereo output. More...
 
#define EXTERNAL_AUDIO_OUTPUT   false
 Defining this option as true in mozzi_config.h allows to completely customize the audio output, e.g. More...
 
#define STANDARD   0
 Used to set AUDIO_MODE to STANDARD, STANDARD_PLUS, or HIFI. More...
 
-#define AUDIO_BIAS   ((uint16_t) 1 << (AUDIO_BITS - 1))
 
#define STANDARD_PWM_RESOLUTION   488
 This is the dynamic range of Mozzi's audio output in STANDARD mode. More...
 
#define STANDARD_PWM_RESOLUTION   488
 This is the dynamic range of Mozzi's audio output in STANDARD mode. More...
 
-#define AUDIO_BIAS   ((uint16_t) 2048)
 
-#define AUDIO_BIAS   ((uint16_t) 512)
 
#define CONSTTABLE_STORAGE(X)
 Declare a variable such that it will be stored in flash memory, instead of RAM, on platforms where this is reasonably possible (i.e. More...
 
- - - + + + + + + + + - + - - - - - - - - - + + + - + - + - + - +

Functions

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 restored when Mozzi stops. More...
 
template<typename T >
mozzi_pgm_read_wrapper (const T *address)
 Helper function to FLASH_OR_RAM_READ(). More...
 
template<typename T >
FLASH_OR_RAM_READ (T *address)
 Read a value from flash or RAM. More...
 
void stopMozzi ()
 Stops audio and control interrupts and restores the timers to the values they had before Mozzi was started. More...
 Stops audio and control interrupts and restores the timers to the values they had before Mozzi was started. More...
 
-void pauseMozzi ()
 Obsolete function, use stopMozzi() instead.
 
void unPauseMozzi ()
 Obsolete function, use startMozzi() instead. More...
 
AudioOutput_t updateAudio ()
 This is where you put your audio code. More...
 
AudioOutput updateAudio ()
 This is where you put your audio code. More...
 
void updateControl ()
 This is where you put your control code. More...
 This is where you put your control code. More...
 
void audioHook ()
 This is required in Arduino's loop(). More...
 This is required in Arduino's loop(). More...
 
unsigned long audioTicks ()
 An alternative for Arduino time functions like micros() and millis(). More...
 An alternative for Arduino time functions like micros() and millis(). More...
 
unsigned long mozziMicros ()
 An alternative for Arduino time functions like micros() and millis(). More...
 An alternative for Arduino time functions like micros() and millis(). More...
 
-

Detailed Description

-


- Core definitions and functions.

-

The bones of every Mozzi sketch.

Macro Definition Documentation

- -

◆ AUDIO_CHANNELS

- -
-
- - - - -
#define AUDIO_CHANNELS   MONO
-
- -

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.
-
-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.
- -

Definition at line 92 of file mozzi_config.h.

- -
-
- -

◆ AUDIO_INPUT_PIN

- -
-
- - - - -
#define AUDIO_INPUT_PIN   0
-
- -

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.
- -

Definition at line 76 of file mozzi_config.h.

- -
-
- -

◆ AUDIO_MODE

- -
-
- - - - -
#define AUDIO_MODE   STANDARD_PLUS
-
- -

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.
- -

Definition at line 28 of file mozzi_config.h.

- -
-
- -

◆ AUDIO_RATE

- -
-
- - - - -
#define AUDIO_RATE   AUDIO_RATE_PLATFORM_DEFAULT
-
- -

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.

- -

Definition at line 62 of file mozzi_config.h.

- -
-
- -

◆ EXTERNAL_AUDIO_OUTPUT

- -
-
- - - - -
#define EXTERNAL_AUDIO_OUTPUT   false
-
- -

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 also
AudioOuput .
- -

Definition at line 99 of file mozzi_config.h.

- -
-
- -

◆ STANDARD

- -
-
- - - - -
#define STANDARD   0
-
- -

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.

-

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.
- resistor.....3.9k......499k
-x................9..........10...............Arduino Uno
-x................9..........10...............Arduino Duemilanove
-x................9..........10...............Arduino Nano
-x................9..........10...............Arduino Leonardo
-x................9..........10...............Ardweeny
-x................9..........10...............Boarduino
-x...............11.........12...............Freetronics EtherMega
-.................11.........12...............Arduino Mega
-.................14.........15...............Teensy
-.............B5(14)...B6(15)...........Teensy2
-x...........B5(25)...B6(26)...........Teensy2++
-.................13.........12...............Sanguino
- HIFI is not available/not required on Teensy 3.* or ARM.

- -

Definition at line 164 of file MozziGuts.h.

- -
-
- -

◆ STANDARD_PWM_RESOLUTION [1/2]

- -
-
- - - - -
#define STANDARD_PWM_RESOLUTION   488
-
- -

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.

- -

Definition at line 11 of file AudioConfigStandard9bitPwm.h.

- -
-
- -

◆ STANDARD_PWM_RESOLUTION [2/2]

+ +

◆ CONSTTABLE_STORAGE

- + + + + +
#define STANDARD_PWM_RESOLUTION   488#define CONSTTABLE_STORAGE( X)
-

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.

+

Declare a variable such that it will be stored in flash memory, instead of RAM, on platforms where this is reasonably possible (i.e.

+

not on ESP8266, where random location flash memory access is too slow). To read the variable in a cross-platform compatible way, use FLASH_OR_RAM_READ().

-

Definition at line 11 of file AudioConfigStandardPlus.h.

+

Definition at line 67 of file mozzi_pgmspace.h.

@@ -439,9 +203,9 @@

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, 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 they can be called less often by moving them into updateControl(), to save processing power. Otherwise it may be most efficient to calculate a block of samples at a time by putting audioHook() in a loop of its own, rather than calculating only 1 sample for each time your other functions are called.

+

If there is room in Mozzi's output buffer, audioHook() calls updateAudio() once and puts the result into the output 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 they can be called less often by moving them into updateControl(), to save processing power. Otherwise it may be most efficient to calculate a block of samples at a time by putting audioHook() in a loop of its own, rather than calculating only 1 sample for each time your other functions are called.

-

Definition at line 190 of file MozziGuts.cpp.

+

Definition at line 313 of file MozziGuts.hpp.

@@ -461,75 +225,86 @@

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). audioTicks() is updated each time an audio sample is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when AUDIO_RATE is 16384 Hz).

Returns
the number of audio ticks since the program began.
+

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/MOZZI_AUDIO_RATE seconds from the current time). audioTicks() is updated each time an audio sample is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is 16384 Hz).

Returns
the number of audio ticks since the program began.
-

Definition at line 219 of file MozziGuts.cpp.

+

Definition at line 301 of file MozziGuts.hpp.

- -

◆ mozziMicros()

+ +

◆ FLASH_OR_RAM_READ()

+
+template<typename T >
+ + + + + +
- + - + +
unsigned long mozziMicros T FLASH_OR_RAM_READ ()T * address)
+
+inline
-

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). audioTicks() is updated each time an audio sample is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when AUDIO_RATE is 16384 Hz).

Returns
the approximate number of microseconds since the program began.
+

Read a value from flash or RAM.

+

The specified address is read from flash, if T is const, and const tables are stored in flash on this platform (i.e. not on ESP8266). It is read from RAM, if T is not-const or tables are always stored in RAM on this platform.

See also
CONSTTABLE_STORAGE .
-

Definition at line 229 of file MozziGuts.cpp.

+

Definition at line 57 of file mozzi_pgmspace.h.

- -

◆ startMozzi()

+ +

◆ mozzi_pgm_read_wrapper()

+
+template<typename T >
+ + + + + +
- + - - + +
void startMozzi T mozzi_pgm_read_wrapper (int control_rate_hz = CONTROL_RATE)const T * address)
+
+inline
-

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.

-
Parameters
- - -
control_rate_hzSets 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, 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.
-
-
-
Note
startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(), which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack). 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.
+

Helper function to FLASH_OR_RAM_READ().

+

You do not want to call this, directly.

-

Definition at line 234 of file MozziGuts.cpp.

+

Definition at line 32 of file mozzi_pgmspace.h.

- -

◆ stopMozzi()

+ +

◆ mozziMicros()

- + @@ -537,23 +312,21 @@

-

Stops audio and control interrupts and restores the timers to the values they had before Mozzi was started.

-

This could be useful when using sensor libraries which depend on the same timers as Mozzi.

-

A potentially better option for resolving timer conflicts involves using non-blocking methods, such as demonstrated by the twowire_nonblock code in the 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 involve individually saving and restoring particular Timer registers depending on which one(s) are required for other tasks.

+

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/MOZZI_AUDIO_RATE seconds from the current time). audioTicks() is updated each time an audio sample is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is 16384 Hz).

Returns
the approximate number of microseconds since the program began.
-

Definition at line 337 of file MozziGuts_impl_AVR.hpp.

+

Definition at line 300 of file MozziGuts.hpp.

- -

◆ unPauseMozzi()

+ +

◆ stopMozzi()

void stopMozzi unsigned long mozziMicros ( )
- + @@ -561,19 +334,24 @@

-

Obsolete function, use startMozzi() instead.

-

Restores Mozzi audio and control interrupts, if they have been temporarily disabled with pauseMozzi().

+

Stops audio and control interrupts and restores the timers to the values they had before Mozzi was started.

+

This could be useful when using sensor libraries which depend on the same timers as Mozzi.

+

A potentially better option for resolving timer conflicts involves using non-blocking methods, such as demonstrated by the twowire_nonblock code in the 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.hpp could involve individually saving and restoring particular Timer registers depending on which one(s) are required for other tasks.

+
Note
This function is not actually implemented on all platforms.
+ +

Definition at line 303 of file MozziGuts.hpp.

- -

◆ updateAudio()

+ +

◆ updateAudio()

void unPauseMozzi void stopMozzi ( )
- + @@ -582,7 +360,10 @@

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 calculations here which could be done in setup() or updateControl().

Returns
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.
+

updateAudio() has to keep up with the 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().

Returns
an audio sample.
+

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.

+ +

Definition at line 5 of file Skeleton_Multi_Unit2.cpp.

@@ -602,19 +383,14 @@

This is where you put your control code.

-

You need updateControl() somewhere in your sketch, even if it's empty. updateControl() is called at the control rate you set in startMozzi(). To save processor load, avoid any calculations here which could be done in setup().

+

You need updateControl() somewhere in your sketch, even if it's empty. updateControl() is called at the control rate you set in startMozzi(). To save processor load, avoid any calculations here which could be done in setup().

- -

@@ -61,10 +57,10 @@
AudioOutput_t updateAudio AudioOutput updateAudio ( )
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)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -102,41 +98,24 @@
-
Fixmath
+
Fast integer based fixed-point arithmetic
- -

Fixed point fractional number types and conversion routines. -More...

+

Detailed Description

+
Note
For new sketches it is recommended to utitlize the FixMath library with its typesafe classes UFix and SFix, instead of these typedefs! See https://github.com/tomcombriat/FixMath . These are provided for backwards compatibility, only.
+

Fixed point fractional number types and conversion routines. Fixed point is often best for fast audio code for Arduino, and these can ease some of the pain.

+
+
Note
+

Take care when converting that the important bits of your numbers will fit in the types you choose!

+

Timing: converting between fixed and float 10-12us, converting between fixed types about 1us.

+
+
- + - - - - - - - - - - - - - - - - - @@ -225,287 +204,303 @@ typedef uint32_t  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Functions

Q7n8 Q7n8_mult (Q7n8 a, Q7n8 b)
 Fast fixed point multiply for Q7n8 fractional numbers. More...
 Fast fixed point multiply for Q7n8 fractional numbers. More...
 
uint8_t uint8_tMod (uint8_t n, uint8_t d)
 
-fast uint8_t modulus More...
 
uint8_t uint8_tDiv (uint8_t n, uint8_t d)
 Fast uint8_t division. More...
 
-uint8_t uint8_tRnd (uint8_t min, uint8_t max)
 
-int ipow (int base, int exp)
 
Q16n16 Q16n16_pow2 (Q8n8 exponent)
 
-fast replacement for pow(2,x), where x is a Q8n8 fractional fixed-point exponent. More...
 
-uint32_t isqrt32 (uint32_t n)
 
-uint16_t isqrt16 (uint16_t n)
 
typedef int8_t Q0n7
 signed fractional number using 7 fractional bits, represents -0.5 to 0.496
Q16n16
 unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535.999
 
-#define Q0n7_FIX1   ((Q0n7) 127)
 0.992 in Q0n7 format
 
-#define Q7n8_FIX1   ((Q7n8) 256)
 1 in Q7n8 format
 
-#define Q8n8_FIX1   ((Q8n8) 256)
 1 in Q8n8 format
 
-#define Q23n8_FIX1   ((Q23n8) 256)
 1 in Q23n8 format
 
-#define Q1n14_FIX1   ((Q1n14) 16384)
 1 in Q1n14 format
 
-#define Q1n15_FIX1   ((Q1n15) 32768)
 1 in Q1n15 format
 
-#define Q16n16_FIX1   ((Q16n16) 65536)
 1 in Q16n16 format
 
-#define Q0n15_FIX1   ((Q0n15) 32767)
 0.999 in Q0n15 format
 
-#define Q0n16_FIX1   ((Q0n16) 65535)
 0.999 in Q0n16 format
 
-#define Q15n0_FIX1   ((Q15n0) 16384)
 1 in Q15n0 format
 
-#define Q15n16_FIX1   ((Q15n16) 65536)
 1 in Q15n16 format
 
-#define Q8n24_FIX1   ((Q8n24) 16777216)
 1 in Q8n24 format
 
-#define Q0n32_FIX1   ((Q0n32) 4294967295)
 0.999999999767169 in Q0n32 format
 
-#define Q16n16_PI   ((Q16n16) 205887)
 PI in Q16n16 format.
 
-#define Q3n13_2PI   ((Q3n13) 411775)
 2*PI in Q3n13 format
 
-#define Q16n16_2PI   ((Q16n16) 411775)
 2*PI in Q16n16 format
 
-#define low15bits   ((Q1n15) 32767)
 Useful for keeping the lower 15 bits of a Q1n15 number, using &.
 
uint8_t uint8_tMod (uint8_t n, uint8_t d)
 fast uint8_t modulus More...
 
uint8_t uint8_tDiv (uint8_t n, uint8_t d)
 Fast uint8_t division. More...
 
+uint8_t uint8_tRnd (uint8_t min, uint8_t max)
 
+int ipow (int base, int exp)
 
Q16n16 Q16n16_pow2 (Q8n8 exponent)
 fast replacement for pow(2,x), where x is a Q8n8 fractional fixed-point exponent. More...
 
+uint32_t isqrt32 (uint32_t n)
 
+uint16_t isqrt16 (uint16_t n)
 
Q0n7 float_to_Q0n7 (float a)
 Convert float to Q0n7 fix. More...
 Convert float to Q0n7 fix. More...
 
Q0n8 float_to_Q0n8 (float a)
 Convert float to Q0n8 fix. More...
 Convert float to Q0n8 fix. More...
 
Q7n8 float_to_Q7n8 (float a)
 Convert float to Q7n8 fix. More...
 Convert float to Q7n8 fix. More...
 
Q8n8 float_to_Q8n8 (float a)
 Convert float to Q8n8 fix. More...
 Convert float to Q8n8 fix. More...
 
Q1n14 float_to_Q1n14 (float a)
 Convert float to Q1n14 fix. More...
 Convert float to Q1n14 fix. More...
 
Q1n15 float_to_Q1n15 (float a)
 Convert float to Q1n15 fix. More...
 Convert float to Q1n15 fix. More...
 
Q8n24 float_to_Q8n24 (float a)
 Convert float to Q8n24 fix. More...
 Convert float to Q8n24 fix. More...
 
Q23n8 float_to_Q23n8 (float a)
 Convert float to Q23n8 fix. More...
 Convert float to Q23n8 fix. More...
 
Q24n8 float_to_Q24n8 (float a)
 Convert float to Q24n8 fix. More...
 Convert float to Q24n8 fix. More...
 
Q16n16 float_to_Q16n16 (float a)
 Convert float to Q16n16 fix. More...
 Convert float to Q16n16 fix. More...
 
Q0n16 float_to_Q0n16 (float a)
 Convert float to Q0n16 fix. More...
 Convert float to Q0n16 fix. More...
 
Q15n16 float_to_Q15n16 (float a)
 Convert float to Q15n16 fix. More...
 Convert float to Q15n16 fix. More...
 
Q1n14 Q0n7_to_Q1n14 (Q0n7 a)
 Convert Q0n7 int8_t to Q1n14 fix. More...
 Convert Q0n7 int8_t to Q1n14 fix. More...
 
Q15n16 Q0n7_to_Q15n16 (Q0n7 a)
 Convert Q0n7 signed int8_t to Q15n16 fix. More...
 Convert Q0n7 signed int8_t to Q15n16 fix. More...
 
float Q0n7_to_float (Q0n7 a)
 Convert Q0n7 fix to float. More...
 Convert Q0n7 fix to float. More...
 
Q1n15 Q0n8_to_Q1n15 (Q0n8 a)
 Convert Q0n8 uint8_t to Q1n15 fix. More...
 Convert Q0n8 uint8_t to Q1n15 fix. More...
 
Q8n8 Q0n8_to_Q8n8 (Q0n8 a)
 Convert Q0n8 uint8_t to Q8n8 fix. More...
 Convert Q0n8 uint8_t to Q8n8 fix. More...
 
Q8n24 Q0n8_to_Q8n24 (Q0n8 a)
 Convert Q0n8 uint8_t to Q8n24 fix. More...
 Convert Q0n8 uint8_t to Q8n24 fix. More...
 
Q24n8 Q0n8_to_Q24n8 (Q0n8 a)
 Convert Q0n8 uint8_t to Q24n8 fix. More...
 Convert Q0n8 uint8_t to Q24n8 fix. More...
 
Q15n16 Q0n8_to_Q15n16 (Q0n8 a)
 Convert Q0n8 uint8_t to Q15n16 fix. More...
 Convert Q0n8 uint8_t to Q15n16 fix. More...
 
Q16n16 Q0n8_to_Q16n16 (Q0n8 a)
 Convert Q0n8 uint8_t to Q16n16 fix. More...
 Convert Q0n8 uint8_t to Q16n16 fix. More...
 
float Q0n8_to_float (Q0n8 a)
 Convert Q0n8 fix to float. More...
 Convert Q0n8 fix to float. More...
 
Q7n8 Q7n0_to_Q7n8 (Q7n0 a)
 Convert Q7n0 int8_t to Q7n8 fix. More...
 Convert Q7n0 int8_t to Q7n8 fix. More...
 
Q15n16 Q7n0_to_Q15n16 (Q7n0 a)
 Convert Q7n0 int8_t to Q15n16 fix. More...
 Convert Q7n0 int8_t to Q15n16 fix. More...
 
Q7n8 Q8n0_to_Q7n8 (Q8n0 a)
 Convert Q8n0 uint8_t to Q7n8 fix. More...
 Convert Q8n0 uint8_t to Q7n8 fix. More...
 
Q8n8 Q8n0_to_Q8n8 (Q8n0 a)
 Convert uint8_t to Q8n8 fix. More...
 Convert uint8_t to Q8n8 fix. More...
 
Q15n16 Q8n0_to_Q15n16 (Q8n0 a)
 Convert Q8n0 uint8_t to Q15n16 fix. More...
 Convert Q8n0 uint8_t to Q15n16 fix. More...
 
Q16n16 Q8n0_to_Q16n16 (Q8n0 a)
 Convert Q8n0 uint8_t to Q16n16 fix. More...
 Convert Q8n0 uint8_t to Q16n16 fix. More...
 
Q7n0 Q7n8_to_Q7n0 (Q7n8 a)
 Convert Q7n8 fix to Q7n0. More...
 Convert Q7n8 fix to Q7n0. More...
 
Q15n16 Q7n8_to_Q15n16 (Q7n8 a)
 Convert Q7n8 fix to Q15n16. More...
 Convert Q7n8 fix to Q15n16. More...
 
float Q7n8_to_float (Q7n8 a)
 Convert Q7n8 fix to float. More...
 Convert Q7n8 fix to float. More...
 
Q8n0 Q8n8_to_Q8n0 (Q8n8 a)
 Convert Q8n8 fix to Q8n0 uint8_t. More...
 Convert Q8n8 fix to Q8n0 uint8_t. More...
 
Q16n16 Q8n8_to_Q16n16 (Q8n8 a)
 Convert Q8n8 fix to Q16n16 uint32_t. More...
 Convert Q8n8 fix to Q16n16 uint32_t. More...
 
float Q8n8_to_float (Q8n8 a)
 Convert Q8n8 fix to float. More...
 Convert Q8n8 fix to float. More...
 
Q0n7 Q1n14_to_Q0n7 (Q1n14 a)
 Convert Q1n14 fixed to Q0n7 int8_t. More...
 Convert Q1n14 fixed to Q0n7 int8_t. More...
 
float Q1n14_to_float (Q1n14 a)
 Convert fix to float. More...
 Convert fix to float. More...
 
Q0n8 Q1n15_to_Q0n8 (Q1n15 a)
 Convert Q1n15 fixed to Q0n8 uint8_t. More...
 Convert Q1n15 fixed to Q0n8 uint8_t. More...
 
float Q1n15_to_float (Q1n15 a)
 Convert fix to float. More...
 Convert fix to float. More...
 
float Q0n16_to_float (Q0n16 a)
 Convert fix to float. More...
 Convert fix to float. More...
 
Q15n16 Q15n0_to_Q15n16 (Q15n0 a)
 Convert Q15n0 int16_t to Q15n16 fix. More...
 Convert Q15n0 int16_t to Q15n16 fix. More...
 
Q15n16 Q16n0_to_Q15n16 (Q16n0 a)
 Convert Q16n0 uint16_t to Q15n16 fix. More...
 Convert Q16n0 uint16_t to Q15n16 fix. More...
 
Q23n8 Q16n0_to_Q23n8 (Q16n0 a)
 Convert Q16n0 uint16_t to Q23n8 fixed point signed int32_t. More...
 Convert Q16n0 uint16_t to Q23n8 fixed point signed int32_t. More...
 
Q24n8 Q16n0_to_Q24n8 (Q16n0 a)
 Convert Q16n0 uint16_t to Q24n8 fixed point uint32_t. More...
 Convert Q16n0 uint16_t to Q24n8 fixed point uint32_t. More...
 
Q16n16 Q16n0_to_Q16n16 (Q16n0 a)
 Convert Q16n0 uint16_t to Q16n16 fixed point uint32_t. More...
 Convert Q16n0 uint16_t to Q16n16 fixed point uint32_t. More...
 
float Q16n0_to_float (Q16n0 a)
 Convert Q16n0 uint16_t to float. More...
 Convert Q16n0 uint16_t to float. More...
 
Q0n8 Q8n24_to_Q0n8 (Q8n24 a)
 Convert Q8n24 fixed to Q0n8 uint8_t. More...
 Convert Q8n24 fixed to Q0n8 uint8_t. More...
 
float Q8n24_to_float (Q8n24 a)
 Convert fix to float. More...
 Convert fix to float. More...
 
Q31n0 Q23n8_to_Q31n0 (Q23n8 a)
 Convert Q23n8 fixed to Q31n0 int32_t. More...
 Convert Q23n8 fixed to Q31n0 int32_t. More...
 
Q16n0 Q23n8_to_Q16n0 (Q23n8 a)
 Convert Q23n8 fixed to Q16n0 uint16_t. More...
 Convert Q23n8 fixed to Q16n0 uint16_t. More...
 
Q15n0 Q23n8_to_Q15n0 (Q23n8 a)
 Convert Q23n8 fixed to Q15n0 signed int16_t. More...
 Convert Q23n8 fixed to Q15n0 signed int16_t. More...
 
Q7n8 Q23n8_to_Q7n8 (Q23n8 a)
 Convert Q23n8 fixed to Q7n8 signed int16_t, losing most significant bits. More...
 Convert Q23n8 fixed to Q7n8 signed int16_t, losing most significant bits. More...
 
float Q23n8_to_float (Q23n8 a)
 Convert fix to float. More...
 Convert fix to float. More...
 
Q0n8 Q24n8_to_Q0n8 (Q24n8 a)
 Convert Q24n8 fixed to Q0n8 uint8_t. More...
 Convert Q24n8 fixed to Q0n8 uint8_t. More...
 
Q16n16 Q24n8_to_Q16n0 (Q24n8 a)
 Convert Q24n8 fixed to Q16n0 uint16_t. More...
 Convert Q24n8 fixed to Q16n0 uint16_t. More...
 
Q32n0 Q24n8_to_Q32n0 (Q24n8 a)
 Convert Q24n8 fixed to Q32n0 uint32_t. More...
 Convert Q24n8 fixed to Q32n0 uint32_t. More...
 
Q16n16 Q24n8_to_Q16n16 (Q24n8 a)
 Convert Q24n8 fixed to Q16n16 uint32_t. More...
 Convert Q24n8 fixed to Q16n16 uint32_t. More...
 
float Q24n8_to_float (Q24n8 a)
 Convert fix to float. More...
 Convert fix to float. More...
 
Q0n8 Q15n16_to_Q0n8 (Q15n16 a)
 Convert Q15n16 fixed to Q0n8 uint8_t. More...
 Convert Q15n16 fixed to Q0n8 uint8_t. More...
 
Q8n0 Q15n16_to_Q8n0 (Q15n16 a)
 Convert Q15n16 fixed to Q8n0 uint8_t. More...
 Convert Q15n16 fixed to Q8n0 uint8_t. More...
 
Q15n0 Q15n16_to_Q15n0 (Q15n16 a)
 Convert Q15n16 fixed to Q15n0 signed int16_t. More...
 Convert Q15n16 fixed to Q15n0 signed int16_t. More...
 
Q7n8 Q15n16_to_Q7n8 (Q15n16 a)
 Convert Q15n16 fixed to Q7n8 signed int16_t, keeping middle bits only. More...
 Convert Q15n16 fixed to Q7n8 signed int16_t, keeping middle bits only. More...
 
Q8n8 Q15n16_to_Q8n8 (Q15n16 a)
 Convert Q15n16 fixed to Q8n8 signed int16_t, keeping middle bits only. More...
 Convert Q15n16 fixed to Q8n8 signed int16_t, keeping middle bits only. More...
 
Q23n8 Q15n16_to_Q23n8 (Q15n16 a)
 Convert Q15n16 fixed to Q23n8 signed int32_t. More...
 Convert Q15n16 fixed to Q23n8 signed int32_t. More...
 
float Q15n16_to_float (Q15n16 a)
 Convert fix to float. More...
 Convert fix to float. More...
 
Q0n8 Q16n16_to_Q0n8 (Q16n16 a)
 Convert Q16n16 fixed to Q0n8 uint8_t. More...
 Convert Q16n16 fixed to Q0n8 uint8_t. More...
 
Q8n8 Q16n16_to_Q8n8 (Q8n8 a)
 Convert Q16n16 fixed to Q8n8 uint16_t. More...
 Convert Q16n16 fixed to Q8n8 uint16_t. More...
 
Q16n0 Q16n16_to_Q16n0 (Q16n16 a)
 Convert Q16n16 fixed to Q16n0 uint16_t. More...
 Convert Q16n16 fixed to Q16n0 uint16_t. More...
 
Q24n8 Q16n16_to_Q24n8 (Q16n16 a)
 Convert Q16n16 fixed to Q24n8 uint32_t. More...
 Convert Q16n16 fixed to Q24n8 uint32_t. More...
 
float Q16n16_to_float (Q16n16 a)
 Convert fix to float. More...
 Convert fix to float. More...
 
+#define Q0n7_FIX1
 0.992 in Q0n7 format
 
+#define Q7n8_FIX1
 1 in Q7n8 format
 
+#define Q8n8_FIX1
 1 in Q8n8 format
 
+#define Q23n8_FIX1
 1 in Q23n8 format
 
+#define Q1n14_FIX1
 1 in Q1n14 format
 
+#define Q1n15_FIX1
 1 in Q1n15 format
 
+#define Q16n16_FIX1
 1 in Q16n16 format
 
+#define Q0n15_FIX1
 0.999 in Q0n15 format
 
+#define Q0n16_FIX1
 0.999 in Q0n16 format
 
+#define Q15n0_FIX1
 1 in Q15n0 format
 
+#define Q15n16_FIX1
 1 in Q15n16 format
 
+#define Q8n24_FIX1
 1 in Q8n24 format
 
+#define Q0n32_FIX1
 0.999999999767169 in Q0n32 format
 
+#define Q16n16_PI
 PI in Q16n16 format.
 
+#define Q3n13_2PI
 2*PI in Q3n13 format
 
+#define Q16n16_2PI
 2*PI in Q16n16 format
 
+#define low15bits
 Useful for keeping the lower 15 bits of a Q1n15 number, using &.
 
-

Detailed Description

-

Fixed point fractional number types and conversion routines.

-

Fixed point is often best for fast audio code for Arduino, and these can ease some of the pain.

Note
Take care when converting that the important bits of your numbers will fit in the types you choose!
-
-Timing: converting between fixed and float 10-12us, converting between fixed types about 1us.

Function Documentation

◆ float_to_Q0n16()

@@ -539,7 +534,7 @@

Definition at line 124 of file mozzi_fixmath.h.

+

Definition at line 130 of file mozzi_fixmath.h.

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

Definition at line 94 of file mozzi_fixmath.h.

+

Definition at line 100 of file mozzi_fixmath.h.

@@ -611,7 +606,7 @@

Definition at line 97 of file mozzi_fixmath.h.

+

Definition at line 103 of file mozzi_fixmath.h.

@@ -647,7 +642,7 @@

Definition at line 127 of file mozzi_fixmath.h.

+

Definition at line 133 of file mozzi_fixmath.h.

@@ -683,7 +678,7 @@

Definition at line 121 of file mozzi_fixmath.h.

+

Definition at line 127 of file mozzi_fixmath.h.

@@ -719,7 +714,7 @@

Definition at line 106 of file mozzi_fixmath.h.

+

Definition at line 112 of file mozzi_fixmath.h.

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

Definition at line 109 of file mozzi_fixmath.h.

+

Definition at line 115 of file mozzi_fixmath.h.

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

Definition at line 115 of file mozzi_fixmath.h.

+

Definition at line 121 of file mozzi_fixmath.h.

@@ -827,7 +822,7 @@

Definition at line 118 of file mozzi_fixmath.h.

+

Definition at line 124 of file mozzi_fixmath.h.

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

Definition at line 100 of file mozzi_fixmath.h.

+

Definition at line 106 of file mozzi_fixmath.h.

@@ -899,7 +894,7 @@

Definition at line 112 of file mozzi_fixmath.h.

+

Definition at line 118 of file mozzi_fixmath.h.

@@ -935,7 +930,7 @@

Definition at line 103 of file mozzi_fixmath.h.

+

Definition at line 109 of file mozzi_fixmath.h.

@@ -971,7 +966,7 @@

Definition at line 208 of file mozzi_fixmath.h.

+

Definition at line 214 of file mozzi_fixmath.h.

@@ -1007,7 +1002,7 @@

Definition at line 136 of file mozzi_fixmath.h.

+

Definition at line 142 of file mozzi_fixmath.h.

@@ -1043,7 +1038,7 @@

Definition at line 133 of file mozzi_fixmath.h.

+

Definition at line 139 of file mozzi_fixmath.h.

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

Definition at line 130 of file mozzi_fixmath.h.

+

Definition at line 136 of file mozzi_fixmath.h.

@@ -1115,7 +1110,7 @@

Definition at line 157 of file mozzi_fixmath.h.

+

Definition at line 163 of file mozzi_fixmath.h.

@@ -1151,7 +1146,7 @@

Definition at line 151 of file mozzi_fixmath.h.

+

Definition at line 157 of file mozzi_fixmath.h.

@@ -1187,7 +1182,7 @@

Definition at line 154 of file mozzi_fixmath.h.

+

Definition at line 160 of file mozzi_fixmath.h.

@@ -1223,7 +1218,7 @@

Definition at line 139 of file mozzi_fixmath.h.

+

Definition at line 145 of file mozzi_fixmath.h.

@@ -1259,7 +1254,7 @@

Definition at line 148 of file mozzi_fixmath.h.

+

Definition at line 154 of file mozzi_fixmath.h.

@@ -1295,7 +1290,7 @@

Definition at line 145 of file mozzi_fixmath.h.

+

Definition at line 151 of file mozzi_fixmath.h.

@@ -1331,7 +1326,7 @@

Definition at line 142 of file mozzi_fixmath.h.

+

Definition at line 148 of file mozzi_fixmath.h.

@@ -1367,7 +1362,7 @@

Definition at line 211 of file mozzi_fixmath.h.

+

Definition at line 217 of file mozzi_fixmath.h.

@@ -1403,7 +1398,7 @@

Definition at line 285 of file mozzi_fixmath.h.

+

Definition at line 291 of file mozzi_fixmath.h.

@@ -1439,7 +1434,7 @@

Definition at line 267 of file mozzi_fixmath.h.

+

Definition at line 273 of file mozzi_fixmath.h.

@@ -1475,7 +1470,7 @@

Definition at line 273 of file mozzi_fixmath.h.

+

Definition at line 279 of file mozzi_fixmath.h.

@@ -1511,7 +1506,7 @@

Definition at line 282 of file mozzi_fixmath.h.

+

Definition at line 288 of file mozzi_fixmath.h.

@@ -1547,7 +1542,7 @@

Definition at line 276 of file mozzi_fixmath.h.

+

Definition at line 282 of file mozzi_fixmath.h.

@@ -1583,7 +1578,7 @@

Definition at line 270 of file mozzi_fixmath.h.

+

Definition at line 276 of file mozzi_fixmath.h.

@@ -1619,7 +1614,7 @@

Definition at line 279 of file mozzi_fixmath.h.

+

Definition at line 285 of file mozzi_fixmath.h.

@@ -1655,7 +1650,7 @@

Definition at line 226 of file mozzi_fixmath.h.

+

Definition at line 232 of file mozzi_fixmath.h.

@@ -1691,7 +1686,7 @@

Definition at line 214 of file mozzi_fixmath.h.

+

Definition at line 220 of file mozzi_fixmath.h.

@@ -1727,7 +1722,7 @@

Definition at line 223 of file mozzi_fixmath.h.

+

Definition at line 229 of file mozzi_fixmath.h.

@@ -1763,7 +1758,7 @@

Definition at line 217 of file mozzi_fixmath.h.

+

Definition at line 223 of file mozzi_fixmath.h.

@@ -1799,7 +1794,7 @@

Definition at line 220 of file mozzi_fixmath.h.

+

Definition at line 226 of file mozzi_fixmath.h.

@@ -1819,8 +1814,7 @@

-


-fast replacement for pow(2,x), where x is a Q8n8 fractional fixed-point exponent.

+

fast replacement for pow(2,x), where x is a Q8n8 fractional fixed-point exponent.

It's less accurate than pow(2,x), but useful where a tradeoff between accuracy and speed is required to keep audio from glitching.

Parameters
@@ -1829,7 +1823,7 @@

Returns
pow(2,x) in Q16n16 format.
-

Definition at line 105 of file mozzi_fixmath.cpp.

+

Definition at line 116 of file mozzi_fixmath.cpp.

@@ -1865,7 +1859,7 @@

Definition at line 300 of file mozzi_fixmath.h.

+

Definition at line 306 of file mozzi_fixmath.h.

@@ -1901,7 +1895,7 @@

Definition at line 288 of file mozzi_fixmath.h.

+

Definition at line 294 of file mozzi_fixmath.h.

@@ -1937,7 +1931,7 @@

Definition at line 294 of file mozzi_fixmath.h.

+

Definition at line 300 of file mozzi_fixmath.h.

@@ -1973,7 +1967,7 @@

Definition at line 297 of file mozzi_fixmath.h.

+

Definition at line 303 of file mozzi_fixmath.h.

@@ -2009,7 +2003,7 @@

Definition at line 291 of file mozzi_fixmath.h.

+

Definition at line 297 of file mozzi_fixmath.h.

@@ -2045,7 +2039,7 @@

Definition at line 199 of file mozzi_fixmath.h.

+

Definition at line 205 of file mozzi_fixmath.h.

@@ -2081,7 +2075,7 @@

Definition at line 196 of file mozzi_fixmath.h.

+

Definition at line 202 of file mozzi_fixmath.h.

@@ -2117,7 +2111,7 @@

Definition at line 205 of file mozzi_fixmath.h.

+

Definition at line 211 of file mozzi_fixmath.h.

@@ -2153,7 +2147,7 @@

Definition at line 202 of file mozzi_fixmath.h.

+

Definition at line 208 of file mozzi_fixmath.h.

@@ -2189,7 +2183,7 @@

Definition at line 249 of file mozzi_fixmath.h.

+

Definition at line 255 of file mozzi_fixmath.h.

@@ -2225,7 +2219,7 @@

Definition at line 242 of file mozzi_fixmath.h.

+

Definition at line 248 of file mozzi_fixmath.h.

@@ -2261,7 +2255,7 @@

Definition at line 239 of file mozzi_fixmath.h.

+

Definition at line 245 of file mozzi_fixmath.h.

@@ -2297,7 +2291,7 @@

Definition at line 236 of file mozzi_fixmath.h.

+

Definition at line 242 of file mozzi_fixmath.h.

@@ -2333,7 +2327,7 @@

Definition at line 245 of file mozzi_fixmath.h.

+

Definition at line 251 of file mozzi_fixmath.h.

@@ -2369,7 +2363,7 @@

Definition at line 264 of file mozzi_fixmath.h.

+

Definition at line 270 of file mozzi_fixmath.h.

@@ -2405,7 +2399,7 @@

Definition at line 252 of file mozzi_fixmath.h.

+

Definition at line 258 of file mozzi_fixmath.h.

@@ -2441,7 +2435,7 @@

Definition at line 255 of file mozzi_fixmath.h.

+

Definition at line 261 of file mozzi_fixmath.h.

@@ -2477,7 +2471,7 @@

Definition at line 261 of file mozzi_fixmath.h.

+

Definition at line 267 of file mozzi_fixmath.h.

@@ -2513,7 +2507,7 @@

Definition at line 258 of file mozzi_fixmath.h.

+

Definition at line 264 of file mozzi_fixmath.h.

@@ -2549,7 +2543,7 @@

Definition at line 163 of file mozzi_fixmath.h.

+

Definition at line 169 of file mozzi_fixmath.h.

@@ -2585,7 +2579,7 @@

Definition at line 160 of file mozzi_fixmath.h.

+

Definition at line 166 of file mozzi_fixmath.h.

@@ -2633,7 +2627,7 @@

Returns
a Q7n8 format product
-

Definition at line 340 of file mozzi_fixmath.h.

+

Definition at line 346 of file mozzi_fixmath.h.

@@ -2669,7 +2663,7 @@

Definition at line 184 of file mozzi_fixmath.h.

+

Definition at line 190 of file mozzi_fixmath.h.

@@ -2705,7 +2699,7 @@

Definition at line 181 of file mozzi_fixmath.h.

+

Definition at line 187 of file mozzi_fixmath.h.

@@ -2741,7 +2735,7 @@

Definition at line 178 of file mozzi_fixmath.h.

+

Definition at line 184 of file mozzi_fixmath.h.

@@ -2777,7 +2771,7 @@

Definition at line 172 of file mozzi_fixmath.h.

+

Definition at line 178 of file mozzi_fixmath.h.

@@ -2813,7 +2807,7 @@

Definition at line 175 of file mozzi_fixmath.h.

+

Definition at line 181 of file mozzi_fixmath.h.

@@ -2849,7 +2843,7 @@

Definition at line 166 of file mozzi_fixmath.h.

+

Definition at line 172 of file mozzi_fixmath.h.

@@ -2885,7 +2879,7 @@

Definition at line 169 of file mozzi_fixmath.h.

+

Definition at line 175 of file mozzi_fixmath.h.

@@ -2921,7 +2915,7 @@

Definition at line 232 of file mozzi_fixmath.h.

+

Definition at line 238 of file mozzi_fixmath.h.

@@ -2957,7 +2951,7 @@

Definition at line 229 of file mozzi_fixmath.h.

+

Definition at line 235 of file mozzi_fixmath.h.

@@ -2993,7 +2987,7 @@

Definition at line 193 of file mozzi_fixmath.h.

+

Definition at line 199 of file mozzi_fixmath.h.

@@ -3029,7 +3023,7 @@

Definition at line 190 of file mozzi_fixmath.h.

+

Definition at line 196 of file mozzi_fixmath.h.

@@ -3065,7 +3059,7 @@

Definition at line 187 of file mozzi_fixmath.h.

+

Definition at line 193 of file mozzi_fixmath.h.

@@ -3105,7 +3099,7 @@

Returns
quotient
-

Definition at line 37 of file mozzi_fixmath.cpp.

+

Definition at line 48 of file mozzi_fixmath.cpp.

@@ -3135,8 +3129,7 @@

-


-fast uint8_t modulus

+

fast uint8_t modulus

Parameters

exponentin Q8n8 format.
@@ -3146,19 +3139,14 @@

Returns
modulus
-

Definition at line 25 of file mozzi_fixmath.cpp.

+

Definition at line 36 of file mozzi_fixmath.cpp.

- -

@@ -61,10 +57,10 @@
nnumerator
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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -102,37 +98,61 @@
-
Midi
+
Midi note number to frequency conversions
-

Midi note number to frequency conversions. +

Useful if you like playing notes in tune. More...

+

Detailed Description

+

Useful if you like playing notes in tune.

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

Functions

float mtof (float midival)
 Converts midi note number to frequency. More...
 Converts midi note number to frequency. More...
 
Q16n16 Q16n16_mtof (Q16n16 midival_fractional)
 Converts midi note number to frequency with speed and accuracy. More...
 
int mtof (uint8_t midi_note)
 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 midi_note)
 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 midival_fractional)
 Converts midi note number to frequency with speed and accuracy. More...
 
template<uint64_t RANGE>
UFix< 16, 16 > mtof (UFix< 16, 16, RANGE > midival)
 Converts midi note number with speed and accuracy from a UFix<16,16>. More...
 
template<int8_t NI, int8_t NF, uint64_t RANGE>
UFix< 16, 16 > mtof (UFix< NI, NF, RANGE > midival)
 Converts midi note number with speed and accuracy from any UFix. More...
 
template<int8_t NI, int8_t NF, uint64_t RANGE>
UFix< 16, 16 > mtof (SFix< NI, NF, RANGE > midival)
 Converts midi note number with speed and accuracy from any SFix. More...
 
+template<int8_t NI, uint64_t RANGE>
UFix< 16, 16 > mtof (UFix< NI, 0, RANGE > midival)
 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 > midival)
 Converts whole midi note number with speed and accuracy (more accurate that mtof(uint8_t))
 
-

Detailed Description

-

Midi note number to frequency conversions.

-

Useful if you like playing notes in tune.

Function Documentation

-

◆ mtof() [1/3]

+

◆ mtof() [1/6]

+ + + @@ -61,10 +57,10 @@
@@ -142,10 +162,15 @@

+inline +

+
float mtof

Converts midi note number to frequency.

-

Caution: this can take up to 400 microseconds to run. It can seriously mess up the audio output if you use it in updateControl() or updateAudio(). This is a good choice in setup(), or where you need precise midi-pitch conversion and aren't doing much other audio calculation.

Note
Beware this returns an invalid result for midi note 0.
+

Caution: this can take up to 400 microseconds to run. It can seriously mess up the audio output if you use it in updateControl() or updateAudio(). This is a good choice in setup(), or where you need precise midi-pitch conversion and aren't doing much other audio calculation.

Note
Beware this returns an invalid result for midi note 0.
Timing: ~350 us
Parameters
@@ -156,24 +181,32 @@

Returns
the frequency represented by the input midi note number..

-

Definition at line 18 of file mozzi_midi.cpp.

+

Definition at line 75 of file mozzi_midi.h.

- -

◆ mtof() [2/3]

+ +

◆ mtof() [2/6]

+ + + + + +
- +
int mtof (uint8_t int  midi_note)
+
+inline

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

@@ -185,24 +218,131 @@

Returns
an integer approximation of the midi note's frequency.
-

Definition at line 156 of file mozzi_midi.cpp.

+

Definition at line 102 of file mozzi_midi.h.

- -

◆ mtof() [3/3]

+ +

◆ mtof() [3/6]

+ +
+
+
+template<int8_t NI, int8_t NF, uint64_t RANGE>
+ + + + + +
+ + + + + + + + +
UFix<16,16> mtof (SFix< NI, NF, RANGE > midival)
+
+inline
+
+ +

Converts midi note number with speed and accuracy from any SFix.

+

Uses Q16n16_mtof internally.

+ +

Definition at line 163 of file mozzi_midi.h.

+ +
+
+ +

◆ mtof() [4/6]

+ +
+
+
+template<uint64_t RANGE>
+ + + + + +
+ + + + + + + + +
UFix<16,16> mtof (UFix< 16, 16, RANGE > midival)
+
+inline
+
+ +

Converts midi note number with speed and accuracy from a UFix<16,16>.

+

Uses Q16n16_mtof internally.

+ +

Definition at line 143 of file mozzi_midi.h.

+ +
+
+ +

◆ mtof() [5/6]

+ +
+
+
+template<int8_t NI, int8_t NF, uint64_t RANGE>
+ + + + + +
+ + + + + + + + +
UFix<16,16> mtof (UFix< NI, NF, RANGE > midival)
+
+inline
+
+ +

Converts midi note number with speed and accuracy from any UFix.

+

Uses Q16n16_mtof internally.

+ +

Definition at line 153 of file mozzi_midi.h.

+ +
+
+ +

◆ mtof() [6/6]

+ + + + + +
- +
int mtof (int uint8_t  midi_note)
+
+inline

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

@@ -214,7 +354,7 @@

Returns
an integer approximation of the midi note's frequency.
-

Definition at line 166 of file mozzi_midi.cpp.

+

Definition at line 93 of file mozzi_midi.h.

@@ -223,6 +363,9 @@

+ + + @@ -61,10 +57,10 @@
@@ -232,10 +375,15 @@

+inline +

+
Q16n16 Q16n16_mtof

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
@@ -244,19 +392,14 @@

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 132 of file mozzi_midi.cpp.

+

Definition at line 119 of file mozzi_midi.h.

- -

@@ -61,10 +57,10 @@
midival_fractionala midi note number in Q16n16 format, for fractional values.
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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -102,121 +98,122 @@
-
Random
+
Fast random number generator functions
-

Fast random number generator functions. +

These replace Arduino random() which is so slow it will stop your audio. More...

+

Detailed Description

+

These replace Arduino random() which is so slow it will stop your audio.

+

They can even be used to generate audio noise.

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

Functions

unsigned long xorshift96 ()
 Random number generator. More...
 
void randSeed (long seed)
 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function. More...
 
uint32_t xorshift96 ()
 Random number generator. More...
 
void randSeed (uint32_t seed)
 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used in Mozzi's rand() function. More...
 
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 xorshiftSeed (long seed)
 Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number. More...
 
void xorshiftSeed (uint32_t seed)
 Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number. More...
 
int8_t rand (int8_t minval, int8_t maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
uint8_t rand (uint8_t minval, uint8_t maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
int rand (int minval, int maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
unsigned int rand (unsigned int minval, unsigned int maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
int8_t rand (int8_t maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
uint8_t rand (uint8_t minval, uint8_t maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
uint8_t rand (uint8_t maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
int rand (int minval, int maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
int rand (int maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
unsigned int rand (unsigned int minval, unsigned int maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
unsigned int rand (unsigned int maxval)
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi. More...
 
uint8_t randMidiNote ()
 Generates a random number in the range for midi notes. More...
 Generates a random number in the range for midi notes. More...
 
unsigned int randPrime (unsigned int n)
 Generates a random prime number between 0 and the n-1th prime number. More...
 Generates a random prime number between 0 and the n-1th prime number. More...
 
unsigned int randPrimeUpTo (unsigned int n)
 Generates a random prime number between 0 and the given input number inclusive. More...
 Generates a random prime number between 0 and the given input number inclusive. More...
 
-

Detailed Description

-

Fast random number generator functions.

-

These replace Arduino random() which is so slow it will stop your audio. They can even be used to generate audio noise.

Function Documentation

- -

◆ rand() [1/8]

+ +

◆ rand() [1/8]

+ + + + + +
- + - - - - - - - - - - + + - -
int8_t rand int rand (int8_t minval,
int8_t maxval 
int maxval) )
+
+inline

Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.

Parameters
- - +
minvalthe minimum signed uint8_t value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
maxvalthe maximum signed uint8_t value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
maxvalthe maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
-
Returns
a random int8_t between minval and maxval-1 inclusive.
+
Returns
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.
-

Definition at line 171 of file mozzi_rand.cpp.

+

Definition at line 130 of file mozzi_rand.h.

- -

◆ rand() [2/8]

+ +

◆ rand() [2/8]

+ + + +constexpr
- + - + - + @@ -225,78 +222,84 @@

+inline +

+
uint8_t rand int rand (uint8_t int  minval,
uint8_t int  maxval 
- -

◆ rand() [3/8]

+ +

◆ rand() [3/8]

+ + + + + +
- + - - - - - - - - - - + + - -
int rand int8_t rand (int minval,
int maxval 
int8_t maxval) )
+
+inline

Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.

Parameters
- - +
minvalthe minimum signed int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
maxvalthe maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
maxvalthe maximum signed byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
-
Returns
a random int between minval and maxval-1 inclusive.
+
Returns
a random signed byte between 0 and maxval-1 inclusive.
-

Definition at line 195 of file mozzi_rand.cpp.

+

Definition at line 84 of file mozzi_rand.h.

- -

◆ rand() [4/8]

+ +

◆ rand() [4/8]

+ + + @@ -61,10 +57,10 @@
- + - + - + @@ -305,135 +308,195 @@

+inline +

+
unsigned int rand int8_t rand (unsigned int int8_t  minval,
unsigned int int8_t  maxval 
- -

◆ rand() [5/8]

+ +

◆ rand() [5/8]

+ + + + + +
- + - +
int8_t rand uint8_t rand (int8_t uint8_t  maxval)
+
+inline

Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.

Parameters
- +
maxvalthe maximum signed uint8_t value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
maxvalthe maximum unsigned byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
-
Returns
a random int8_t between 0 and maxval-1 inclusive.
+
Returns
a random unsigned byte between 0 and maxval-1 inclusive.
-

Definition at line 218 of file mozzi_rand.cpp.

+

Definition at line 105 of file mozzi_rand.h.

- -

◆ rand() [6/8]

+ +

◆ rand() [6/8]

+ + + + + +
- + + + + + + + + + + +
uint8_t rand ( uint8_t maxval)minval,
uint8_t maxval 
)
+
+inline

Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.

Parameters
- + +
maxvalthe maximum unsigned uint8_t value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
minvalthe minimum unsigned byte value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
maxvalthe maximum unsigned byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
-
Returns
a random uint8_t between 0 and maxval-1 inclusive.
+
Returns
a random unsigned byte between minval and maxval-1 inclusive.
-

Definition at line 229 of file mozzi_rand.cpp.

+

Definition at line 95 of file mozzi_rand.h.

- -

◆ rand() [7/8]

+ +

◆ rand() [7/8]

+ + + + + +
- + - +
int rand unsigned int rand (int unsigned int  maxval)
+
+inline

Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.

Parameters
- +
maxvalthe maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
maxvalthe maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
-
Returns
a random int between 0 and maxval-1 inclusive.
+
Returns
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.
-

Definition at line 240 of file mozzi_rand.cpp.

+

Definition at line 153 of file mozzi_rand.h.

- -

◆ rand() [8/8]

+ +

◆ rand() [8/8]

+ + + + + +
- + + + + + + + + + + +
unsigned int rand ( unsigned int maxval)minval,
unsigned int maxval 
)
+
+inline

Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.

Parameters
+
minvalthe minimum unsigned int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
maxvalthe maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
-
Returns
a random unsigned int between 0 and maxval-1 inclusive.
+
Returns
a random unsigned int between minval and maxval-1 inclusive.
-

Definition at line 251 of file mozzi_rand.cpp.

+

Definition at line 141 of file mozzi_rand.h.

@@ -442,6 +505,9 @@

+ + + @@ -61,10 +57,10 @@
@@ -450,12 +516,17 @@

+inline +

+
uint8_t randMidiNote
@@ -535,116 +606,143 @@

-

◆ randSeed() [1/2]

+ +

◆ randSeed() [1/2]

+ + + + + +
- - +
void randSeed (long seed))
+
+inline
-

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.
-
-
+

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 53 of file mozzi_rand.cpp.

+

Definition at line 59 of file mozzi_rand.h.

- -

◆ randSeed() [2/2]

+ +

◆ randSeed() [2/2]

+ + + + + +
- + +
void randSeed ()uint32_t seed)
+
+inline
-

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
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.
+

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 117 of file mozzi_rand.cpp.

+

Definition at line 41 of file mozzi_rand.h.

- -

◆ xorshift96()

+ +

◆ xorshift96()

+ + + + + +
- +
unsigned long xorshift96 uint32_t xorshift96 ( )
+
+inline

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.
+

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 26 of file mozzi_rand.cpp.

+

Definition at line 30 of file mozzi_rand.h.

- -

◆ xorshiftSeed()

+ +

◆ xorshiftSeed()

+ + + + + +
- +
void xorshiftSeed (long uint32_t  seed)
+
+inline
-

Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number.

+

Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number.

Parameters
- +
seeda number to use as a seed.
seeda number to use as a seed. TODO: duplicate deprecate / remove
-

Definition at line 158 of file mozzi_rand.cpp.

+

Definition at line 66 of file mozzi_rand.h.

- -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -100,23 +96,18 @@
-
Soundtables
+
Look-up-tables and python scripts to generate tables or convert sounds.

Look-up-tables and python scripts to generate tables or convert sounds. -More...

+

Look-up-tables and python scripts to generate tables or convert sounds.

-

Includes ready-to-use wave tables and a few example samples which are in the Mozzi/tables and Mozzi/samples folders. You can convert your own sounds from a program like Audacity to tables for Mozzi with a script called char2mozzi.py, in Mozzi/python. Read the int8_t2mozzi.py file for instructions. Also check out the other scripts in the python folder for templates to use if you want to do your own thing.

+

Includes ready-to-use wave tables and a few example samples which are in the Mozzi/tables and Mozzi/samples folders. You can convert your own sounds from a program like Audacity to tables for Mozzi with a script called char2mozzi.py, in Mozzi/python. Read the int8_t2mozzi.py file for instructions. Also check out the other scripts in the python folder for templates to use if you want to do your own thing.

- -

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)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -104,167 +100,109 @@ Classes | Functions
-
Util
+
Utility functions, and debugging

Utility functions. More...

+

Detailed Description

+

Utility functions.

+

Includes functions for debugging and profiling high frequency code with an oscilloscope when serial is too slow, some miscellaneous functions used internally by Mozzi, python scripts for converting or generating sound tables, and assorted meta-programming utils.

- +

Files

file  char2mozzi.py
 
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.
 
+ + +

Classes

struct  IntegerType< BYTES >
 Provides appropriate integer types that can bit the given number of bytes on this platform (at most 64). More...
 
struct  Int2Type< I >
 Enables you to instantiate a template based on an integer value. More...
 
- - - - - + + - - + + - - + + + + +

Functions

unsigned int BPMtoMillis (float bpm)
 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. More...
 
void setPin13Out ()
 Set digital pin 13 to output for testing timing with an oscilloscope. More...
+void setPin13Out ()
 Set digital pin 13 to output for testing timing with an oscilloscope.
 
void setPin13High ()
 Set pin 13 high for testing timing with an oscilloscope. More...
+void setPin13High ()
 Set pin 13 high for testing timing with an oscilloscope.
 
void setPin13Low ()
 Set pin 13 low for testing timing with an oscilloscope. More...
+void setPin13Low ()
 Set pin 13 low for testing timing with an oscilloscope.
 
constexpr uint8_t trailingZerosConst (unsigned long v)
 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. More...
 
-

Detailed Description

-

Utility functions.

-

Includes functions for debugging and profiling high frequency code with an oscilloscope when serial is too slow, some miscellaneous functions used internally by Mozzi, and python scripts for converting or generating sound tables.


Class Documentation

- -

◆ Int2Type

+ +

◆ IntegerType

- +
struct Int2Typestruct IntegerType
-

template<int I>
-struct Int2Type< I >

+

template<uint8_t BYTES>
+struct IntegerType< BYTES >

-

Enables you to instantiate a template based on an integer value.

-

For example, this is used in StateVariable.h to choose a different next() function for each kind of filter, LOWPASS, BANDPASS, HIGHPASS or NOTCH, which are simple integer values 0,1,2,3 provided to the StateVariable template on instantiation. Fantastic! It's in C++11, but not yet available in avr-gcc. See "c++ enable_if"

+

Provides appropriate integer types that can bit the given number of bytes on this platform (at most 64).

-

Definition at line 20 of file meta.h.

+

Definition at line 20 of file IntegerType.h.

- - + + + +

Public Types

enum  { value = I - }
 
+typedef IntegerType<(BYTES< 8) ?(BYTES+1) :8 >::unsigned_type unsigned_type
 
+typedef IntegerType<(BYTES< 8) ?(BYTES+1) :8 >::signed_type signed_type
 
-

Function Documentation

- -

◆ BPMtoMillis()

- -
-
- - - - - - - - -
unsigned int BPMtoMillis (float bpm)
-
- -

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.

-
Parameters
- - -
apower of 2, or any other number for that matter
-
-
-
Returns
the number of trailing zeros on the right hand end Convert BPM to milliseconds, which can be used to set the delay between beats for Metronome.
-
Parameters
- - -
bpmbeats per minute
-
-
- -

Definition at line 33 of file mozzi_utils.cpp.

- -
-
- -

◆ setPin13High()

+ +

◆ Int2Type

- - - - - -
- - - - +
void setPin13High ()struct Int2Type
-
-inline
+

template<int I>
+struct Int2Type< I >

-

Set pin 13 high for testing timing with an oscilloscope.

- -

Definition at line 39 of file mozzi_utils.h.

- -
-
- -

◆ setPin13Low()

+

Enables you to instantiate a template based on an integer value.

+

For example, this is used in StateVariable.h to choose a different next() function for each kind of filter, LOWPASS, BANDPASS, HIGHPASS or NOTCH, which are simple integer values 0,1,2,3 provided to the StateVariable template on instantiation. Fantastic! It's in C++11, but not yet available in avr-gcc. See "c++ enable_if"

-
-
- - - - - +

Definition at line 40 of file meta.h.

+
- - - - - - - -
void setPin13Low ()
-
-inline
+ + +

Public Types

enum  { value + }
 
-
- -

Set pin 13 low for testing timing with an oscilloscope.

- -

Definition at line 52 of file mozzi_utils.h.

- -

◆ setPin13Out()

+

Function Documentation

+ +

◆ trailingZerosConst()

-inline
-

Set digital pin 13 to output for testing timing with an oscilloscope.

+

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.

+
Parameters
+ + +
apower of 2, or any other number for that matter
+
+
+
Returns
the number of trailing zeros on the right hand end
-

Definition at line 26 of file mozzi_utils.h.

+

Definition at line 73 of file mozzi_utils.h.

- -
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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -103,24 +99,139 @@
hardware_defines.h
-
1 #ifndef HARDWARE_DEFINES_H_
2 #define HARDWARE_DEFINES_H_
3 
4 #if ARDUINO >= 100
5  #include "Arduino.h"
6 #else
7  #include "WProgram.h"
8 #endif
9 
10 /* Macros to tell apart the supported platforms. The advantages of using these are, rather than the underlying defines
11 - Easier to read and write
12 - Compiler protection against typos
13 - Easy to extend for new but compatible boards */
14 
15 #define IS_AVR() (defined(__AVR__)) // "Classic" Arduino boards
16 #define IS_SAMD21() (defined(ARDUINO_ARCH_SAMD))
17 #define IS_TEENSY3() (defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__)) // 32bit arm-based Teensy
18 #define IS_TEENSY4() (defined(__IMXRT1062__)) // Teensy4 (no DAC)
19 #define IS_STM32() (defined(__arm__) && !IS_TEENSY3() && !IS_SAMD21() && !IS_TEENSY4() && !IS_RP2040()) // STM32 boards (note that only the maple based core is supported at this time. If another cores is to be supported in the future, this define should be split.
20 #define IS_ESP8266() (defined(ESP8266))
21 #define IS_ESP32() (defined(ESP32))
22 #define IS_RP2040() (defined(ARDUINO_ARCH_RP2040))
23 
24 #if !(IS_AVR() || IS_TEENSY3() || IS_TEENSY4() || IS_STM32() || IS_ESP8266() || IS_SAMD21() || IS_ESP32() || IS_RP2040())
25 #error Your hardware is not supported by Mozzi or not recognized. Edit hardware_defines.h to proceed.
26 #endif
27 
28 // Hardware detail defines
29 #if IS_STM32()
30 #define NUM_ANALOG_INPUTS 16 // probably wrong, but mostly needed to allocate an array of readings
31 #elif IS_ESP8266()
32 #define NUM_ANALOG_INPUTS 1
33 #endif
34 
35 #if IS_AVR()
36 #define AUDIO_RATE_PLATFORM_DEFAULT 16384
37 #else
38 #define AUDIO_RATE_PLATFORM_DEFAULT 32768
39 #endif
40 
41 #if IS_ESP8266()
42 #define CACHED_FUNCTION_ATTR ICACHE_RAM_ATTR
43 #elif IS_ESP32()
44 #define CACHED_FUNCTION_ATTR IRAM_ATTR
45 #else
46 #define CACHED_FUNCTION_ATTR
47 #endif
48 
49 #if IS_STM32()
50 // 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).
51 // Putting it here, instead, seem to work.
52 #include <STM32ADC.h>
53 #endif
54 
55 #endif /* HARDWARE_DEFINES_H_ */
#define IS_SAMD21()
-
#define IS_TEENSY4()
-
#define IS_STM32()
-
#define IS_AVR()
-
#define IS_TEENSY3()
-
#define IS_RP2040()
-
#define IS_ESP8266()
-
#define IS_ESP32()
+
1 /*
+
2  * hardware_defines.h.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 
+
13 #ifndef HARDWARE_DEFINES_H_
+
14 #define HARDWARE_DEFINES_H_
+
15 
+
16 #include "Arduino.h"
+
17 
+
18 /* Macros to tell apart the supported platforms. The advantages of using these are, rather than the underlying defines
+
19 - Easier to read and write
+
20 - Compiler protection against typos
+
21 - Easy to extend for new but compatible boards */
+
22 
+
23 // "Classic" Arduino boards
+
24 #if (defined(__AVR__))
+
25 #define IS_AVR() 1
+
26 #else
+
27 #define IS_AVR() 0
+
28 #endif
+
29 
+
30 // SAMD
+
31 #if (defined(ARDUINO_ARCH_SAMD))
+
32 #define IS_SAMD21() 1
+
33 #else
+
34 #define IS_SAMD21() 0
+
35 #endif
+
36 
+
37 // 32bit arm-based Teensy
+
38 #if (defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__))
+
39 #define IS_TEENSY3() 1
+
40 #else
+
41 #define IS_TEENSY3() 0
+
42 #endif
+
43 
+
44 // Teensy4 (no DAC)
+
45 #if (defined(__IMXRT1062__))
+
46 #define IS_TEENSY4() 1
+
47 #else
+
48 #define IS_TEENSY4() 0
+
49 #endif
+
50 
+
51 // RP2040 (Raspberry Pi Pico and friends)
+
52 #if (defined(ARDUINO_ARCH_RP2040))
+
53 #define IS_RP2040() 1
+
54 #else
+
55 #define IS_RP2040() 0
+
56 #endif
+
57 
+
58 // STM32 boards (libmaple based)
+
59 // https://github.com/stevstrong/Arduino_STM32
+
60 #if (defined(__arm__) && !IS_TEENSY3() && !IS_TEENSY4() && __has_include("libmaple/libmaple.h"))
+
61 #define IS_STM32MAPLE() 1
+
62 #else
+
63 #define IS_STM32MAPLE() 0
+
64 #endif
+
65 
+
66 // Mbed OS based boards
+
67 #if (defined(ARDUINO_ARCH_MBED))
+
68 #define IS_MBED() 1
+
69 #else
+
70 #define IS_MBED() 0
+
71 #endif
+
72 
+
73 // Arduino Giga
+
74 #if (IS_MBED() && defined(ARDUINO_GIGA))
+
75 #define IS_GIGA() 1
+
76 #else
+
77 #define IS_GIGA() 0
+
78 #endif
+
79 
+
80 // Arduino Uno R4 (Renesas arch)
+
81 #if (defined(ARDUINO_FSP))
+
82 #define IS_RENESAS() 1
+
83 #else
+
84 #define IS_RENESAS() 0
+
85 #endif
+
86 
+
87 #if (defined(__arm__) && !IS_STM32MAPLE() && !IS_TEENSY3() && !IS_TEENSY4() && !IS_RP2040() && !IS_SAMD21() && !IS_MBED() && !IS_RENESAS())
+
88 #define IS_STM32DUINO() 1
+
89 #else
+
90 #define IS_STM32DUINO() 0
+
91 #endif
+
92 
+
93 #if (defined(ESP8266))
+
94 #define IS_ESP8266() 1
+
95 #else
+
96 #define IS_ESP8266() 0
+
97 #endif
+
98 
+
99 #if (defined(ESP32))
+
100 #define IS_ESP32() 1
+
101 #else
+
102 #define IS_ESP32() 0
+
103 #endif
+
104 
+
105 #if !(IS_AVR() || IS_TEENSY3() || IS_TEENSY4() || IS_STM32MAPLE() || IS_STM32DUINO() || IS_ESP8266() || IS_SAMD21() || IS_ESP32() || IS_RP2040() || IS_MBED() || IS_RENESAS())
+
106 // TODO: add an exception for MOZZI_OUTPUT_EXTERNAL_CUSTOM
+
107 #error Your hardware is not supported by Mozzi or not recognized. Edit hardware_defines.h to proceed.
+
108 #endif
+
109 
+
110 // Hardware detail defines
+
111 #if IS_STM32MAPLE()
+
112 #define NUM_ANALOG_INPUTS 16 // probably wrong, but mostly needed to allocate an array of readings
+
113 #elif IS_ESP8266()
+
114 #define NUM_ANALOG_INPUTS 1
+
115 #endif
+
116 
+
117 #if IS_ESP8266() || IS_ESP32()
+
118 #define CACHED_FUNCTION_ATTR IRAM_ATTR
+
119 #else
+
120 #define CACHED_FUNCTION_ATTR
+
121 #endif
+
122 
+
123 #if IS_STM32MAPLE()
+
124 // 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).
+
125 // Putting it here, instead, seem to work.
+
126 #include <STM32ADC.h>
+
127 #endif
+
128 
+
129 #endif /* HARDWARE_DEFINES_H_ */
- -

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)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -98,26 +94,24 @@
-
+
-
OverSample< T, RESOLUTION_INCREASE_BITS > Member List
+
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 Mozzi on MBED-based boards (Arduino Giga / Portenta).) 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. 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 Mozzi on STM32-boards with libmaple based core.
    • +
    • A generic Arduino core for STM32 is the STM32duino core. 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 Mozzi on STM32duino-based boards.
    • +
    +
  • +
+
+ - -

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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -98,40 +94,42 @@
-
- +
-
IntegerType< BYTES > Struct Template Reference
+
Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards.
- - - - - - -

-Public Types

-typedef IntegerType<(BYTES< 8) ?(BYTES+1) :8 >::unsigned_type unsigned_type
 
-typedef IntegerType<(BYTES< 8) ?(BYTES+1) :8 >::signed_type signed_type
 
-

Detailed Description

-

template<uint8_t BYTES>
-struct IntegerType< BYTES >

- - -

Definition at line 2 of file IntegerType.h.

+

port by Tim Barrass

+
Note
For Teensy 4.x see Mozzi on Teensy 4.x boards.
+

+Port status and ussage notes

+

This port requires the following two libraries (which should be part of a default installtion, however):

+

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.
  • +
+

+Output modes

+

The following audio modes (see 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 MOZZI_OUTPUT_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:

+
#define MOZZI_AUDIO_PIN_1 ... // Default: A14, A12, or A21, depending on board
+

+MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM

+

See External audio output

+
- -

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)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -105,90 +101,83 @@
This inheritance list is sorted roughly, but not completely, alphabetically:
[detail level 12]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 CADSR< CONTROL_UPDATE_RATE, LERP_RATE, T >A simple ADSR envelope generator
 CADSR< CONTROL_RATE, AUDIO_RATE >
 CADSR< CONTROL_RATE, CONTROL_RATE >
 CAudioDelay< NUM_BUFFER_SAMPLES, T >Audio delay line for comb filter, flange, chorus and short echo effects
 CControlDelay< NUM_BUFFER_SAMPLES, T >
-Control-rate delay line for delaying control signals
 CAudioDelay< 128 >
 CAudioDelay< 128, int >
 CAudioDelay< 256, int >
 CAudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >Audio delay line with feedback for comb filter, flange, chorus and short echo effects
 CAutoRange< T >Keeps a running calculation of the range of the input values it receives
 CAutoRange< int >
 CAutoMapAutomatically map an input value to an output range without knowing the precise range of inputs beforehand
 CCapPoll< SENSOR_PIN, SEND_PIN >
-A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime
 CCircularBuffer< ITEM_TYPE >Circular buffer object
 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
 CMetronomeA metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat
 CInt2Type< I >Enables you to instantiate a template based on an integer value
 CIntegerType< BYTES >
 CIntegerType< 1 >
 CIntegerType< 2 >
 CIntegerType< 4 >
 CIntegerType< 8 >
 CIntegerType< sizeof(su)+sizeof(su)>
 CIntegerType< sizeof(T)>
 CIntMapA faster version of Arduino's map() function
 CLine< T >For linear changes with a minimum of calculation at each step
 CLine< Q15n16 >
 CLine< Q16n16 >
 CLine< unsigned char >
 CLine< unsigned int >
 CLine< unsigned long >
 CMetaOscil< NUM_TABLE_CELLS, UPDATE_RATE, N_OSCIL >MetaOscil is a wrapper for several Oscil
 CMonoOutputThis struct encapsulates one frame of mono audio output
 COscil< NUM_TABLE_CELLS, UPDATE_RATE >
-Oscil plays a wavetable, cycling through the table to generate an audio or control signal
 COscil< 8192, AUDIO_RATE >
 COscil< COS8192_NUM_CELLS, AUDIO_RATE >
 COscil< SIN2048_NUM_CELLS, AUDIO_RATE >
 CPDResonantPDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on https://en.wikipedia.org/wiki/Phase_distortion_synthesis
 CPhasor< UPDATE_RATE >Phasor repeatedly generates a high resolution ramp at a variable frequency
 CPhasor< AUDIO_RATE >
 CPortamento< CONTROL_UPDATE_RATE >A simple portamento (pitch slide from one note to the next) effect, useful for note-based applications
 CRCpoll< SENSOR_PIN >
-A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime
 CResonantFilter< FILTER_TYPE, su >A generic resonant filter for audio signals
 CResonantFilter< LOWPASS, su >
 CMultiResonantFilter< su >A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime
 CReverbTank
-A reverb which sounds like the inside of a tin can
 CRollingAverage< T, WINDOW_LENGTH >Calculates a running average over a specified number of the most recent readings
 CRollingAverage< T,(1<<(RESOLUTION_INCREASE_BITS *2))>
 COverSample< T, RESOLUTION_INCREASE_BITS >Enables the resolution of analog inputs to be increased by oversampling and decimation
 CRollingStat< T, WINDOW_LENGTH >WARNING: this class is work in progress, don't use it yet
 CSample< NUM_TABLE_CELLS, UPDATE_RATE, INTERP >Sample is like Oscil, it plays a wavetable
 CSampleHuffmanA sample player for samples encoded with Huffman compression
 CSmooth< T >A simple infinite impulse response low pass filter for smoothing control or audio signals
 CStack< T, NUM_ITEMS >A simple stack, used internally for keeping track of analog input channels as they are read
 CStateVariable< 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
 CStereoOutputThis struct encapsulates one frame of mono audio output
 CWaveFolder< T >A simple wavefolder
 CWavePacket< ALGORITHM >
-Wavepacket synthesis, with two overlapping streams of wave packets
 CWavePacketSample< ALGORITHM >A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains)
 CWaveShaper< T >WaveShaper 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
 CADSR< CONTROL_UPDATE_RATE, LERP_RATE, T >A simple ADSR envelope generator
 CADSR< MOZZI_CONTROL_RATE, MOZZI_AUDIO_RATE >
 CADSR< MOZZI_CONTROL_RATE, MOZZI_CONTROL_RATE >
 CAudioDelay< NUM_BUFFER_SAMPLES, T >Audio delay line for comb filter, flange, chorus and short echo effects
 CAudioDelay< 128 >
 CAudioDelay< 128, int >
 CAudioDelay< 256, int >
 CAudioDelay< NUM_BUFFER_SAMPLES, int >
 CControlDelay< NUM_BUFFER_SAMPLES, T >Control-rate delay line for delaying control signals
 CAudioDelayFeedback< NUM_BUFFER_SAMPLES, INTERP_TYPE >Audio delay line with feedback for comb filter, flange, chorus and short echo effects
 CAutoRange< T >Keeps a running calculation of the range of the input values it receives
 CAutoRange< int >
 CAutoMapAutomatically map an input value to an output range without knowing the precise range of inputs beforehand
 CCapPoll< SENSOR_PIN, SEND_PIN >A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime
 CCircularBuffer< ITEM_TYPE >Circular buffer object
 CDCfilterA DC-blocking filter useful for highlighting changes in control signals
 CEadExponential attack decay envelope
 CEventDelayA non-blocking replacement for Arduino's delay() function
 CMetronomeA metronome class which is like an EventDelay which retriggers itself when the delay time is up, to produce a repeating beat
 CInt2Type< I >Enables you to instantiate a template based on an integer value
 CIntegerType< BYTES >Provides 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 >
 CIntegerType< sizeof(AudioOutputStorage_t)>
 CIntegerType< sizeof(uint8_t)+sizeof(uint8_t)>
 CIntMapA faster version of Arduino's map() function
 CLine< T >For linear changes with a minimum of calculation at each step
 CLine< Q15n16 >
 CLine< Q16n16 >
 CLine< SFix< NI, NF > >
 CLine< UFix< NI, NF > >
 CLine< unsigned char >
 CLine< unsigned int >
 CLine< unsigned long >
 CMetaOscil< NUM_TABLE_CELLS, UPDATE_RATE, N_OSCIL >MetaOscil is a wrapper for several Oscil
 CMidiToFreqPrivateInternal
 CMonoOutputThis struct encapsulates one frame of mono audio output
 CMozziPrivate::MozziRandPrivate
 COscil< NUM_TABLE_CELLS, UPDATE_RATE >Oscil plays a wavetable, cycling through the table to generate an audio or control signal
 COscil< 8192, MOZZI_AUDIO_RATE >
 COscil< COS8192_NUM_CELLS, MOZZI_AUDIO_RATE >
 COscil< SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE >
 CPDResonantPDResonant is a simple midi instrument using Phase distortion used to simulate resonant filter, based on https://en.wikipedia.org/wiki/Phase_distortion_synthesis
 CPhasor< UPDATE_RATE >Phasor repeatedly generates a high resolution ramp at a variable frequency
 CPhasor< MOZZI_AUDIO_RATE >
 CPortamento< CONTROL_UPDATE_RATE >A simple portamento (pitch slide from one note to the next) effect, useful for note-based applications
 CRCpoll< SENSOR_PIN >A class for reading voltage on a digital pin, derived from http://arduino.cc/en/Tutorial/RCtime
 CResonantFilter< FILTER_TYPE, su >A generic resonant filter for audio signals
 CResonantFilter< LOWPASS, uint8_t >
 CMultiResonantFilter< su >A generic filter for audio signals that can produce lowpass, highpass, bandpass and notch outputs at runtime
 CReverbTankA reverb which sounds like the inside of a tin can
 CRollingAverage< T, WINDOW_LENGTH >Calculates a running average over a specified number of the most recent readings
 CRollingAverage< T,(1<<(RESOLUTION_INCREASE_BITS *2))>
 COverSample< T, RESOLUTION_INCREASE_BITS >Enables the resolution of analog inputs to be increased by oversampling and decimation
 CRollingStat< T, WINDOW_LENGTH >WARNING: this class is work in progress, don't use it yet
 CSample< NUM_TABLE_CELLS, UPDATE_RATE, INTERP >Sample is like Oscil, it plays a wavetable
 CSampleHuffmanA sample player for samples encoded with Huffman compression
 CSmooth< T >A simple infinite impulse response low pass filter for smoothing control or audio signals
 CSmooth< SFix< NI, NF > >
 CSmooth< UFix< NI, NF > >
 CStack< T, NUM_ITEMS >A simple stack, used internally for keeping track of analog input channels as they are read
 CStateVariable< FILTER_TYPE >State 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
 CWaveFolder< T >A simple wavefolder
 CWavePacket< ALGORITHM >Wavepacket synthesis, with two overlapping streams of wave packets
 CWavePacketSample< ALGORITHM >A WavePacket which allows a custom table to be set as the audio source for the wavepackets (or grains)
 CWaveShaper< T >WaveShaper 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
- - - + @@ -80,7 +76,7 @@
@@ -104,6 +100,7 @@
- -
@@ -103,22 +99,192 @@
mozzi_analog.h
-
1 /*
2  * mozzi_analog.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 MOZZI_ANALOG_H_
13 #define MOZZI_ANALOG_H_
14 
15  #if ARDUINO >= 100
16  #include "Arduino.h"
17 #else
18  #include "WProgram.h"
19 #endif
20 
21 #include "hardware_defines.h"
22 
23 #if (USE_AUDIO_INPUT==true)
24 #warning "Using AUDIO_INPUT_PIN defined in mozzi_config.h for audio input."
25 #endif
26 
27 // hack for Teensy 2 (ATmega32U4), which has "adc_mapping" instead of "analog_pin_to_channel_PGM"
28 #if defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
29 //pasted from hardware/arduino/variants/leonardo/pins_arduino.h, doesn't work as of mozzi 0.01.2a
30 // __AVR_ATmega32U4__ has an unusual mapping of pins to channels
31 //extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
32 //#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
33 
34 // look at Arduino.app/Contents/Resources/Java/hardware/teensy/cores/teensy/pins_teensy.c - analogRead
35 // adc_mapping is already declared in pins_teensy.c, but it's static there so we can't access it
36 static const uint8_t PROGMEM adc_mapping[] = {
37 // 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8
38  0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8, 10, 11, 12, 13, 7, 6, 5, 4, 1, 0, 8
39 };
40 #define analogPinToChannel(P) ( pgm_read_byte( adc_mapping + (P) ) )
41 #endif
42 
43 
44 // include this although already in teensy 3 analog.c, because it is static there
45 #if defined(__MK20DX128__)
46 static const uint8_t channel2sc1a[] = {
47  5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
48  0, 19, 3, 21, 26, 22, 23
49 };
50 #elif defined(__MK20DX256__)
51 static const uint8_t channel2sc1a[] = {
52  5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
53  0, 19, 3, 19+128, 26, 18+128, 23,
54  5+192, 5+128, 4+128, 6+128, 7+128, 4+192
55 // A15 26 E1 ADC1_SE5a 5+64
56 // A16 27 C9 ADC1_SE5b 5
57 // A17 28 C8 ADC1_SE4b 4
58 // A18 29 C10 ADC1_SE6b 6
59 // A19 30 C11 ADC1_SE7b 7
60 // A20 31 E0 ADC1_SE4a 4+64
61 };
62 #endif
63 
64 
65 // for setupFastAnalogRead()
66 enum ANALOG_READ_SPEED {FAST_ADC,FASTER_ADC,FASTEST_ADC};
67 
68 /**
69 @ingroup analog
70 This is automatically called in startMozzi.
71 It makes mozziAnalogRead() happen faster than the standard Arduino analogRead(), changing the
72 duration from about 105 in unmodified Arduino to about 16 microseconds for a
73 dependable read with the default speed parameter FAST_ADC.
74 If you want to set on of the faster modes (see params) you can call this after startMozzi().
75 See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11, and
76 http://www.marulaberry.co.za/index.php/tutorials/code/arduino-adc/
77 @param speed FAST_ADC, FASTER_ADC or FASTEST_ADC. If no parameter is supplied, the
78 default is FAST_ADC, which sets the analog conversion clock predivide rate to
79 16, giving 1Mhz on a 16MHz board, the fastest rate for which behaviour is
80 defined (~16us per sample). However, divisors of 8 and 4 also show usable
81 results in the graphs in this paper:
82 http://dam.mellis.org/Mellis%20-%20Sensor%20Library%20for%20Arduino%20-%20Paper.pdf,
83 so you can also try FASTER_ADC or FASTEST_ADC for divide rates of 8 or 4, giving
84 times of about 8us or 4us per sample. Beware, reliable results will depend on
85 the sort of input signal you have. Only use FASTER_ADC or FASTEST_ADC if you
86 know what you're doing.
87 */
88 void setupFastAnalogRead(int8_t speed=FAST_ADC);
89 
90 
91 
92 /* @ingroup analog
93 Set up for asynchronous analog input, which enables analog reads to take
94 place in the background without blocking the processor.
95 @param speed FAST_ADC, FASTER_ADC or FASTEST_ADC. See setupFastAnalogRead();
96 */
97 void setupMozziADC(int8_t speed=FAST_ADC);
98 
99 
100 
101 /** @ingroup analog
102 Prepare an analog input channel by turning off its digital input buffer.
103 This helps to reduce noise, increase analog reading speed, and save power.
104 
105 Here's more detail from http://www.openmusiclabs.com/learning/digital/atmega-adc/:
106 
107 The DIDR (Data Input Disable Register) disconnects the digital inputs from
108 whichever ADC channels you are using. This is important for 2 reasons. First
109 off, an analog input will be floating all over the place, and causing the
110 digital input to constantly toggle high and low. This creates excessive noise
111 near the ADC, and burns extra power. Secondly, the digital input and associated
112 DIDR switch have a capacitance associated with them which will slow down your
113 input signal if you are sampling a highly resistive load.
114 
115 And from the ATmega328p datasheet, p266:
116 
117 When an analog signal is applied to the ADC pin and the digital input from
118 this pin is not needed, this bit should be written logic one to reduce power
119 consumption in the digital input buffer. Note that ADC named_pins ADC7
120 and ADC6 do not have digital input buffers, and therefore do not require
121 Digital Input Disable bits.
122 @param channel_num the analog input channel you wish to use.
123 */
124 void disconnectDigitalIn(uint8_t channel_num);
125 
126 
127 /** @ingroup analog
128 Reconnect the digital input buffer for an analog input channel which has
129 been set for analog input with disconnectDigitalIn().
130 @param channel_num the analog input channel you wish to reconnect.
131 */
132 void reconnectDigitalIn(uint8_t channel_num);
133 
134 
135 /** @ingroup analog
136 Prepare all analog input channels by turning off their digital input buffers.
137 This helps to reduce noise, increase analog reading speed, and save power.
138 */
140 
141 
142 /** @ingroup analog
143 Reconnect the digital input buffers for analog input channels which have
144 been set for analog input with disconnectDigitalIn().
145 */
147 
148 
149 
150 /* @ingroup analog
151 Starts an analog to digital conversion of the voltage on a specified channel. Unlike
152 Arduino's analogRead() function which waits until a conversion is complete before
153 returning, adcStartConversion() only sets the conversion to begin, so you can use
154 the cpu for other things and call for the result later with adcGetResult().
155 @param channel is the analog channel number (0 to ....), which is not necessarily the same as the pin number
156 Use adcPinToChannelNum() to convert the pin number to its channel number.
157 @note Timing: about 1us when used in updateControl() with CONTROL_RATE 64.
158 */
159 void adcStartConversion(uint8_t channel);
160 
161 
162 
163 /** @ingroup analog
164 Reads the analog input of a chosen channel, without blocking other operations from running.
165 It actually returns the most recent analog reading and puts the chosen pin or channel
166 on the stack of channels to be read in the background before the next control
167 interrupt.
168 @param pin_or_channel the analog pin or channel number.
169 @return the digitised value of the voltage on the chosen channel, in the range 0-1023. @Note that non-AVR
170 hardware may return a different range, e.g. 0-4095 on STM32 boards.
171 */
172 int mozziAnalogRead(uint8_t pin);
173 
174 
175 uint8_t adcPinToChannelNum(uint8_t pin);
176 
177 
178 #endif /* MOZZI_ANALOG_H_ */
int mozziAnalogRead(uint8_t pin)
Reads the analog input of a chosen channel, without blocking other operations from running...
Definition: MozziGuts.cpp:109
-
void adcReconnectAllDigitalIns()
Reconnect the digital input buffers for analog input channels which have been set for analog input wi...
-
void reconnectDigitalIn(uint8_t channel_num)
Reconnect the digital input buffer for an analog input channel which has been set for analog input wi...
-
void disconnectDigitalIn(uint8_t channel_num)
Prepare an analog input channel by turning off its digital input buffer.
-
void setupFastAnalogRead(int8_t speed)
NOTE: Code needed to set up faster than usual analog reads, e.g.
-
void adcDisconnectAllDigitalIns()
Prepare all analog input channels by turning off their digital input buffers.
+
1 /*
+
2  * mozzi_analog.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 MOZZI_ANALOG_H_
+
14 #define MOZZI_ANALOG_H_
+
15 
+
16 #include "Arduino.h"
+
17 
+
18 #include "hardware_defines.h"
+
19 
+
20 // for setupFastAnalogRead()
+
21 enum ANALOG_READ_SPEED {FAST_ADC,FASTER_ADC,FASTEST_ADC};
+
22 
+
23 /** @defgroup analog
+
24 
+
25 @brief Efficient analog input functions for sensors and audio.
+
26 
+
27 Helps produce glitch-free audio by allowing analog input functions which normally block processing to be performed in the background.
+
28 */
+
29 
+
30 /**
+
31 @ingroup analog
+
32 This is automatically called in startMozzi.
+
33 It makes mozziAnalogRead() happen faster than the standard Arduino analogRead(), changing the
+
34 duration from about 105 in unmodified Arduino to about 16 microseconds for a
+
35 dependable read with the default speed parameter FAST_ADC.
+
36 If you want to set on of the faster modes (see params) you can call this after startMozzi().
+
37 See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11, and
+
38 http://www.marulaberry.co.za/index.php/tutorials/code/arduino-adc/
+
39 @param speed FAST_ADC, FASTER_ADC or FASTEST_ADC. If no parameter is supplied, the
+
40 default is FAST_ADC, which sets the analog conversion clock predivide rate to
+
41 16, giving 1Mhz on a 16MHz board, the fastest rate for which behaviour is
+
42 defined (~16us per sample). However, divisors of 8 and 4 also show usable
+
43 results in the graphs in this paper:
+
44 http://dam.mellis.org/Mellis%20-%20Sensor%20Library%20for%20Arduino%20-%20Paper.pdf,
+
45 so you can also try FASTER_ADC or FASTEST_ADC for divide rates of 8 or 4, giving
+
46 times of about 8us or 4us per sample. Beware, reliable results will depend on
+
47 the sort of input signal you have. Only use FASTER_ADC or FASTEST_ADC if you
+
48 know what you're doing.
+
49 */
+
50 void setupFastAnalogRead(int8_t speed=FAST_ADC);
+
51 
+
52 
+
53 
+
54 /* @ingroup analog
+
55 Set up for asynchronous analog input, which enables analog reads to take
+
56 place in the background without blocking the processor.
+
57 @param speed FAST_ADC, FASTER_ADC or FASTEST_ADC. See setupFastAnalogRead();
+
58 */
+
59 void setupMozziADC(int8_t speed=FAST_ADC);
+
60 
+
61 
+
62 
+
63 /** @ingroup analog
+
64 Prepare an analog input channel by turning off its digital input buffer.
+
65 This helps to reduce noise, increase analog reading speed, and save power.
+
66 
+
67 Here's more detail from http://www.openmusiclabs.com/learning/digital/atmega-adc/:
+
68 
+
69 The DIDR (Data Input Disable Register) disconnects the digital inputs from
+
70 whichever ADC channels you are using. This is important for 2 reasons. First
+
71 off, an analog input will be floating all over the place, and causing the
+
72 digital input to constantly toggle high and low. This creates excessive noise
+
73 near the ADC, and burns extra power. Secondly, the digital input and associated
+
74 DIDR switch have a capacitance associated with them which will slow down your
+
75 input signal if you are sampling a highly resistive load.
+
76 
+
77 And from the ATmega328p datasheet, p266:
+
78 
+
79 When an analog signal is applied to the ADC pin and the digital input from
+
80 this pin is not needed, this bit should be written logic one to reduce power
+
81 consumption in the digital input buffer. Note that ADC named_pins ADC7
+
82 and ADC6 do not have digital input buffers, and therefore do not require
+
83 Digital Input Disable bits.
+
84 @param channel_num the analog input channel you wish to use.
+
85 */
+
86 inline void disconnectDigitalIn(uint8_t channel_num) {
+
87 #if IS_AVR()
+
88  DIDR0 |= 1<<channel_num;
+
89 #else
+
90  (void) channel_num; // unused, suppress warning
+
91 #endif
+
92 }
+
93 
+
94 /** @ingroup analog
+
95 Reconnect the digital input buffer for an analog input channel which has
+
96 been set for analog input with disconnectDigitalIn().
+
97 @param channel_num the analog input channel you wish to reconnect.
+
98 */
+
99 inline void reconnectDigitalIn(uint8_t channel_num) {
+
100 #if IS_AVR()
+
101  DIDR0 &= ~(1<<channel_num);
+
102 #else
+
103  (void) channel_num; // unused, suppress warning
+
104 #endif
+
105 }
+
106 
+
107 /** @ingroup analog
+
108 Prepare all analog input channels by turning off their digital input buffers.
+
109 This helps to reduce noise, increase analog reading speed, and save power.
+
110 */
+
111 inline void adcDisconnectAllDigitalIns() {
+
112 #if IS_AVR()
+
113  for (uint8_t i = 0; i<NUM_ANALOG_INPUTS; i++){
+
114  DIDR0 |= 1<<i;
+
115  }
+
116 #endif
+
117 }
+
118 
+
119 
+
120 /** @ingroup analog
+
121 Reconnect the digital input buffers for analog input channels which have
+
122 been set for analog input with disconnectDigitalIn().
+
123 */
+
124 inline void adcReconnectAllDigitalIns() {
+
125 #if IS_AVR()
+
126  for (uint8_t i = 0; i<NUM_ANALOG_INPUTS; i++){
+
127  DIDR0 &= ~(1<<i);
+
128  }
+
129 #endif
+
130 }
+
131 
+
132 /* @ingroup analog
+
133 Starts an analog to digital conversion of the voltage on a specified channel. Unlike
+
134 Arduino's analogRead() function which waits until a conversion is complete before
+
135 returning, adcStartConversion() only sets the conversion to begin, so you can use
+
136 the cpu for other things and call for the result later with adcGetResult().
+
137 @param channel is the analog channel number (0 to ....), which is not necessarily the same as the pin number
+
138 Use adcPinToChannelNum() to convert the pin number to its channel number.
+
139 @note Timing: about 1us when used in updateControl() with MOZZI_CONTROL_RATE 64.
+
140 */
+
141 void adcStartConversion(uint8_t channel);
+
142 
+
143 /** @ingroup analog
+
144 See mozziAnalogRead(). The template parameter RES specifies the number of bits to return.
+
145 */
+
146 template<byte RES> uint16_t mozziAnalogRead(uint8_t pin);
+
147 
+
148 /** @ingroup analog
+
149 See mozziAnalogRead() but always returns the value shifted to 16 bit range. THis is exactly
+
150 equivalent to mozziAnalogRead<16>(pin);
+
151 */
+
152 inline uint16_t mozziAnalogRead16(uint8_t pin) { return mozziAnalogRead<16>(pin); };
+
153 
+
154 #if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION)
+
155 /** @ingroup analog
+
156 Reads the analog input of a chosen channel, without blocking other operations from running.
+
157 It actually returns the most recent analog reading and puts the chosen pin or channel
+
158 on the stack of channels to be read in the background before the next control
+
159 interrupt.
+
160 
+
161 @note Analog reads have different hardware resolution on different platforms. E.g. an analog read
+
162  on an Arduino Uno R3 will return a value in the range 0-1023 (10 bits), on a Raspberry Pi Pico
+
163  it will return 0-4095 (12 bits). For portable code, it is thus necessary to specify the desired
+
164  resolution of reads. This can be done by setting MOZZI_ANALOG_READ_RESOLUTION to the resolution
+
165  in bits, near the top of your sketch. All reads will then be adjusted to that range, automatically
+
166  (using a simple bit-shift). Alternatively, the templated version of mozziAanalogRead() allows
+
167  to specifiy the target resolution per read.
+
168  If MOZZI_ANALOG_READ_RESOLUTION is not defined, this (non-templated) function returns a value
+
169  in the default hardware resolution, with a warning.
+
170 
+
171 @param pin_or_channel the analog pin or channel number.
+
172 @return the digitised value of the voltage on the chosen channel. See the note above regarding the output range!
+
173 */
+
174 inline uint16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead<MOZZI_ANALOG_READ_RESOLUTION>(pin); }
+
175 #else
+
176 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<MOZZI__INTERNAL_ANALOG_READ_RESOLUTION>(pin); }
+
177 #endif
+
178 
+
179 uint8_t adcPinToChannelNum(uint8_t pin);
+
180 
+
181 
+
182 #endif /* MOZZI_ANALOG_H_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,20 +99,195 @@
mozzi_fixmath.cpp
-
1 #include "mozzi_fixmath.h"
2 
3 /** @ingroup fixmath
4 @{
5 */
6 
7 //Snipped from http://code.google.com/p/ht1632c/wiki/Optimizations
8 //TB2012 changed names to not interfere with arduino compilation
9 //Fast integer math
10 //
11 //If you need to include arithmetic operations in you code but you don't need
12 //floating point operations, you could use boolean operations instead of arithmetic
13 //operations, or use smaller data types and custom functions instead of stdlib functions
14 //or C operators (expecially / and %).
15 //Look at IntegerCodeSnippets, http://code.google.com/p/ht1632c/wiki/IntegerCodeSnippets
16 //
17 //Here is some ready to use fast integer 1 uint8_t wide math functions (from ht1632c library).
18 
19 /**
20 fast uint8_t modulus
21 @param n numerator
22 @param d denominator
23 @return modulus
24 */
26 {
27  while(n >= d)
28  n -= d;
29  return n;
30 }
31 
32 /** Fast uint8_t division
33 @param n numerator
34 @param d denominator
35 @return quotient
36 */
37 uint8_t uint8_tDiv(uint8_t n, uint8_t d)
38 {
39  uint8_t q = 0;
40  while(n >= d)
41  {
42  n -= d;
43  q++;
44  }
45  return q;
46 }
47 
48 /* fast integer (1 uint8_t) PRNG */
49 uint8_t uint8_tRnd(uint8_t min, uint8_t max)
50 {
51  static uint8_t seed;
52  seed = (21 * seed + 21);
53  return min + uint8_tMod(seed, --max);
54 }
55 //WARNING: don't use this uint8_tRnd() function for cryptography!
56 
57 //} of snip from http://code.google.com/p/ht1632c/wiki/Optimizations
58 
59 
60 
61 // from http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int
62 /* Exponentiation by squaring.
63 */
64 int ipow(int base, int exp)
65 {
66  int result = 1;
67  while (exp)
68  {
69  if (exp & 1)
70  result *= base;
71  exp >>= 1;
72  base *= base;
73  }
74 
75  return result;
76 }
77 
78 
79 /*
80 from: http://objectmix.com/vhdl/189970-2-powerof-x-where-x-fixed-point-value-2.html
81 
82 to do 2^(x.y) first find
83 2^x and 2^(x+1) through bit shifting 1 to the left by x and (x + 1) places
84 
85 now you do linear interpolation by drawing a line through these two points 2^x,
86 2^(x+1), then use f = m*x+b. the slope, m = rise over run
87 = (2^(x+1) - 2^x)/((x+1) - (x))
88 = 2^(x) * (2 - 1) / 1
89 = 2^(x)
90 b = 2^x, so to linearly interpolate do....(edited out typo)..
91 f = 2^(x) * (y) + 2^x
92 = 2^x * (y + 1)
93 where x is integer part, y is fractional part
94 */
95 
96 
97 /**
98 fast replacement for pow(2,x), where x is a Q8n8 fractional
99 fixed-point exponent. It's less accurate than pow(2,x), but useful where a
100 tradeoff between accuracy and speed is required to keep audio from glitching.
101 @param exponent in Q8n8 format.
102 @return pow(2,x) in Q16n16 format.
103 @todo Q16n16_pow2() accuracy needs more attention.
104 */
105 Q16n16 Q16n16_pow2(Q8n8 exponent)
106 {
107  // to do 2^(x.y) first find
108  //2^x and 2^(x+1) through bit shifting 1 to the left by x and (x + 1) places
109  uint8_t Q = (uint8_t)((Q8n8)exponent>>8); // integer part
110  uint8_t n = (uint8_t) exponent; // fractional part
111  // f = 2^x * (y + 1)
112  return (((Q16n16)Q8n8_FIX1 << Q) * (Q8n8_FIX1 + n));
113 }
114 
115 
116 
117 
118 //http://www.codecodex.com/wiki/Calculate_an_integer_square_root
119 //see Integer Square Roots by Jack W. Crenshaw, figure 2, http://www.embedded.com/electronics-blogs/programmer-s-toolbox/4219659/Integer-Square-Roots
120 
121 uint32_t // OR uint16 OR uint8_t
122 isqrt32 (uint32_t n) // OR isqrt16 ( uint16_t n ) OR isqrt8 ( uint8_t n ) - respectively [ OR overloaded as isqrt (uint16_t?? n) in C++ ]
123 {
124  uint32_t // OR register uint16_t OR register uint8_t - respectively
125  root, remainder, place;
126 
127  root = 0;
128  remainder = n;
129  place = 0x40000000; // OR place = 0x4000; OR place = 0x40; - respectively
130 
131  while (place > remainder)
132  place = place >> 2;
133  while (place)
134  {
135  if (remainder >= root + place)
136  {
137  remainder = remainder - root - place;
138  root = root + (place << 1);
139  }
140  root = root >> 1;
141  place = place >> 2;
142  }
143  return root;
144 }
145 
146 
147 //http://www.codecodex.com/wiki/Calculate_an_integer_square_root
148 uint16_t // OR uint16_t OR uint8_t
149 isqrt16 (uint16_t n) // OR isqrt16 ( uint16_t n ) OR isqrt8 ( uint8_t n ) - respectively [ OR overloaded as isqrt (uint16_t?? n) in C++ ]
150 {
151  uint16_t // OR register uint16_t OR register uint8_t - respectively
152  root, remainder, place;
153 
154  root = 0;
155  remainder = n;
156  place = 0x4000; // OR place = 0x4000; OR place = 0x40; - respectively
157 
158  while (place > remainder)
159  place = place >> 2;
160  while (place)
161  {
162  if (remainder >= root + place)
163  {
164  remainder = remainder - root - place;
165  root = root + (place << 1);
166  }
167  root = root >> 1;
168  place = place >> 2;
169  }
170  return root;
171 }
172 
173 
174 /** @} */
uint16_t Q8n8
unsigned fractional number using 8 integer bits and 8 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:35
-
#define Q8n8_FIX1
1 in Q8n8 format
Definition: mozzi_fixmath.h:55
-
uint8_t uint8_tMod(uint8_t n, uint8_t d)
fast uint8_t modulus
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46
+
1 /*
+
2  * mozzi_fixmath.cpp
+
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 "mozzi_fixmath.h"
+
13 
+
14 /** @ingroup fixmath
+
15 @{
+
16 */
+
17 
+
18 //Snipped from http://code.google.com/p/ht1632c/wiki/Optimizations
+
19 //TB2012 changed names to not interfere with arduino compilation
+
20 //Fast integer math
+
21 //
+
22 //If you need to include arithmetic operations in you code but you don't need
+
23 //floating point operations, you could use boolean operations instead of arithmetic
+
24 //operations, or use smaller data types and custom functions instead of stdlib functions
+
25 //or C operators (expecially / and %).
+
26 //Look at IntegerCodeSnippets, http://code.google.com/p/ht1632c/wiki/IntegerCodeSnippets
+
27 //
+
28 //Here is some ready to use fast integer 1 uint8_t wide math functions (from ht1632c library).
+
29 
+
30 /**
+
31 fast uint8_t modulus
+
32 @param n numerator
+
33 @param d denominator
+
34 @return modulus
+
35 */
+ +
37 {
+
38  while(n >= d)
+
39  n -= d;
+
40  return n;
+
41 }
+
42 
+
43 /** Fast uint8_t division
+
44 @param n numerator
+
45 @param d denominator
+
46 @return quotient
+
47 */
+ +
49 {
+
50  uint8_t q = 0;
+
51  while(n >= d)
+
52  {
+
53  n -= d;
+
54  q++;
+
55  }
+
56  return q;
+
57 }
+
58 
+
59 /* fast integer (1 uint8_t) PRNG */
+
60 uint8_t uint8_tRnd(uint8_t min, uint8_t max)
+
61 {
+
62  static uint8_t seed;
+
63  seed = (21 * seed + 21);
+
64  return min + uint8_tMod(seed, --max);
+
65 }
+
66 //WARNING: don't use this uint8_tRnd() function for cryptography!
+
67 
+
68 //} of snip from http://code.google.com/p/ht1632c/wiki/Optimizations
+
69 
+
70 
+
71 
+
72 // from http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int
+
73 /* Exponentiation by squaring.
+
74 */
+
75 int ipow(int base, int exp)
+
76 {
+
77  int result = 1;
+
78  while (exp)
+
79  {
+
80  if (exp & 1)
+
81  result *= base;
+
82  exp >>= 1;
+
83  base *= base;
+
84  }
+
85 
+
86  return result;
+
87 }
+
88 
+
89 
+
90 /*
+
91 from: http://objectmix.com/vhdl/189970-2-powerof-x-where-x-fixed-point-value-2.html
+
92 
+
93 to do 2^(x.y) first find
+
94 2^x and 2^(x+1) through bit shifting 1 to the left by x and (x + 1) places
+
95 
+
96 now you do linear interpolation by drawing a line through these two points 2^x,
+
97 2^(x+1), then use f = m*x+b. the slope, m = rise over run
+
98 = (2^(x+1) - 2^x)/((x+1) - (x))
+
99 = 2^(x) * (2 - 1) / 1
+
100 = 2^(x)
+
101 b = 2^x, so to linearly interpolate do....(edited out typo)..
+
102 f = 2^(x) * (y) + 2^x
+
103 = 2^x * (y + 1)
+
104 where x is integer part, y is fractional part
+
105 */
+
106 
+
107 
+
108 /**
+
109 fast replacement for pow(2,x), where x is a Q8n8 fractional
+
110 fixed-point exponent. It's less accurate than pow(2,x), but useful where a
+
111 tradeoff between accuracy and speed is required to keep audio from glitching.
+
112 @param exponent in Q8n8 format.
+
113 @return pow(2,x) in Q16n16 format.
+
114 @todo Q16n16_pow2() accuracy needs more attention.
+
115 */
+
116 Q16n16 Q16n16_pow2(Q8n8 exponent)
+
117 {
+
118  // to do 2^(x.y) first find
+
119  //2^x and 2^(x+1) through bit shifting 1 to the left by x and (x + 1) places
+
120  uint8_t Q = (uint8_t)((Q8n8)exponent>>8); // integer part
+
121  uint8_t n = (uint8_t) exponent; // fractional part
+
122  // f = 2^x * (y + 1)
+
123  return (((Q16n16)Q8n8_FIX1 << Q) * (Q8n8_FIX1 + n));
+
124 }
+
125 
+
126 
+
127 
+
128 
+
129 //http://www.codecodex.com/wiki/Calculate_an_integer_square_root
+
130 //see Integer Square Roots by Jack W. Crenshaw, figure 2, http://www.embedded.com/electronics-blogs/programmer-s-toolbox/4219659/Integer-Square-Roots
+
131 
+
132 uint32_t // OR uint16 OR uint8_t
+
133 isqrt32 (uint32_t n) // OR isqrt16 ( uint16_t n ) OR isqrt8 ( uint8_t n ) - respectively [ OR overloaded as isqrt (uint16_t?? n) in C++ ]
+
134 {
+
135  uint32_t // OR register uint16_t OR register uint8_t - respectively
+
136  root, remainder, place;
+
137 
+
138  root = 0;
+
139  remainder = n;
+
140  place = 0x40000000; // OR place = 0x4000; OR place = 0x40; - respectively
+
141 
+
142  while (place > remainder)
+
143  place = place >> 2;
+
144  while (place)
+
145  {
+
146  if (remainder >= root + place)
+
147  {
+
148  remainder = remainder - root - place;
+
149  root = root + (place << 1);
+
150  }
+
151  root = root >> 1;
+
152  place = place >> 2;
+
153  }
+
154  return root;
+
155 }
+
156 
+
157 
+
158 //http://www.codecodex.com/wiki/Calculate_an_integer_square_root
+
159 uint16_t // OR uint16_t OR uint8_t
+
160 isqrt16 (uint16_t n) // OR isqrt16 ( uint16_t n ) OR isqrt8 ( uint8_t n ) - respectively [ OR overloaded as isqrt (uint16_t?? n) in C++ ]
+
161 {
+
162  uint16_t // OR register uint16_t OR register uint8_t - respectively
+
163  root, remainder, place;
+
164 
+
165  root = 0;
+
166  remainder = n;
+
167  place = 0x4000; // OR place = 0x4000; OR place = 0x40; - respectively
+
168 
+
169  while (place > remainder)
+
170  place = place >> 2;
+
171  while (place)
+
172  {
+
173  if (remainder >= root + place)
+
174  {
+
175  remainder = remainder - root - place;
+
176  root = root + (place << 1);
+
177  }
+
178  root = root >> 1;
+
179  place = place >> 2;
+
180  }
+
181  return root;
+
182 }
+
183 
+
184 
+
185 /** @} */
- - - + @@ -80,7 +76,7 @@
@@ -103,109 +99,429 @@
mozzi_fixmath.h
-
1 /*
2  * mozzi_fixmath.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 FIXEDMATH_H_
13 #define FIXEDMATH_H_
14 
15 #if ARDUINO >= 100
16  #include "Arduino.h"
17 #else
18  #include "WProgram.h"
19 #endif
20 
21 /**@ingroup fixmath
22 @{
23 */
24 // types
25 typedef int8_t Q0n7; /**< signed fractional number using 7 fractional bits, represents -0.5 to 0.496*/
26 typedef int8_t Q7n0; /**< ordinary old signed Q7n0 int8_t with 0 fractional bits, represents -128 to 127*/
27 typedef uint8_t Q0n8; /**< unsigned fractional number using 8 fractional bits, represents 0.0 to 0.996*/
28 typedef uint8_t Q8n0; /**< normal uint8_t with 0 fractional bits, represents 0.0 to 255.0*/
29 typedef uint16_t Q0n16; /**< unsigned fractional number using 16 fractional bits, represents 0.0 to 0.999*/
30 typedef uint32_t Q0n31; /**< signed number using 0 integer bits and 31 fractional bits, represents -0.2147483648 to 0.2147483647*/
31 typedef int16_t Q7n8; /**< signed fractional number using 7 integer bits and 8 fractional bits, represents -127.996 to 127.996*/
32 typedef uint16_t Q3n13; /**< unsigned fractional number using 3 integer bits and 13 fractional bits, represents 0 to 7.999*/
33 typedef int16_t Q1n14; /**< signed fractional number using 1 integer bit and 14 fractional bits, represents -1.999 to 1.999*/
34 typedef int16_t Q15n0; /**< signed number using 15 integer bits and 0 fractional bits, represents -32768 to 32767*/
35 typedef uint16_t Q8n8; /**< unsigned fractional number using 8 integer bits and 8 fractional bits, represents 0 to 255.996*/
36 typedef int16_t Q0n15; /**< signed fractional number using 0 integer bits and 15 fractional bits, represents -0.32768 to 0.32767*/
37 typedef uint16_t Q1n15; /**< unsigned fractional number using 1 integer bit and 15 fractional bits, represents 0 to 1.999*/
38 typedef uint16_t Q16n0; /**< unsigned number using 16 integer bits and 0 fractional bits, represents 0 to 65536.0*/
39 typedef int32_t Q23n8; /**< signed fractional number using 23 integer bits and 8 fractional bits, represents -8388607.996 to 8388607.996*/
40 typedef int32_t Q15n16; /**< signed fractional number using 15 integer bits and 16 fractional bits, represents -32767.999 to 32767.999*/
41 typedef int32_t Q31n0; /**< signed (normal int32_t int16_t) number using 31 integer bits and 0 fractional bits, represents -2147483648 to 2147483647*/
42 typedef uint32_t Q32n0; /**< unsigned (normal uint32_t int16_t) number using 32 integer bits and 0 fractional bits, represents 0 to 4294967295*/
43 typedef uint32_t Q0n32; /**< unsigned fractional number using 0 integer bits and 32 fractional bits, represents 0 to 0.999999999767169*/
44 typedef uint32_t Q8n24; /**< signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255.999*/
45 typedef uint32_t Q24n8; /**< unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215*/
46 typedef uint32_t Q16n16; /**< unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535.999*/
47 /** @}*/
48 
49 /** @ingroup fixmath
50 @{
51 */
52 // macros to save runtime calculations for representations of 1
53 #define Q0n7_FIX1 ((Q0n7) 127) /**< 0.992 in Q0n7 format*/
54 #define Q7n8_FIX1 ((Q7n8) 256) /**< 1 in Q7n8 format*/
55 #define Q8n8_FIX1 ((Q8n8) 256) /**< 1 in Q8n8 format*/
56 #define Q23n8_FIX1 ((Q23n8) 256) /**< 1 in Q23n8 format*/
57 #define Q1n14_FIX1 ((Q1n14) 16384) /**< 1 in Q1n14 format*/
58 #define Q1n15_FIX1 ((Q1n15) 32768) /**< 1 in Q1n15 format*/
59 #define Q16n16_FIX1 ((Q16n16) 65536) /**< 1 in Q16n16 format*/
60 #define Q0n15_FIX1 ((Q0n15) 32767) /**< 0.999 in Q0n15 format*/
61 #define Q0n16_FIX1 ((Q0n16) 65535) /**< 0.999 in Q0n16 format*/
62 #define Q15n0_FIX1 ((Q15n0) 16384) /**< 1 in Q15n0 format*/
63 #define Q15n16_FIX1 ((Q15n16) 65536) /**< 1 in Q15n16 format*/
64 #define Q8n24_FIX1 ((Q8n24) 16777216) /**< 1 in Q8n24 format*/
65 #define Q0n32_FIX1 ((Q0n32) 4294967295) /**< 0.999999999767169 in Q0n32 format*/
66 
67 #define Q16n16_PI ((Q16n16) 205887) /**< PI in Q16n16 format*/
68 #define Q3n13_2PI ((Q3n13) 411775) /**< 2*PI in Q3n13 format*/
69 #define Q16n16_2PI ((Q16n16) 411775) /**< 2*PI in Q16n16 format*/
70 
71 #define low15bits ((Q1n15) 32767) /**< Useful for keeping the lower 15 bits of a Q1n15 number, using &*/
72 /** @}*/
73 
74 
75 /*
76 Type conversions: Float to Q
77 
78 To convert a number from floating point to Qm.n format:
79 
80  Multiply the floating point number by 2^n
81  Round to the nearest integer
82 
83 Q to float
84 
85 To convert a number from Qm.n format to floating point:
86 
87  Convert the number to floating point as if it were an integer
88  Multiply by 2^-n
89 */
90 /** @ingroup fixmath
91 @{
92 */
93 inline
94 Q0n7 float_to_Q0n7(float a) { return static_cast<Q0n7>(a*256); } /**<Convert float to Q0n7 fix. @param a is a float*/
95 
96 inline
97 Q0n8 float_to_Q0n8(float a) { return static_cast<Q0n8>(a*256); } /**<Convert float to Q0n8 fix. @param a is a float*/
98 
99 inline
100 Q7n8 float_to_Q7n8(float a) { return static_cast<Q7n8>(a*256); } /**<Convert float to Q7n8 fix. @param a is a float*/
101 
102 inline
103 Q8n8 float_to_Q8n8(float a) { return static_cast<Q8n8>(a*256); } /**<Convert float to Q8n8 fix. @param a is a float*/
104 
105 inline
106 Q1n14 float_to_Q1n14(float a) { return static_cast<Q1n14>(a*16384); } /**<Convert float to Q1n14 fix. @param a is a float*/
107 
108 inline
109 Q1n15 float_to_Q1n15(float a) { return static_cast<Q1n15>(a*32768); } /**<Convert float to Q1n15 fix. @param a is a float*/
110 
111 inline
112 Q8n24 float_to_Q8n24(float a) { return static_cast<Q8n24>(a*16777216); } /**<Convert float to Q8n24 fix. @param a is a float*/
113 
114 inline
115 Q23n8 float_to_Q23n8(float a) { return static_cast<Q23n8>(a*256); } /**<Convert float to Q23n8 fix. @param a is a float*/
116 
117 inline
118 Q24n8 float_to_Q24n8(float a) { return static_cast<Q24n8>(a*256); } /**<Convert float to Q24n8 fix. @param a is a float*/
119 
120 inline
121 Q16n16 float_to_Q16n16(float a) { return static_cast<Q16n16>(a*65536); } /**<Convert float to Q16n16 fix. @param a is a float*/
122 
123 inline
124 Q0n16 float_to_Q0n16(float a) { return static_cast<Q0n16>(a*65536); } /**<Convert float to Q0n16 fix. @param a is a float*/
125 
126 inline
127 Q15n16 float_to_Q15n16(float a) { return static_cast<Q15n16>(a*65536); } /**<Convert float to Q15n16 fix. @param a is a float*/
128 
129 inline
130 Q1n14 Q0n7_to_Q1n14(Q0n7 a) { return (static_cast<Q1n14>(a))<<7; } /**<Convert Q0n7 int8_t to Q1n14 fix. @param a is a Q0n7 int8_t */
131 
132 inline
133 Q15n16 Q0n7_to_Q15n16(Q0n7 a) { return (static_cast<Q15n16>(a))<<8; } /**<Convert Q0n7 signed int8_t to Q15n16 fix. @param a is a Q0n7 signed int8_t */
134 
135 inline
136 float Q0n7_to_float(Q0n7 a) { return (static_cast<float>(a))/256; } /**<Convert Q0n7 fix to float. @param a is a Q0n7 int8_t*/
137 
138 inline
139 Q1n15 Q0n8_to_Q1n15(Q0n8 a) { return (static_cast<Q1n15>(a))<<7; } /**<Convert Q0n8 uint8_t to Q1n15 fix. @param a is a Q0n8 uint8_t */
140 
141 inline
142 Q8n8 Q0n8_to_Q8n8(Q0n8 a) { return (static_cast<Q8n8>(a))<<8; } /**<Convert Q0n8 uint8_t to Q8n8 fix. @param a is a Q0n8 uint8_t */
143 
144 inline
145 Q8n24 Q0n8_to_Q8n24(Q0n8 a) { return (static_cast<Q8n24>(a))<<16; } /**<Convert Q0n8 uint8_t to Q8n24 fix. @param a is a Q0n8 uint8_t */
146 
147 inline
148 Q24n8 Q0n8_to_Q24n8(Q0n8 a) { return (static_cast<Q24n8>(a))<<8; } /**<Convert Q0n8 uint8_t to Q24n8 fix. @param a is a Q0n8 uint8_t */
149 
150 inline
151 Q15n16 Q0n8_to_Q15n16(Q0n8 a) { return (static_cast<Q15n16>(a))<<8; } /**<Convert Q0n8 uint8_t to Q15n16 fix. @param a is a Q0n8 uint8_t */
152 
153 inline
154 Q16n16 Q0n8_to_Q16n16(Q0n8 a) { return (static_cast<Q16n16>(a))<<8; } /**<Convert Q0n8 uint8_t to Q16n16 fix. @param a is a Q0n8 uint8_t */
155 
156 inline
157 float Q0n8_to_float(Q0n8 a) { return (static_cast<float>(a))/256; } /**<Convert Q0n8 fix to float. @param a is a Q0n8 uint8_t*/
158 
159 inline
160 Q7n8 Q7n0_to_Q7n8(Q7n0 a) { return (static_cast<Q7n8>(a))<<8; } /**<Convert Q7n0 int8_t to Q7n8 fix. @param a is a int8_t*/
161 
162 inline
163 Q15n16 Q7n0_to_Q15n16(Q7n0 a) { return (static_cast<Q15n16>(a))<<16; } /**<Convert Q7n0 int8_t to Q15n16 fix. @param a is a int8_t*/
164 
165 inline
166 Q7n8 Q8n0_to_Q7n8(Q8n0 a) { return (static_cast<Q7n8>(a))<<8; } /**<Convert Q8n0 uint8_t to Q7n8 fix. @param a is a Q8n0 uint8_t*. Beware of overflow. */
167 
168 inline
169 Q8n8 Q8n0_to_Q8n8(Q8n0 a) { return (static_cast<Q8n8>(a))<<8; } /**<Convert uint8_t to Q8n8 fix. @param a is a Q8n0 uint8_t*/
170 
171 inline
172 Q15n16 Q8n0_to_Q15n16(Q8n0 a) { return (static_cast<Q15n16>(a))<<16; } /**<Convert Q8n0 uint8_t to Q15n16 fix. @param a is a Q8n0 uint8_t */
173 
174 inline
175 Q16n16 Q8n0_to_Q16n16(Q8n0 a) { return (static_cast<Q16n16>(a))<<16; } /**<Convert Q8n0 uint8_t to Q16n16 fix. @param a is a Q8n0 uint8_t */
176 
177 inline
178 Q7n0 Q7n8_to_Q7n0(Q7n8 a) { return static_cast<Q7n0>((Q7n8)a>>8); } /**<Convert Q7n8 fix to Q7n0. @param a is a Q7n8 int16_t*/
179 
180 inline
181 Q15n16 Q7n8_to_Q15n16(Q7n8 a) { return (static_cast<Q15n16>(a))<<8; } /**<Convert Q7n8 fix to Q15n16. @param a is a Q7n8 int16_t*/
182 
183 inline
184 float Q7n8_to_float(Q7n8 a) { return (static_cast<float>(a))/256; } /**<Convert Q7n8 fix to float. @param a is a Q7n8 int16_t*/
185 
186 inline
187 Q8n0 Q8n8_to_Q8n0(Q8n8 a) { return static_cast<Q8n0>((Q8n8)a>>8); } /**<Convert Q8n8 fix to Q8n0 uint8_t. @param a is a Q8n8 uint16_t*/
188 
189 inline
190 Q16n16 Q8n8_to_Q16n16(Q8n8 a) { return (static_cast<Q16n16>(a))<<8; } /**<Convert Q8n8 fix to Q16n16 uint32_t. @param a is a Q8n8 uint16_t*/
191 
192 inline
193 float Q8n8_to_float(Q8n8 a) { return (static_cast<float>(a))/256; } /**<Convert Q8n8 fix to float. @param a is a Q8n8 uint16_t*/
194 
195 inline
196 Q0n7 Q1n14_to_Q0n7(Q1n14 a) { return static_cast<Q0n7>((Q1n14)a>>7); } /**<Convert Q1n14 fixed to Q0n7 int8_t. @param a is a Q1n14 int16_t*/
197 
198 inline
199 float Q1n14_to_float(Q1n14 a) { return (static_cast<float>(a))/16384; } /**<Convert fix to float. @param a is an int16_t*/
200 
201 inline
202 Q0n8 Q1n15_to_Q0n8(Q1n15 a) { return static_cast<Q0n8>((Q1n15)a>>7); } /**<Convert Q1n15 fixed to Q0n8 uint8_t. Only for positive values! @param a is a Q1n15 uint16_t*/
203 
204 inline
205 float Q1n15_to_float(Q1n15 a) { return (static_cast<float>(a))/32768; } /**<Convert fix to float. @param a is a Q1n15 uint16_t*/
206 
207 inline
208 float Q0n16_to_float(Q0n16 a) { return (static_cast<float>(a))/65536; } /**<Convert fix to float. @param a is a Q0n16 uint16_t*/
209 
210 inline
211 Q15n16 Q15n0_to_Q15n16(Q15n0 a) { return (static_cast<Q15n16>(a))<<16; } /**<Convert Q15n0 int16_t to Q15n16 fix. @param a is a Q15n0 int16_t */
212 
213 inline
214 Q15n16 Q16n0_to_Q15n16(Q16n0 a) { return (static_cast<Q15n16>(a))<<16; } /**<Convert Q16n0 uint16_t to Q15n16 fix. @param a is a Q16n0 uint16_t */
215 
216 inline
217 Q23n8 Q16n0_to_Q23n8(Q16n0 a) { return (static_cast<Q23n8>(a))<<8; } /**<Convert Q16n0 uint16_t to Q23n8 fixed point signed int32_t. @param a is a Q16n0 uint16_t*/
218 
219 inline
220 Q24n8 Q16n0_to_Q24n8(Q16n0 a) { return (static_cast<Q24n8>(a))<<8; } /**<Convert Q16n0 uint16_t to Q24n8 fixed point uint32_t. @param a is a Q16n0 uint16_t*/
221 
222 inline
223 Q16n16 Q16n0_to_Q16n16(Q16n0 a) { return (static_cast<Q16n16>(a))<<16; } /**<Convert Q16n0 uint16_t to Q16n16 fixed point uint32_t. @param a is a Q16n0 uint16_t*/
224 
225 inline
226 float Q16n0_to_float(Q16n0 a) { return (static_cast<float>(a)); } /**<Convert Q16n0 uint16_t to float. @param a is a Q16n0 uint16_t*/
227 
228 inline
229 Q0n8 Q8n24_to_Q0n8(Q8n24 a) { return static_cast<Q0n8>((Q8n24)a>>16); } /**<Convert Q8n24 fixed to Q0n8 uint8_t. @param a is a Q8n24 uint32_t*/
230 
231 inline
232 float Q8n24_to_float(Q8n24 a) { return (static_cast<float>(a))/16777216; } /**<Convert fix to float. @param a is a Q8n24 uint32_t*/
233 
234 
235 inline
236 Q31n0 Q23n8_to_Q31n0(Q23n8 a) { return static_cast<Q31n0>((Q23n8)a>>8); } /**<Convert Q23n8 fixed to Q31n0 int32_t. @param a is a Q23n8 int32_t*/
237 
238 inline
239 Q16n0 Q23n8_to_Q16n0(Q23n8 a) { return static_cast<Q16n0>((Q23n8)a>>8); } /**<Convert Q23n8 fixed to Q16n0 uint16_t. Positive values only. @param a is a Q23n8 int32_t*/
240 
241 inline
242 Q15n0 Q23n8_to_Q15n0(Q23n8 a) { return static_cast<Q15n0>((Q23n8)a>>8); } /**<Convert Q23n8 fixed to Q15n0 signed int16_t. @param a is a Q23n8 int32_t*/
243 
244 inline
245 Q7n8 Q23n8_to_Q7n8(Q23n8 a) { return static_cast<Q7n8>(a); } /**<Convert Q23n8 fixed to Q7n8 signed int16_t, losing most significant bits. @param a is a Q23n8 signed int32_t.*/
246 
247 
248 inline
249 float Q23n8_to_float(Q23n8 a) { return (static_cast<float>(a))/256; } /**<Convert fix to float. @param a is a Q23n8 signed int32_t*/
250 
251 inline
252 Q0n8 Q24n8_to_Q0n8(Q24n8 a) { return static_cast<Q0n8>(a); } /**<Convert Q24n8 fixed to Q0n8 uint8_t. @param a is a Q24n8 uint32_t*/
253 
254 inline
255 Q16n16 Q24n8_to_Q16n0(Q24n8 a) { return (static_cast<Q16n0>((Q24n8)a))>>8; } /**<Convert Q24n8 fixed to Q16n0 uint16_t. @param a is a Q24n8 uint32_t*/
256 
257 inline
258 Q32n0 Q24n8_to_Q32n0(Q24n8 a) { return static_cast<Q32n0>((Q24n8)a>>8); } /**<Convert Q24n8 fixed to Q32n0 uint32_t. @param a is a Q24n8 uint32_t*/
259 
260 inline
261 Q16n16 Q24n8_to_Q16n16(Q24n8 a) { return (static_cast<Q16n16>(a))<<8; } /**<Convert Q24n8 fixed to Q16n16 uint32_t. @param a is a Q24n8 uint32_t*/
262 
263 inline
264 float Q24n8_to_float(Q24n8 a) { return (static_cast<float>(a))/256; } /**<Convert fix to float. @param a is a Q24n8 uint32_t*/
265 
266 inline
267 Q0n8 Q15n16_to_Q0n8(Q15n16 a) { return static_cast<Q0n8>((Q15n16)a>>8); } /**<Convert Q15n16 fixed to Q0n8 uint8_t. Only for positive values! @param a is a Q15n16 signed int32_t*/
268 
269 inline
270 Q8n0 Q15n16_to_Q8n0(Q15n16 a) { return static_cast<Q8n0>((Q15n16)a>>16); } /**<Convert Q15n16 fixed to Q8n0 uint8_t. Only for positive values! @param a is a Q15n16 signed int32_t*/
271 
272 inline
273 Q15n0 Q15n16_to_Q15n0(Q15n16 a) { return static_cast<Q15n0>((Q15n16)a>>16); } /**<Convert Q15n16 fixed to Q15n0 signed int16_t. @param a is a Q15n16 signed int32_t*/
274 
275 inline
276 Q7n8 Q15n16_to_Q7n8(Q15n16 a) { return static_cast<Q7n8>((Q15n16)a>>8); } /**<Convert Q15n16 fixed to Q7n8 signed int16_t, keeping middle bits only. @param a is a Q15n16 signed int32_t.*/
277 
278 inline
279 Q8n8 Q15n16_to_Q8n8(Q15n16 a) { return static_cast<Q8n8>((Q15n16)a>>8); } /**<Convert Q15n16 fixed to Q8n8 signed int16_t, keeping middle bits only. @param a is a Q15n16 signed int32_t.*/
280 
281 inline
282 Q23n8 Q15n16_to_Q23n8(Q15n16 a) { return static_cast<Q23n8>((Q15n16)a>>8); } /**<Convert Q15n16 fixed to Q23n8 signed int32_t. @param a is a Q15n16 signed int32_t.*/
283 
284 inline
285 float Q15n16_to_float(Q15n16 a) { return (static_cast<float>(a))/65536; } /**<Convert fix to float. @param a is a Q15n16 signed int32_t*/
286 
287 inline
288 Q0n8 Q16n16_to_Q0n8(Q16n16 a) { return static_cast<Q0n8>((Q16n16)a>>8); } /**<Convert Q16n16 fixed to Q0n8 uint8_t. @param a is a Q16n16 uint32_t*/
289 
290 inline
291 Q8n8 Q16n16_to_Q8n8(Q8n8 a) { return static_cast<Q8n8>((Q16n16)a>>16); } /**<Convert Q16n16 fixed to Q8n8 uint16_t. @param a is a Q16n16 uint32_t*/
292 
293 inline
294 Q16n0 Q16n16_to_Q16n0(Q16n16 a) { return static_cast<Q16n0>((Q16n16)a>>16); } /**<Convert Q16n16 fixed to Q16n0 uint16_t. @param a is a Q16n16 uint32_t*/
295 
296 inline
297 Q24n8 Q16n16_to_Q24n8(Q16n16 a) { return static_cast<Q24n8>((Q16n16)a>>8); } /**<Convert Q16n16 fixed to Q24n8 uint32_t. @param a is a Q16n16 uint32_t*/
298 
299 inline
300 float Q16n16_to_float(Q16n16 a) { return (static_cast<float>(a))/65536; } /**<Convert fix to float. @param a is a Q16n16 uint32_t*/
301 /** @}*/
302 
303 /* @ingroup fixmath
304 Fast (?) fixed point multiply for Q7n8 fractional numbers.
305 The c version below is 3 times faster, and not subject to the same overflow limitations (+-3.99, or +-2048)
306 @param a Q7n8 format multiplicand
307 @param b Q7n8 format multiplier
308 @return a Q7n8 format product
309 */
310 /*
311 #define Q7n8_mult(a,b) \
312 ({ \
313 int16_t prod, val1=a, val2=b ; \
314 __asm__ __volatile__ ( \
315  "muls %B1, %B2 \n\t" \
316  "mov %B0, r0 \n\t" \
317  "mul %A1, %A2\n\t" \
318  "mov %A0, r1 \n\t" \
319  "mulsu %B1, %A2 \n\t" \
320  "add %A0, r0 \n\t" \
321  "adc %B0, r1 \n\t" \
322  "mulsu %B2, %A1 \n\t" \
323  "add %A0, r0 \n\t" \
324  "adc %B0, r1 \n\t" \
325  "clr r1 \n\t" \
326  : "=&d" (prod) \
327  : "a" (val1), "a" (val2) \
328  ); \
329  prod; \
330 })
331 */
332 
333 /** @ingroup fixmath
334 Fast fixed point multiply for Q7n8 fractional numbers.
335 @param a Q7n8 format multiplicand
336 @param b Q7n8 format multiplier
337 @return a Q7n8 format product
338 */
339 inline
340 Q7n8 Q7n8_mult(Q7n8 a, Q7n8 b) {
341  return ((int16_t)((((int32_t)(a))*(b))>>8));
342 }
343 
344 
345 /*
346 #define FMULS8(v1, v2) \
347 ({ \
348  uint8_t res; \
349  uint8_t val1 = v1; \
350  uint8_t val2 = v2; \
351  __asm__ __volatile__ \
352  ( \
353  "fmuls $1, $2" "\n\t" \
354  "mov $0, r1" "\n\t" \
355  "clr r1" "\n\t" \
356  : "=&d" (res) \
357  : "a" (val1), "a" (val2) \
358  ); \
359  res; \
360 }) */
361 
362 
363 /*
364 // from octosynth, Joe Marshall 2011:
365 
366  // multiply 2 16 bit numbers together and shift 8 without precision loss
367  // requires assembler really
368  volatile uint8_t zeroReg=0;
369  volatile uint16_t multipliedCounter=oscillators[c].phaseStep;
370  asm volatile
371  (
372  // high uint8_ts mult together = high uint8_t
373  "ldi %A[outVal],0" "\n\t"
374  "mul %B[phaseStep],%B[pitchB}]" "\n\t"
375  "mov %B[outVal],r0" "\n\t"
376  // ignore overflow into r1 (should never overflow)
377  // low uint8_t * high uint8_t -> both uint8_ts
378  "mul %A[phaseStep],%B[pitchB}]" "\n\t"
379  "add %A[outVal],r0" "\n\t"
380  // carry into high uint8_t
381  "adc %B[outVal],r1" "\n\t"
382  // high uint8_t* low uint8_t -> both uint8_ts
383  "mul %B[phaseStep],%A[pitchB}]" "\n\t"
384  "add %A[outVal],r0" "\n\t"
385  // carry into high uint8_t
386  "adc %B[outVal],r1" "\n\t"
387  // low uint8_t * low uint8_t -> round
388  "mul %A[phaseStep],%A[pitchB}]" "\n\t"
389  // the adc below is to round up based on high bit of low*low:
390  "adc %A[outVal],r1" "\n\t"
391  "adc %B[outVal],%[ZERO]" "\n\t"
392  "clr r1" "\n\t"
393  :[outVal] "=&d" (multipliedCounter)
394  :[phaseStep] "d" (oscillators[c].phaseStep),[pitchB}] "d"( pitchB}Multiplier),[ZERO] "d" (zeroReg)
395  :"r1","r0"
396  );
397  oscillators[c].phaseStep=multipliedCounter;
398 
399  */
400 
401 
402 
403 int16_t ipow(int16_t base, int16_t exp); /**< dangerous overflow-prone int16_t power function */
404 
405 Q16n16 Q16n16_pow2(Q8n8 exponent);
406 
408 uint8_t uint8_tDiv(uint8_t n, uint8_t d);
409 uint8_t uint8_tRnd(uint8_t min, uint8_t max);
410 uint16_t isqrt16(uint16_t n);
411 uint32_t isqrt32(uint32_t n);
412 
413 #endif /* FIXEDMATH_H_ */
Q0n8 Q24n8_to_Q0n8(Q24n8 a)
Convert Q24n8 fixed to Q0n8 uint8_t.
-
float Q16n0_to_float(Q16n0 a)
Convert Q16n0 uint16_t to float.
-
Q8n8 Q16n16_to_Q8n8(Q8n8 a)
Convert Q16n16 fixed to Q8n8 uint16_t.
-
Q23n8 Q15n16_to_Q23n8(Q15n16 a)
Convert Q15n16 fixed to Q23n8 signed int32_t.
-
Q7n8 Q8n0_to_Q7n8(Q8n0 a)
Convert Q8n0 uint8_t to Q7n8 fix.
-
float Q24n8_to_float(Q24n8 a)
Convert fix to float.
-
Q16n16 Q16n0_to_Q16n16(Q16n0 a)
Convert Q16n0 uint16_t to Q16n16 fixed point uint32_t.
-
Q0n7 float_to_Q0n7(float a)
Convert float to Q0n7 fix.
Definition: mozzi_fixmath.h:94
-
int8_t Q0n7
signed fractional number using 7 fractional bits, represents -0.5 to 0.496
Definition: mozzi_fixmath.h:25
-
Q0n8 Q16n16_to_Q0n8(Q16n16 a)
Convert Q16n16 fixed to Q0n8 uint8_t.
-
Q15n0 Q15n16_to_Q15n0(Q15n16 a)
Convert Q15n16 fixed to Q15n0 signed int16_t.
-
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:40
-
Q15n16 Q0n8_to_Q15n16(Q0n8 a)
Convert Q0n8 uint8_t to Q15n16 fix.
-
Q8n24 float_to_Q8n24(float a)
Convert float to Q8n24 fix.
-
Q1n15 float_to_Q1n15(float a)
Convert float to Q1n15 fix.
-
Q1n14 float_to_Q1n14(float a)
Convert float to Q1n14 fix.
-
int8_t Q7n0
ordinary old signed Q7n0 int8_t with 0 fractional bits, represents -128 to 127
Definition: mozzi_fixmath.h:26
-
uint16_t Q8n8
unsigned fractional number using 8 integer bits and 8 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:35
-
Q15n16 Q7n8_to_Q15n16(Q7n8 a)
Convert Q7n8 fix to Q15n16.
-
uint32_t Q32n0
unsigned (normal uint32_t int16_t) number using 32 integer bits and 0 fractional bits, represents 0 to 4294967295
Definition: mozzi_fixmath.h:42
-
Q15n16 float_to_Q15n16(float a)
Convert float to Q15n16 fix.
-
float Q0n8_to_float(Q0n8 a)
Convert Q0n8 fix to float.
-
float Q8n24_to_float(Q8n24 a)
Convert fix to float.
-
Q0n7 Q1n14_to_Q0n7(Q1n14 a)
Convert Q1n14 fixed to Q0n7 int8_t.
-
float Q8n8_to_float(Q8n8 a)
Convert Q8n8 fix to float.
-
Q15n16 Q16n0_to_Q15n16(Q16n0 a)
Convert Q16n0 uint16_t to Q15n16 fix.
-
Q7n8 Q15n16_to_Q7n8(Q15n16 a)
Convert Q15n16 fixed to Q7n8 signed int16_t, keeping middle bits only.
-
Q24n8 Q16n0_to_Q24n8(Q16n0 a)
Convert Q16n0 uint16_t to Q24n8 fixed point uint32_t.
-
Q16n16 Q24n8_to_Q16n0(Q24n8 a)
Convert Q24n8 fixed to Q16n0 uint16_t.
-
Q8n0 Q15n16_to_Q8n0(Q15n16 a)
Convert Q15n16 fixed to Q8n0 uint8_t.
-
Q7n0 Q7n8_to_Q7n0(Q7n8 a)
Convert Q7n8 fix to Q7n0.
-
Q15n16 Q15n0_to_Q15n16(Q15n0 a)
Convert Q15n0 int16_t to Q15n16 fix.
-
Q15n16 Q0n7_to_Q15n16(Q0n7 a)
Convert Q0n7 signed int8_t to Q15n16 fix.
-
Q8n24 Q0n8_to_Q8n24(Q0n8 a)
Convert Q0n8 uint8_t to Q8n24 fix.
-
Q23n8 Q16n0_to_Q23n8(Q16n0 a)
Convert Q16n0 uint16_t to Q23n8 fixed point signed int32_t.
-
Q7n8 Q7n8_mult(Q7n8 a, Q7n8 b)
Fast fixed point multiply for Q7n8 fractional numbers.
-
int16_t Q1n14
signed fractional number using 1 integer bit and 14 fractional bits, represents -1.999 to 1.999
Definition: mozzi_fixmath.h:33
-
Q32n0 Q24n8_to_Q32n0(Q24n8 a)
Convert Q24n8 fixed to Q32n0 uint32_t.
-
Q16n16 float_to_Q16n16(float a)
Convert float to Q16n16 fix.
-
float Q16n16_to_float(Q16n16 a)
Convert fix to float.
-
uint32_t Q0n32
unsigned fractional number using 0 integer bits and 32 fractional bits, represents 0 to 0...
Definition: mozzi_fixmath.h:43
-
Q0n8 Q15n16_to_Q0n8(Q15n16 a)
Convert Q15n16 fixed to Q0n8 uint8_t.
-
Q16n16 Q24n8_to_Q16n16(Q24n8 a)
Convert Q24n8 fixed to Q16n16 uint32_t.
-
int32_t Q31n0
signed (normal int32_t int16_t) number using 31 integer bits and 0 fractional bits, represents -2147483648 to 2147483647
Definition: mozzi_fixmath.h:41
-
Q31n0 Q23n8_to_Q31n0(Q23n8 a)
Convert Q23n8 fixed to Q31n0 int32_t.
-
Q15n16 Q7n0_to_Q15n16(Q7n0 a)
Convert Q7n0 int8_t to Q15n16 fix.
-
uint32_t Q0n31
signed number using 0 integer bits and 31 fractional bits, represents -0.2147483648 to 0...
Definition: mozzi_fixmath.h:30
-
float Q0n7_to_float(Q0n7 a)
Convert Q0n7 fix to float.
-
Q8n8 float_to_Q8n8(float a)
Convert float to Q8n8 fix.
-
Q15n16 Q8n0_to_Q15n16(Q8n0 a)
Convert Q8n0 uint8_t to Q15n16 fix.
-
uint16_t Q16n0
unsigned number using 16 integer bits and 0 fractional bits, represents 0 to 65536.0
Definition: mozzi_fixmath.h:38
-
int16_t Q0n15
signed fractional number using 0 integer bits and 15 fractional bits, represents -0.32768 to 0.32767
Definition: mozzi_fixmath.h:36
-
float Q23n8_to_float(Q23n8 a)
Convert fix to float.
-
Q7n8 Q7n0_to_Q7n8(Q7n0 a)
Convert Q7n0 int8_t to Q7n8 fix.
-
uint16_t Q3n13
unsigned fractional number using 3 integer bits and 13 fractional bits, represents 0 to 7...
Definition: mozzi_fixmath.h:32
-
Q0n8 float_to_Q0n8(float a)
Convert float to Q0n8 fix.
Definition: mozzi_fixmath.h:97
-
Q23n8 float_to_Q23n8(float a)
Convert float to Q23n8 fix.
-
uint16_t Q0n16
unsigned fractional number using 16 fractional bits, represents 0.0 to 0.999
Definition: mozzi_fixmath.h:29
-
Q24n8 Q16n16_to_Q24n8(Q16n16 a)
Convert Q16n16 fixed to Q24n8 uint32_t.
-
float Q0n16_to_float(Q0n16 a)
Convert fix to float.
-
Q8n0 Q8n8_to_Q8n0(Q8n8 a)
Convert Q8n8 fix to Q8n0 uint8_t.
-
float Q1n14_to_float(Q1n14 a)
Convert fix to float.
-
float Q15n16_to_float(Q15n16 a)
Convert fix to float.
-
float Q1n15_to_float(Q1n15 a)
Convert fix to float.
-
Q7n8 float_to_Q7n8(float a)
Convert float to Q7n8 fix.
-
uint8_t uint8_tMod(uint8_t n, uint8_t d)
fast uint8_t modulus
-
uint16_t Q1n15
unsigned fractional number using 1 integer bit and 15 fractional bits, represents 0 to 1...
Definition: mozzi_fixmath.h:37
-
Q1n15 Q0n8_to_Q1n15(Q0n8 a)
Convert Q0n8 uint8_t to Q1n15 fix.
-
Q16n16 Q0n8_to_Q16n16(Q0n8 a)
Convert Q0n8 uint8_t to Q16n16 fix.
-
uint32_t Q24n8
unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215 ...
Definition: mozzi_fixmath.h:45
-
Q8n8 Q0n8_to_Q8n8(Q0n8 a)
Convert Q0n8 uint8_t to Q8n8 fix.
-
Q16n0 Q16n16_to_Q16n0(Q16n16 a)
Convert Q16n16 fixed to Q16n0 uint16_t.
-
Q24n8 Q0n8_to_Q24n8(Q0n8 a)
Convert Q0n8 uint8_t to Q24n8 fix.
-
Q1n14 Q0n7_to_Q1n14(Q0n7 a)
Convert Q0n7 int8_t to Q1n14 fix.
-
int16_t Q15n0
signed number using 15 integer bits and 0 fractional bits, represents -32768 to 32767 ...
Definition: mozzi_fixmath.h:34
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46
-
Q24n8 float_to_Q24n8(float a)
Convert float to Q24n8 fix.
-
Q8n8 Q8n0_to_Q8n8(Q8n0 a)
Convert uint8_t to Q8n8 fix.
-
Q0n16 float_to_Q0n16(float a)
Convert float to Q0n16 fix.
-
int16_t Q7n8
signed fractional number using 7 integer bits and 8 fractional bits, represents -127.996 to 127.996
Definition: mozzi_fixmath.h:31
-
uint8_t Q8n0
normal uint8_t with 0 fractional bits, represents 0.0 to 255.0
Definition: mozzi_fixmath.h:28
-
Q16n16 Q8n0_to_Q16n16(Q8n0 a)
Convert Q8n0 uint8_t to Q16n16 fix.
-
Q0n8 Q1n15_to_Q0n8(Q1n15 a)
Convert Q1n15 fixed to Q0n8 uint8_t.
-
uint32_t Q8n24
signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:44
-
uint8_t Q0n8
unsigned fractional number using 8 fractional bits, represents 0.0 to 0.996
Definition: mozzi_fixmath.h:27
-
Q16n0 Q23n8_to_Q16n0(Q23n8 a)
Convert Q23n8 fixed to Q16n0 uint16_t.
-
Q15n0 Q23n8_to_Q15n0(Q23n8 a)
Convert Q23n8 fixed to Q15n0 signed int16_t.
-
Q0n8 Q8n24_to_Q0n8(Q8n24 a)
Convert Q8n24 fixed to Q0n8 uint8_t.
-
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
-
Q16n16 Q8n8_to_Q16n16(Q8n8 a)
Convert Q8n8 fix to Q16n16 uint32_t.
-
Q8n8 Q15n16_to_Q8n8(Q15n16 a)
Convert Q15n16 fixed to Q8n8 signed int16_t, keeping middle bits only.
-
Q7n8 Q23n8_to_Q7n8(Q23n8 a)
Convert Q23n8 fixed to Q7n8 signed int16_t, losing most significant bits.
-
float Q7n8_to_float(Q7n8 a)
Convert Q7n8 fix to float.
+
1 /*
+
2  * mozzi_fixmath.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 FIXEDMATH_H_
+
13 #define FIXEDMATH_H_
+
14 
+
15 #include <Arduino.h>
+
16 
+
17 /** @defgroup fixmath Fast integer based fixed-point arithmetic
+
18 
+
19 @note For new sketches it is recommended to utitlize the FixMath library with its typesafe classes UFix and SFix, instead of these
+
20  typedefs! See https://github.com/tomcombriat/FixMath . These are provided for backwards compatibility, only.
+
21 
+
22 Fixed point fractional number types and conversion routines. Fixed point is often best for fast audio code for Arduino, and these can ease some of the pain. </p><dl class="section note"><dt>Note</dt><dd>Take care when converting that the important bits of your numbers will fit in the types you choose!
+
23 
+
24 Timing: converting between fixed and float 10-12us, converting between fixed types about 1us.
+
25 */
+
26 
+
27 /** @ingroup fixmath
+
28 @{
+
29 */
+
30 // types
+
31 typedef int8_t Q0n7; /**< signed fractional number using 7 fractional bits, represents -0.5 to 0.496*/
+
32 typedef int8_t Q7n0; /**< ordinary old signed Q7n0 int8_t with 0 fractional bits, represents -128 to 127*/
+
33 typedef uint8_t Q0n8; /**< unsigned fractional number using 8 fractional bits, represents 0.0 to 0.996*/
+
34 typedef uint8_t Q8n0; /**< normal uint8_t with 0 fractional bits, represents 0.0 to 255.0*/
+
35 typedef uint16_t Q0n16; /**< unsigned fractional number using 16 fractional bits, represents 0.0 to 0.999*/
+
36 typedef uint32_t Q0n31; /**< signed number using 0 integer bits and 31 fractional bits, represents -0.2147483648 to 0.2147483647*/
+
37 typedef int16_t Q7n8; /**< signed fractional number using 7 integer bits and 8 fractional bits, represents -127.996 to 127.996*/
+
38 typedef uint16_t Q3n13; /**< unsigned fractional number using 3 integer bits and 13 fractional bits, represents 0 to 7.999*/
+
39 typedef int16_t Q1n14; /**< signed fractional number using 1 integer bit and 14 fractional bits, represents -1.999 to 1.999*/
+
40 typedef int16_t Q15n0; /**< signed number using 15 integer bits and 0 fractional bits, represents -32768 to 32767*/
+
41 typedef uint16_t Q8n8; /**< unsigned fractional number using 8 integer bits and 8 fractional bits, represents 0 to 255.996*/
+
42 typedef int16_t Q0n15; /**< signed fractional number using 0 integer bits and 15 fractional bits, represents -0.32768 to 0.32767*/
+
43 typedef uint16_t Q1n15; /**< unsigned fractional number using 1 integer bit and 15 fractional bits, represents 0 to 1.999*/
+
44 typedef uint16_t Q16n0; /**< unsigned number using 16 integer bits and 0 fractional bits, represents 0 to 65536.0*/
+
45 typedef int32_t Q23n8; /**< signed fractional number using 23 integer bits and 8 fractional bits, represents -8388607.996 to 8388607.996*/
+
46 typedef int32_t Q15n16; /**< signed fractional number using 15 integer bits and 16 fractional bits, represents -32767.999 to 32767.999*/
+
47 typedef int32_t Q31n0; /**< signed (normal int32_t int16_t) number using 31 integer bits and 0 fractional bits, represents -2147483648 to 2147483647*/
+
48 typedef uint32_t Q32n0; /**< unsigned (normal uint32_t int16_t) number using 32 integer bits and 0 fractional bits, represents 0 to 4294967295*/
+
49 typedef uint32_t Q0n32; /**< unsigned fractional number using 0 integer bits and 32 fractional bits, represents 0 to 0.999999999767169*/
+
50 typedef uint32_t Q8n24; /**< signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255.999*/
+
51 typedef uint32_t Q24n8; /**< unsigned fractional number using 24 integer bits and 8 fractional bits, represents 0 to 16777215*/
+
52 typedef uint32_t Q16n16; /**< unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535.999*/
+
53 /** @}*/
+
54 
+
55 /** @ingroup fixmath
+
56 @{
+
57 */
+
58 // macros to save runtime calculations for representations of 1
+
59 #define Q0n7_FIX1 ((Q0n7) 127) /**< 0.992 in Q0n7 format*/
+
60 #define Q7n8_FIX1 ((Q7n8) 256) /**< 1 in Q7n8 format*/
+
61 #define Q8n8_FIX1 ((Q8n8) 256) /**< 1 in Q8n8 format*/
+
62 #define Q23n8_FIX1 ((Q23n8) 256) /**< 1 in Q23n8 format*/
+
63 #define Q1n14_FIX1 ((Q1n14) 16384) /**< 1 in Q1n14 format*/
+
64 #define Q1n15_FIX1 ((Q1n15) 32768) /**< 1 in Q1n15 format*/
+
65 #define Q16n16_FIX1 ((Q16n16) 65536) /**< 1 in Q16n16 format*/
+
66 #define Q0n15_FIX1 ((Q0n15) 32767) /**< 0.999 in Q0n15 format*/
+
67 #define Q0n16_FIX1 ((Q0n16) 65535) /**< 0.999 in Q0n16 format*/
+
68 #define Q15n0_FIX1 ((Q15n0) 16384) /**< 1 in Q15n0 format*/
+
69 #define Q15n16_FIX1 ((Q15n16) 65536) /**< 1 in Q15n16 format*/
+
70 #define Q8n24_FIX1 ((Q8n24) 16777216) /**< 1 in Q8n24 format*/
+
71 #define Q0n32_FIX1 ((Q0n32) 4294967295) /**< 0.999999999767169 in Q0n32 format*/
+
72 
+
73 #define Q16n16_PI ((Q16n16) 205887) /**< PI in Q16n16 format*/
+
74 #define Q3n13_2PI ((Q3n13) 411775) /**< 2*PI in Q3n13 format*/
+
75 #define Q16n16_2PI ((Q16n16) 411775) /**< 2*PI in Q16n16 format*/
+
76 
+
77 #define low15bits ((Q1n15) 32767) /**< Useful for keeping the lower 15 bits of a Q1n15 number, using &*/
+
78 /** @}*/
+
79 
+
80 
+
81 /*
+
82 Type conversions: Float to Q
+
83 
+
84 To convert a number from floating point to Qm.n format:
+
85 
+
86  Multiply the floating point number by 2^n
+
87  Round to the nearest integer
+
88 
+
89 Q to float
+
90 
+
91 To convert a number from Qm.n format to floating point:
+
92 
+
93  Convert the number to floating point as if it were an integer
+
94  Multiply by 2^-n
+
95 */
+
96 /** @ingroup fixmath
+
97 @{
+
98 */
+
99 inline
+
100 Q0n7 float_to_Q0n7(float a) { return static_cast<Q0n7>(a*256); } /**<Convert float to Q0n7 fix. @param a is a float*/
+
101 
+
102 inline
+
103 Q0n8 float_to_Q0n8(float a) { return static_cast<Q0n8>(a*256); } /**<Convert float to Q0n8 fix. @param a is a float*/
+
104 
+
105 inline
+
106 Q7n8 float_to_Q7n8(float a) { return static_cast<Q7n8>(a*256); } /**<Convert float to Q7n8 fix. @param a is a float*/
+
107 
+
108 inline
+
109 Q8n8 float_to_Q8n8(float a) { return static_cast<Q8n8>(a*256); } /**<Convert float to Q8n8 fix. @param a is a float*/
+
110 
+
111 inline
+
112 Q1n14 float_to_Q1n14(float a) { return static_cast<Q1n14>(a*16384); } /**<Convert float to Q1n14 fix. @param a is a float*/
+
113 
+
114 inline
+
115 Q1n15 float_to_Q1n15(float a) { return static_cast<Q1n15>(a*32768); } /**<Convert float to Q1n15 fix. @param a is a float*/
+
116 
+
117 inline
+
118 Q8n24 float_to_Q8n24(float a) { return static_cast<Q8n24>(a*16777216); } /**<Convert float to Q8n24 fix. @param a is a float*/
+
119 
+
120 inline
+
121 Q23n8 float_to_Q23n8(float a) { return static_cast<Q23n8>(a*256); } /**<Convert float to Q23n8 fix. @param a is a float*/
+
122 
+
123 inline
+
124 Q24n8 float_to_Q24n8(float a) { return static_cast<Q24n8>(a*256); } /**<Convert float to Q24n8 fix. @param a is a float*/
+
125 
+
126 inline
+
127 Q16n16 float_to_Q16n16(float a) { return static_cast<Q16n16>(a*65536); } /**<Convert float to Q16n16 fix. @param a is a float*/
+
128 
+
129 inline
+
130 Q0n16 float_to_Q0n16(float a) { return static_cast<Q0n16>(a*65536); } /**<Convert float to Q0n16 fix. @param a is a float*/
+
131 
+
132 inline
+
133 Q15n16 float_to_Q15n16(float a) { return static_cast<Q15n16>(a*65536); } /**<Convert float to Q15n16 fix. @param a is a float*/
+
134 
+
135 inline
+
136 Q1n14 Q0n7_to_Q1n14(Q0n7 a) { return (static_cast<Q1n14>(a))<<7; } /**<Convert Q0n7 int8_t to Q1n14 fix. @param a is a Q0n7 int8_t */
+
137 
+
138 inline
+
139 Q15n16 Q0n7_to_Q15n16(Q0n7 a) { return (static_cast<Q15n16>(a))<<8; } /**<Convert Q0n7 signed int8_t to Q15n16 fix. @param a is a Q0n7 signed int8_t */
+
140 
+
141 inline
+
142 float Q0n7_to_float(Q0n7 a) { return (static_cast<float>(a))/256; } /**<Convert Q0n7 fix to float. @param a is a Q0n7 int8_t*/
+
143 
+
144 inline
+
145 Q1n15 Q0n8_to_Q1n15(Q0n8 a) { return (static_cast<Q1n15>(a))<<7; } /**<Convert Q0n8 uint8_t to Q1n15 fix. @param a is a Q0n8 uint8_t */
+
146 
+
147 inline
+
148 Q8n8 Q0n8_to_Q8n8(Q0n8 a) { return (static_cast<Q8n8>(a))<<8; } /**<Convert Q0n8 uint8_t to Q8n8 fix. @param a is a Q0n8 uint8_t */
+
149 
+
150 inline
+
151 Q8n24 Q0n8_to_Q8n24(Q0n8 a) { return (static_cast<Q8n24>(a))<<16; } /**<Convert Q0n8 uint8_t to Q8n24 fix. @param a is a Q0n8 uint8_t */
+
152 
+
153 inline
+
154 Q24n8 Q0n8_to_Q24n8(Q0n8 a) { return (static_cast<Q24n8>(a))<<8; } /**<Convert Q0n8 uint8_t to Q24n8 fix. @param a is a Q0n8 uint8_t */
+
155 
+
156 inline
+
157 Q15n16 Q0n8_to_Q15n16(Q0n8 a) { return (static_cast<Q15n16>(a))<<8; } /**<Convert Q0n8 uint8_t to Q15n16 fix. @param a is a Q0n8 uint8_t */
+
158 
+
159 inline
+
160 Q16n16 Q0n8_to_Q16n16(Q0n8 a) { return (static_cast<Q16n16>(a))<<8; } /**<Convert Q0n8 uint8_t to Q16n16 fix. @param a is a Q0n8 uint8_t */
+
161 
+
162 inline
+
163 float Q0n8_to_float(Q0n8 a) { return (static_cast<float>(a))/256; } /**<Convert Q0n8 fix to float. @param a is a Q0n8 uint8_t*/
+
164 
+
165 inline
+
166 Q7n8 Q7n0_to_Q7n8(Q7n0 a) { return (static_cast<Q7n8>(a))<<8; } /**<Convert Q7n0 int8_t to Q7n8 fix. @param a is a int8_t*/
+
167 
+
168 inline
+
169 Q15n16 Q7n0_to_Q15n16(Q7n0 a) { return (static_cast<Q15n16>(a))<<16; } /**<Convert Q7n0 int8_t to Q15n16 fix. @param a is a int8_t*/
+
170 
+
171 inline
+
172 Q7n8 Q8n0_to_Q7n8(Q8n0 a) { return (static_cast<Q7n8>(a))<<8; } /**<Convert Q8n0 uint8_t to Q7n8 fix. @param a is a Q8n0 uint8_t*. Beware of overflow. */
+
173 
+
174 inline
+
175 Q8n8 Q8n0_to_Q8n8(Q8n0 a) { return (static_cast<Q8n8>(a))<<8; } /**<Convert uint8_t to Q8n8 fix. @param a is a Q8n0 uint8_t*/
+
176 
+
177 inline
+
178 Q15n16 Q8n0_to_Q15n16(Q8n0 a) { return (static_cast<Q15n16>(a))<<16; } /**<Convert Q8n0 uint8_t to Q15n16 fix. @param a is a Q8n0 uint8_t */
+
179 
+
180 inline
+
181 Q16n16 Q8n0_to_Q16n16(Q8n0 a) { return (static_cast<Q16n16>(a))<<16; } /**<Convert Q8n0 uint8_t to Q16n16 fix. @param a is a Q8n0 uint8_t */
+
182 
+
183 inline
+
184 Q7n0 Q7n8_to_Q7n0(Q7n8 a) { return static_cast<Q7n0>((Q7n8)a>>8); } /**<Convert Q7n8 fix to Q7n0. @param a is a Q7n8 int16_t*/
+
185 
+
186 inline
+
187 Q15n16 Q7n8_to_Q15n16(Q7n8 a) { return (static_cast<Q15n16>(a))<<8; } /**<Convert Q7n8 fix to Q15n16. @param a is a Q7n8 int16_t*/
+
188 
+
189 inline
+
190 float Q7n8_to_float(Q7n8 a) { return (static_cast<float>(a))/256; } /**<Convert Q7n8 fix to float. @param a is a Q7n8 int16_t*/
+
191 
+
192 inline
+
193 Q8n0 Q8n8_to_Q8n0(Q8n8 a) { return static_cast<Q8n0>((Q8n8)a>>8); } /**<Convert Q8n8 fix to Q8n0 uint8_t. @param a is a Q8n8 uint16_t*/
+
194 
+
195 inline
+
196 Q16n16 Q8n8_to_Q16n16(Q8n8 a) { return (static_cast<Q16n16>(a))<<8; } /**<Convert Q8n8 fix to Q16n16 uint32_t. @param a is a Q8n8 uint16_t*/
+
197 
+
198 inline
+
199 float Q8n8_to_float(Q8n8 a) { return (static_cast<float>(a))/256; } /**<Convert Q8n8 fix to float. @param a is a Q8n8 uint16_t*/
+
200 
+
201 inline
+
202 Q0n7 Q1n14_to_Q0n7(Q1n14 a) { return static_cast<Q0n7>((Q1n14)a>>7); } /**<Convert Q1n14 fixed to Q0n7 int8_t. @param a is a Q1n14 int16_t*/
+
203 
+
204 inline
+
205 float Q1n14_to_float(Q1n14 a) { return (static_cast<float>(a))/16384; } /**<Convert fix to float. @param a is an int16_t*/
+
206 
+
207 inline
+
208 Q0n8 Q1n15_to_Q0n8(Q1n15 a) { return static_cast<Q0n8>((Q1n15)a>>7); } /**<Convert Q1n15 fixed to Q0n8 uint8_t. Only for positive values! @param a is a Q1n15 uint16_t*/
+
209 
+
210 inline
+
211 float Q1n15_to_float(Q1n15 a) { return (static_cast<float>(a))/32768; } /**<Convert fix to float. @param a is a Q1n15 uint16_t*/
+
212 
+
213 inline
+
214 float Q0n16_to_float(Q0n16 a) { return (static_cast<float>(a))/65536; } /**<Convert fix to float. @param a is a Q0n16 uint16_t*/
+
215 
+
216 inline
+
217 Q15n16 Q15n0_to_Q15n16(Q15n0 a) { return (static_cast<Q15n16>(a))<<16; } /**<Convert Q15n0 int16_t to Q15n16 fix. @param a is a Q15n0 int16_t */
+
218 
+
219 inline
+
220 Q15n16 Q16n0_to_Q15n16(Q16n0 a) { return (static_cast<Q15n16>(a))<<16; } /**<Convert Q16n0 uint16_t to Q15n16 fix. @param a is a Q16n0 uint16_t */
+
221 
+
222 inline
+
223 Q23n8 Q16n0_to_Q23n8(Q16n0 a) { return (static_cast<Q23n8>(a))<<8; } /**<Convert Q16n0 uint16_t to Q23n8 fixed point signed int32_t. @param a is a Q16n0 uint16_t*/
+
224 
+
225 inline
+
226 Q24n8 Q16n0_to_Q24n8(Q16n0 a) { return (static_cast<Q24n8>(a))<<8; } /**<Convert Q16n0 uint16_t to Q24n8 fixed point uint32_t. @param a is a Q16n0 uint16_t*/
+
227 
+
228 inline
+
229 Q16n16 Q16n0_to_Q16n16(Q16n0 a) { return (static_cast<Q16n16>(a))<<16; } /**<Convert Q16n0 uint16_t to Q16n16 fixed point uint32_t. @param a is a Q16n0 uint16_t*/
+
230 
+
231 inline
+
232 float Q16n0_to_float(Q16n0 a) { return (static_cast<float>(a)); } /**<Convert Q16n0 uint16_t to float. @param a is a Q16n0 uint16_t*/
+
233 
+
234 inline
+
235 Q0n8 Q8n24_to_Q0n8(Q8n24 a) { return static_cast<Q0n8>((Q8n24)a>>16); } /**<Convert Q8n24 fixed to Q0n8 uint8_t. @param a is a Q8n24 uint32_t*/
+
236 
+
237 inline
+
238 float Q8n24_to_float(Q8n24 a) { return (static_cast<float>(a))/16777216; } /**<Convert fix to float. @param a is a Q8n24 uint32_t*/
+
239 
+
240 
+
241 inline
+
242 Q31n0 Q23n8_to_Q31n0(Q23n8 a) { return static_cast<Q31n0>((Q23n8)a>>8); } /**<Convert Q23n8 fixed to Q31n0 int32_t. @param a is a Q23n8 int32_t*/
+
243 
+
244 inline
+
245 Q16n0 Q23n8_to_Q16n0(Q23n8 a) { return static_cast<Q16n0>((Q23n8)a>>8); } /**<Convert Q23n8 fixed to Q16n0 uint16_t. Positive values only. @param a is a Q23n8 int32_t*/
+
246 
+
247 inline
+
248 Q15n0 Q23n8_to_Q15n0(Q23n8 a) { return static_cast<Q15n0>((Q23n8)a>>8); } /**<Convert Q23n8 fixed to Q15n0 signed int16_t. @param a is a Q23n8 int32_t*/
+
249 
+
250 inline
+
251 Q7n8 Q23n8_to_Q7n8(Q23n8 a) { return static_cast<Q7n8>(a); } /**<Convert Q23n8 fixed to Q7n8 signed int16_t, losing most significant bits. @param a is a Q23n8 signed int32_t.*/
+
252 
+
253 
+
254 inline
+
255 float Q23n8_to_float(Q23n8 a) { return (static_cast<float>(a))/256; } /**<Convert fix to float. @param a is a Q23n8 signed int32_t*/
+
256 
+
257 inline
+
258 Q0n8 Q24n8_to_Q0n8(Q24n8 a) { return static_cast<Q0n8>(a); } /**<Convert Q24n8 fixed to Q0n8 uint8_t. @param a is a Q24n8 uint32_t*/
+
259 
+
260 inline
+
261 Q16n16 Q24n8_to_Q16n0(Q24n8 a) { return (static_cast<Q16n0>((Q24n8)a))>>8; } /**<Convert Q24n8 fixed to Q16n0 uint16_t. @param a is a Q24n8 uint32_t*/
+
262 
+
263 inline
+
264 Q32n0 Q24n8_to_Q32n0(Q24n8 a) { return static_cast<Q32n0>((Q24n8)a>>8); } /**<Convert Q24n8 fixed to Q32n0 uint32_t. @param a is a Q24n8 uint32_t*/
+
265 
+
266 inline
+
267 Q16n16 Q24n8_to_Q16n16(Q24n8 a) { return (static_cast<Q16n16>(a))<<8; } /**<Convert Q24n8 fixed to Q16n16 uint32_t. @param a is a Q24n8 uint32_t*/
+
268 
+
269 inline
+
270 float Q24n8_to_float(Q24n8 a) { return (static_cast<float>(a))/256; } /**<Convert fix to float. @param a is a Q24n8 uint32_t*/
+
271 
+
272 inline
+
273 Q0n8 Q15n16_to_Q0n8(Q15n16 a) { return static_cast<Q0n8>((Q15n16)a>>8); } /**<Convert Q15n16 fixed to Q0n8 uint8_t. Only for positive values! @param a is a Q15n16 signed int32_t*/
+
274 
+
275 inline
+
276 Q8n0 Q15n16_to_Q8n0(Q15n16 a) { return static_cast<Q8n0>((Q15n16)a>>16); } /**<Convert Q15n16 fixed to Q8n0 uint8_t. Only for positive values! @param a is a Q15n16 signed int32_t*/
+
277 
+
278 inline
+
279 Q15n0 Q15n16_to_Q15n0(Q15n16 a) { return static_cast<Q15n0>((Q15n16)a>>16); } /**<Convert Q15n16 fixed to Q15n0 signed int16_t. @param a is a Q15n16 signed int32_t*/
+
280 
+
281 inline
+
282 Q7n8 Q15n16_to_Q7n8(Q15n16 a) { return static_cast<Q7n8>((Q15n16)a>>8); } /**<Convert Q15n16 fixed to Q7n8 signed int16_t, keeping middle bits only. @param a is a Q15n16 signed int32_t.*/
+
283 
+
284 inline
+
285 Q8n8 Q15n16_to_Q8n8(Q15n16 a) { return static_cast<Q8n8>((Q15n16)a>>8); } /**<Convert Q15n16 fixed to Q8n8 signed int16_t, keeping middle bits only. @param a is a Q15n16 signed int32_t.*/
+
286 
+
287 inline
+
288 Q23n8 Q15n16_to_Q23n8(Q15n16 a) { return static_cast<Q23n8>((Q15n16)a>>8); } /**<Convert Q15n16 fixed to Q23n8 signed int32_t. @param a is a Q15n16 signed int32_t.*/
+
289 
+
290 inline
+
291 float Q15n16_to_float(Q15n16 a) { return (static_cast<float>(a))/65536; } /**<Convert fix to float. @param a is a Q15n16 signed int32_t*/
+
292 
+
293 inline
+
294 Q0n8 Q16n16_to_Q0n8(Q16n16 a) { return static_cast<Q0n8>((Q16n16)a>>8); } /**<Convert Q16n16 fixed to Q0n8 uint8_t. @param a is a Q16n16 uint32_t*/
+
295 
+
296 inline
+
297 Q8n8 Q16n16_to_Q8n8(Q8n8 a) { return static_cast<Q8n8>((Q16n16)a>>16); } /**<Convert Q16n16 fixed to Q8n8 uint16_t. @param a is a Q16n16 uint32_t*/
+
298 
+
299 inline
+
300 Q16n0 Q16n16_to_Q16n0(Q16n16 a) { return static_cast<Q16n0>((Q16n16)a>>16); } /**<Convert Q16n16 fixed to Q16n0 uint16_t. @param a is a Q16n16 uint32_t*/
+
301 
+
302 inline
+
303 Q24n8 Q16n16_to_Q24n8(Q16n16 a) { return static_cast<Q24n8>((Q16n16)a>>8); } /**<Convert Q16n16 fixed to Q24n8 uint32_t. @param a is a Q16n16 uint32_t*/
+
304 
+
305 inline
+
306 float Q16n16_to_float(Q16n16 a) { return (static_cast<float>(a))/65536; } /**<Convert fix to float. @param a is a Q16n16 uint32_t*/
+
307 /** @}*/
+
308 
+
309 /* @ingroup fixmath
+
310 Fast (?) fixed point multiply for Q7n8 fractional numbers.
+
311 The c version below is 3 times faster, and not subject to the same overflow limitations (+-3.99, or +-2048)
+
312 @param a Q7n8 format multiplicand
+
313 @param b Q7n8 format multiplier
+
314 @return a Q7n8 format product
+
315 */
+
316 /*
+
317 #define Q7n8_mult(a,b) \
+
318 ({ \
+
319 int16_t prod, val1=a, val2=b ; \
+
320 __asm__ __volatile__ ( \
+
321  "muls %B1, %B2 \n\t" \
+
322  "mov %B0, r0 \n\t" \
+
323  "mul %A1, %A2\n\t" \
+
324  "mov %A0, r1 \n\t" \
+
325  "mulsu %B1, %A2 \n\t" \
+
326  "add %A0, r0 \n\t" \
+
327  "adc %B0, r1 \n\t" \
+
328  "mulsu %B2, %A1 \n\t" \
+
329  "add %A0, r0 \n\t" \
+
330  "adc %B0, r1 \n\t" \
+
331  "clr r1 \n\t" \
+
332  : "=&d" (prod) \
+
333  : "a" (val1), "a" (val2) \
+
334  ); \
+
335  prod; \
+
336 })
+
337 */
+
338 
+
339 /** @ingroup fixmath
+
340 Fast fixed point multiply for Q7n8 fractional numbers.
+
341 @param a Q7n8 format multiplicand
+
342 @param b Q7n8 format multiplier
+
343 @return a Q7n8 format product
+
344 */
+
345 inline
+
346 Q7n8 Q7n8_mult(Q7n8 a, Q7n8 b) {
+
347  return ((int16_t)((((int32_t)(a))*(b))>>8));
+
348 }
+
349 
+
350 
+
351 /*
+
352 #define FMULS8(v1, v2) \
+
353 ({ \
+
354  uint8_t res; \
+
355  uint8_t val1 = v1; \
+
356  uint8_t val2 = v2; \
+
357  __asm__ __volatile__ \
+
358  ( \
+
359  "fmuls $1, $2" "\n\t" \
+
360  "mov $0, r1" "\n\t" \
+
361  "clr r1" "\n\t" \
+
362  : "=&d" (res) \
+
363  : "a" (val1), "a" (val2) \
+
364  ); \
+
365  res; \
+
366 }) */
+
367 
+
368 
+
369 /*
+
370 // from octosynth, Joe Marshall 2011:
+
371 
+
372  // multiply 2 16 bit numbers together and shift 8 without precision loss
+
373  // requires assembler really
+
374  volatile uint8_t zeroReg=0;
+
375  volatile uint16_t multipliedCounter=oscillators[c].phaseStep;
+
376  asm volatile
+
377  (
+
378  // high uint8_ts mult together = high uint8_t
+
379  "ldi %A[outVal],0" "\n\t"
+
380  "mul %B[phaseStep],%B[pitchB}]" "\n\t"
+
381  "mov %B[outVal],r0" "\n\t"
+
382  // ignore overflow into r1 (should never overflow)
+
383  // low uint8_t * high uint8_t -> both uint8_ts
+
384  "mul %A[phaseStep],%B[pitchB}]" "\n\t"
+
385  "add %A[outVal],r0" "\n\t"
+
386  // carry into high uint8_t
+
387  "adc %B[outVal],r1" "\n\t"
+
388  // high uint8_t* low uint8_t -> both uint8_ts
+
389  "mul %B[phaseStep],%A[pitchB}]" "\n\t"
+
390  "add %A[outVal],r0" "\n\t"
+
391  // carry into high uint8_t
+
392  "adc %B[outVal],r1" "\n\t"
+
393  // low uint8_t * low uint8_t -> round
+
394  "mul %A[phaseStep],%A[pitchB}]" "\n\t"
+
395  // the adc below is to round up based on high bit of low*low:
+
396  "adc %A[outVal],r1" "\n\t"
+
397  "adc %B[outVal],%[ZERO]" "\n\t"
+
398  "clr r1" "\n\t"
+
399  :[outVal] "=&d" (multipliedCounter)
+
400  :[phaseStep] "d" (oscillators[c].phaseStep),[pitchB}] "d"( pitchB}Multiplier),[ZERO] "d" (zeroReg)
+
401  :"r1","r0"
+
402  );
+
403  oscillators[c].phaseStep=multipliedCounter;
+
404 
+
405  */
+
406 
+
407 
+
408 
+
409 int16_t ipow(int16_t base, int16_t exp); /**< dangerous overflow-prone int16_t power function */
+
410 
+
411 Q16n16 Q16n16_pow2(Q8n8 exponent);
+
412 
+ + +
415 uint8_t uint8_tRnd(uint8_t min, uint8_t max);
+
416 uint16_t isqrt16(uint16_t n);
+
417 uint32_t isqrt32(uint32_t n);
+
418 
+
419 #endif /* FIXEDMATH_H_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,20 +99,196 @@
mozzi_midi.h
-
1 #ifndef MOZZI_MIDI_H_
2 #define MOZZI_MIDI_H_
3 
4 #include "mozzi_fixmath.h"
5 
6 float mtof(float x);
7 int mtof(uint8_t midi_note);
8 int mtof(int midi_note);
9 Q16n16 Q16n16_mtof(Q16n16 midival);
10 
11 #endif /* MOZZI_MIDI_H_ */
Q16n16 Q16n16_mtof(Q16n16 midival)
Converts midi note number to frequency with speed and accuracy.
Definition: mozzi_midi.cpp:132
-
float mtof(float x)
Converts midi note number to frequency.
Definition: mozzi_midi.cpp:18
-
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46
-
int mtof(int midi_note)
A good choice if you&#39;re using whole note values, want speed and simplicity, and accuracy isn&#39;t import...
Definition: mozzi_midi.cpp:166
+
1 /*
+
2  * mozzi_midi.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 MOZZI_MIDI_H_
+
13 #define MOZZI_MIDI_H_
+
14 
+
15 #include "mozzi_fixmath.h"
+
16 #include "FixMath.h"
+
17 
+
18 #include "mozzi_pgmspace.h"
+
19 
+
20 /** @brief Internal. Do not use in your sketches.
+
21 
+
22 Internal helper class. Not intended for use in your sketches, and details may change without notic. */
+ +
24 private:
+
25  friend int mtof(uint8_t);
+
26  friend int mtof(int);
+
27  friend Q16n16 Q16n16_mtof(Q16n16);
+
28  template<int8_t NI, uint64_t RANGE>
+
29  friend UFix<16,16> mtof(UFix<NI,0,RANGE>);
+
30 
+
31  template<int8_t NI, uint64_t RANGE>
+
32  friend UFix<16,16> mtof(SFix<NI,0,RANGE>);
+
33 
+ +
35 };
+
36 
+
37 
+
38 CONSTTABLE_STORAGE(uint32_t) MidiToFreqPrivate::midiToFreq[128] =
+
39  {
+
40  0, 567670, 601425, 637188, 675077, 715219, 757748, 802806, 850544, 901120,
+
41  954703, 1011473, 1071618, 1135340, 1202851, 1274376, 1350154, 1430438, 1515497,
+
42  1605613, 1701088, 1802240, 1909406, 2022946, 2143236, 2270680, 2405702, 2548752,
+
43  2700309, 2860877, 3030994, 3211226, 3402176, 3604479, 3818813, 4045892, 4286472,
+
44  4541359, 4811404, 5097504, 5400618, 5721756, 6061988, 6422452, 6804352, 7208959,
+
45  7637627, 8091785, 8572945, 9082719, 9622808, 10195009, 10801235, 11443507,
+
46  12123974, 12844905, 13608704, 14417917, 15275252, 16183563, 17145888, 18165438,
+
47  19245616, 20390018, 21602470, 22887014, 24247948, 25689810, 27217408, 28835834,
+
48  30550514, 32367136, 34291776, 36330876, 38491212, 40780036, 43204940, 45774028,
+
49  48495912, 51379620, 54434816, 57671668, 61101028, 64734272, 68583552, 72661752,
+
50  76982424, 81560072, 86409880, 91548056, 96991792, 102759240, 108869632,
+
51  115343336, 122202056, 129468544, 137167104, 145323504, 153964848, 163120144,
+
52  172819760, 183096224, 193983648, 205518336, 217739200, 230686576, 244403840,
+
53  258937008, 274334112, 290647008, 307929696, 326240288, 345639520, 366192448,
+
54  387967040, 411036672, 435478400, 461373152, 488807680, 517874016, 548668224,
+
55  581294016, 615859392, 652480576, 691279040, 732384896, 775934592, 822073344
+
56  };
+
57 
+
58 
+
59 /** @defgroup midi Midi note number to frequency conversions
+
60 
+
61 Useful if you like playing notes in tune.
+
62 */
+
63 
+
64 /** @ingroup midi
+
65 Converts midi note number to frequency. Caution: this can take up to 400
+
66 microseconds to run. It can seriously mess up the audio output if you use it in
+
67 updateControl() or updateAudio(). This is a good choice in setup(), or where you
+
68 need precise midi-pitch conversion and aren't doing much other audio
+
69 calculation.
+
70 @note Beware this returns an invalid result for midi note 0.
+
71 @note Timing: ~350 us
+
72 @param midival a midi note number, 1.0 or greater. Like the mtof object in Pd, midi values can have fractions.
+
73 @return the frequency represented by the input midi note number..
+
74  */
+
75 inline float mtof(float midival)
+
76 {
+
77  // http://en.wikipedia.org/wiki/Note
+
78  // f = pow(2,(p-69/12) * 440Hz
+
79  // return pow(2.0,(midival-69.0/12.0) * 440.0;
+
80 
+
81  // code from AF_precision_synthesis sketch, copyright 2009, Adrian Freed.
+
82  float f = 0.0;
+
83  if(midival) f = 8.1757989156 * pow(2.0, midival/12.0);
+
84  return f;
+
85 };
+
86 
+
87 
+
88 /** @ingroup midi
+
89 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important.
+
90 @param midi_note a midi note number.
+
91 @return an integer approximation of the midi note's frequency.
+
92 */
+
93 inline int mtof(uint8_t midi_note){
+
94  return (FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + midi_note) >> 16);
+
95 };
+
96 
+
97 /** @ingroup midi
+
98 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important.
+
99 @param midi_note a midi note number.
+
100 @return an integer approximation of the midi note's frequency.
+
101 */
+
102 inline int mtof(int midi_note){
+
103  return (FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + midi_note) >> 16);
+
104 };
+
105 
+
106 
+
107 /** @ingroup midi
+
108 Converts midi note number to frequency with speed and accuracy. Q16n16_mtofLookup() is a fast
+
109 alternative to (float) mtof(), and more accurate than (uint8_t) mtof(),
+
110 using Q16n16 fixed-point format instead of floats or uint8_t values. Q16n16_mtof()
+
111 uses cheap linear interpolation between whole midi-note frequency equivalents
+
112 stored in a lookup table, so is less accurate than the float version, mtof(),
+
113 for non-whole midi values.
+
114 @note Timing: ~8 us.
+
115 @param midival_fractional a midi note number in Q16n16 format, for fractional values.
+
116 @return the frequency represented by the input midi note number, in Q16n16
+
117 fixed point fractional integer format, where the lower word is a fractional value.
+
118 */
+
119 inline Q16n16 Q16n16_mtof(Q16n16 midival_fractional)
+
120 {
+
121  Q16n16 diff_fraction;
+
122  uint8_t index = midival_fractional >> 16;
+
123  uint16_t fraction = (uint16_t) midival_fractional; // keeps low word
+
124  Q16n16 freq1 = (Q16n16) FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + index);
+
125  Q16n16 freq2 = (Q16n16) FLASH_OR_RAM_READ<const uint32_t>((MidiToFreqPrivate::midiToFreq + 1) + index);
+
126  Q16n16 difference = freq2 - freq1;
+
127  if (difference>=65536)
+
128  {
+
129  diff_fraction = ((difference>>8) * fraction) >> 8;
+
130  }
+
131  else
+
132  {
+
133  diff_fraction = (difference * fraction) >> 16;
+
134  }
+
135  return (Q16n16) (freq1+ diff_fraction);
+
136 };
+
137 
+
138 /** @ingroup midi
+
139 Converts midi note number with speed and accuracy from a UFix<16,16>.
+
140 Uses Q16n16_mtof internally.
+
141 */
+
142 template <uint64_t RANGE>
+
143 inline UFix<16,16> mtof(UFix<16,16,RANGE> midival)
+
144 {
+
145  return UFix<16,16>::fromRaw(Q16n16_mtof(midival.asRaw()));
+
146 };
+
147 
+
148 /** @ingroup midi
+
149 Converts midi note number with speed and accuracy from any UFix.
+
150 Uses Q16n16_mtof internally.
+
151 */
+
152 template<int8_t NI, int8_t NF, uint64_t RANGE>
+
153 inline UFix<16,16> mtof(UFix<NI,NF,RANGE> midival)
+
154 {
+
155  return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw()));
+
156 };
+
157 
+
158 /** @ingroup midi
+
159 Converts midi note number with speed and accuracy from any SFix.
+
160 Uses Q16n16_mtof internally.
+
161 */
+
162 template<int8_t NI, int8_t NF, uint64_t RANGE>
+
163 inline UFix<16,16> mtof(SFix<NI,NF,RANGE> midival)
+
164 {
+
165  return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw()));
+
166 };
+
167 
+
168 /** @ingroup midi
+
169 Converts *whole* midi note number with speed and accuracy (more accurate that mtof(uint8_t))
+
170 */
+
171 template<int8_t NI, uint64_t RANGE>
+
172 inline UFix<16,16> mtof(UFix<NI,0,RANGE> midival)
+
173 {
+
174  return UFix<16,16>::fromRaw((FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + midival.asRaw())));
+
175 };
+
176 
+
177 /** @ingroup midi
+
178 Converts *whole* midi note number with speed and accuracy (more accurate that mtof(uint8_t))
+
179 */
+
180 template<int8_t NI, uint64_t RANGE>
+
181 inline UFix<16,16> mtof(SFix<NI,0,RANGE> midival)
+
182 {
+
183  return UFix<16,16>::fromRaw((FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + midival.asUFix().asRaw())));
+
184 };
+
185 
+
186 #endif /* MOZZI_MIDI_H_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,19 +99,80 @@
mozzi_pgmspace.h
-
1 #ifndef MOZZI_PGMSPACE_H
2 #define MOZZI_PGMSPACE_H
3 
4 /* Cross-platform wrapper around avr/pgmspace.h, i.e. macros and functions to
5 * store data in and retrieve data from flash memory. */
6 
8 
9 #if IS_ESP8266() || IS_ESP32() || IS_RP2040()
10 template<typename T> inline T FLASH_OR_RAM_READ(T* address) {
11  return (T) (*address);
12 }
13 #define CONSTTABLE_STORAGE(X) const X
14 #else
15 #include <avr/pgmspace.h>
16 // work around missing std::is_const
17 template<typename T> inline bool mozzi_is_const_pointer(T* x) { return false; }
18 template<typename T> inline bool mozzi_is_const_pointer(const T* x) { return true; }
19 /** @ingroup core
20  * Helper function to FLASH_OR_RAM_READ(). You do not want to call this, directly. */
21 template<typename T> inline T mozzi_pgm_read_wrapper(const T* address) {
22  static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Data type not supported");
23  switch (sizeof(T)) {
24  case 1: return (T) pgm_read_byte_near(address);
25  case 2: return (T) pgm_read_word_near(address);
26  case 4: return (T) pgm_read_dword_near(address);
27  }
28  // case 8: AVR-libc does not provide a read function for this, so we combine two 32-bit reads. TODO: is this MSB/LSB safe?
29  return (T) (pgm_read_dword_near(address) | (uint64_t) pgm_read_dword_near(((byte*) address) + 4) << 32);
30 }
31 template<> inline float mozzi_pgm_read_wrapper(const float* address) {
32  return pgm_read_float_near(address);
33 }
34 template<> inline double mozzi_pgm_read_wrapper(const double* address) {
35  static_assert(sizeof(uint64_t) == sizeof(double) || sizeof(float) == sizeof(double), "Reading double from pgmspace memory not supported on this architecture");
36  if (sizeof(double) == sizeof(uint64_t)) {
37  union u { uint64_t i; double d; };
38  return u{mozzi_pgm_read_wrapper((uint64_t*) address)}.d;
39  }
40  return pgm_read_float_near(address);
41 }
42 /** @ingroup core
43  * Read a value from flash or RAM. The specified address is read from flash, if T is const, _and_ const
44  * tables are stored in flash on this platform (i.e. not on ESP8266). It is read from RAM, if T is not-const
45  * or tables are always stored in RAM on this platform. @see CONSTTABLE_STORAGE . */
46 template<typename T> inline T FLASH_OR_RAM_READ(T* address) {
47  if(mozzi_is_const_pointer(address)) {
48  return mozzi_pgm_read_wrapper(address);
49  }
50  return (T) *address;
51 }
52 /** @ingroup core
53  * Declare a variable such that it will be stored in flash memory, instead of RAM, on platforms where this
54  * is reasonably possible (i.e. not on ESP8266, where random location flash memory access is too slow).
55  * To read the variable in a cross-platform compatible way, use FLASH_OR_RAM_READ(). */
56 #define CONSTTABLE_STORAGE(X) const X __attribute__((section(".progmem.data")))
57 #endif
58 
59 #endif
#define IS_RP2040()
-
#define IS_ESP8266()
-
#define IS_ESP32()
+
1 /*
+
2  * mozzi_pgmspace.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2018-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 MOZZI_PGMSPACE_H
+
13 #define MOZZI_PGMSPACE_H
+
14 
+
15 /* Cross-platform wrapper around avr/pgmspace.h, i.e. macros and functions to
+
16 * store data in and retrieve data from flash memory. */
+
17 
+
18 #include "hardware_defines.h"
+
19 
+
20 #if IS_ESP8266() || IS_ESP32() || IS_RP2040() || IS_RENESAS()
+
21 template<typename T> inline T FLASH_OR_RAM_READ(T* address) {
+
22  return (T) (*address);
+
23 }
+
24 #define CONSTTABLE_STORAGE(X) const X
+
25 #else
+
26 #include <avr/pgmspace.h>
+
27 // work around missing std::is_const
+
28 template<typename T> inline bool mozzi_is_const_pointer(T*) { return false; }
+
29 template<typename T> inline bool mozzi_is_const_pointer(const T*) { return true; }
+
30 /** @ingroup core
+
31  * Helper function to FLASH_OR_RAM_READ(). You do not want to call this, directly. */
+
32 template<typename T> inline T mozzi_pgm_read_wrapper(const T* address) {
+
33  static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Data type not supported");
+
34  switch (sizeof(T)) {
+
35  case 1: return (T) pgm_read_byte_near(address);
+
36  case 2: return (T) pgm_read_word_near(address);
+
37  case 4: return (T) pgm_read_dword_near(address);
+
38  }
+
39  // case 8: AVR-libc does not provide a read function for this, so we combine two 32-bit reads. TODO: is this MSB/LSB safe?
+
40  return (T) (pgm_read_dword_near(address) | (uint64_t) pgm_read_dword_near(((byte*) address) + 4) << 32);
+
41 }
+
42 template<> inline float mozzi_pgm_read_wrapper(const float* address) {
+
43  return pgm_read_float_near(address);
+
44 }
+
45 template<> inline double mozzi_pgm_read_wrapper(const double* address) {
+
46  static_assert(sizeof(uint64_t) == sizeof(double) || sizeof(float) == sizeof(double), "Reading double from pgmspace memory not supported on this architecture");
+
47  if (sizeof(double) == sizeof(uint64_t)) {
+
48  union u { uint64_t i; double d; };
+
49  return u{mozzi_pgm_read_wrapper((uint64_t*) address)}.d;
+
50  }
+
51  return pgm_read_float_near(address);
+
52 }
+
53 /** @ingroup core
+
54  * Read a value from flash or RAM. The specified address is read from flash, if T is const, _and_ const
+
55  * tables are stored in flash on this platform (i.e. not on ESP8266). It is read from RAM, if T is not-const
+
56  * or tables are always stored in RAM on this platform. @see CONSTTABLE_STORAGE . */
+
57 template<typename T> inline T FLASH_OR_RAM_READ(T* address) {
+
58  if(mozzi_is_const_pointer(address)) {
+
59  return mozzi_pgm_read_wrapper(address);
+
60  }
+
61  return (T) *address;
+
62 }
+
63 /** @ingroup core
+
64  * Declare a variable such that it will be stored in flash memory, instead of RAM, on platforms where this
+
65  * is reasonably possible (i.e. not on ESP8266, where random location flash memory access is too slow).
+
66  * To read the variable in a cross-platform compatible way, use FLASH_OR_RAM_READ(). */
+
67 #define CONSTTABLE_STORAGE(X) const X __attribute__((section(".progmem.data")))
+
68 #endif
+
69 
+
70 #endif
- - - + @@ -80,7 +76,7 @@
@@ -103,23 +99,177 @@
mozzi_rand.h
-
1 #ifndef MOZZI_RAND_H_
2 #define MOZZI_RAND_H_
3 
4 #if ARDUINO >= 100
5  #include "Arduino.h"
6 #else
7  #include "WProgram.h"
8 #endif
9 
10 
11 unsigned long xorshift96();
12 
13 void xorshiftSeed(unsigned long seed);
14 void randSeed(unsigned long seed);
15 void randSeed();
16 
19 
22 
23 int rand(int minval, int maxval);
24 int rand(int maxval);
25 
26 unsigned int rand(unsigned int minval, unsigned int maxval);
27 unsigned int rand(unsigned int maxval);
28 
30 
31 #endif /* MOZZI_RAND_H_ */
void randSeed()
Initialises Mozzi&#39;s (pseudo)random number generator xorshift96(), which is used in Mozzi&#39;s rand() fun...
Definition: mozzi_rand.cpp:117
-
int rand(int maxval)
Ranged random number generator, faster than Arduino&#39;s built-in random function, which is too slow for...
Definition: mozzi_rand.cpp:240
-
unsigned int rand(unsigned int minval, unsigned int maxval)
Ranged random number generator, faster than Arduino&#39;s built-in random function, which is too slow for...
Definition: mozzi_rand.cpp:207
-
unsigned long xorshift96()
Random number generator.
Definition: mozzi_rand.cpp:26
-
uint8_t randMidiNote()
Generates a random number in the range for midi notes.
Definition: mozzi_rand.cpp:261
-
unsigned int rand(unsigned int maxval)
Ranged random number generator, faster than Arduino&#39;s built-in random function, which is too slow for...
Definition: mozzi_rand.cpp:251
-
int rand(int minval, int maxval)
Ranged random number generator, faster than Arduino&#39;s built-in random function, which is too slow for...
Definition: mozzi_rand.cpp:195
+
1 /*
+
2  * mozzi_rand.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 MOZZI_RAND_H_
+
13 #define MOZZI_RAND_H_
+
14 
+
15 #include <Arduino.h>
+
16 #include "internal/mozzi_rand_p.h"
+
17 
+
18 /** @defgroup random Fast random number generator functions
+
19 
+
20 These replace Arduino random() which is so slow it will stop your audio. They can even be used to generate audio noise.
+
21 */
+
22 
+
23 /** @ingroup random
+
24 Random number generator. A faster replacement for Arduino's random function,
+
25 which is too slow to use with Mozzi.
+
26 Based on Marsaglia, George. (2003). Xorshift RNGs. http://www.jstatsoft.org/v08/i14/xorshift.pdf
+
27 @return a random 32 bit integer.
+
28 @todo check timing of xorshift96(), rand() and other PRNG candidates.
+
29  */
+
30 inline uint32_t xorshift96() { return MozziPrivate::MozziRandPrivate::xorshift96(); };
+
31 
+
32 /** @ingroup random
+
33 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used
+
34 in Mozzi's rand() function. This can be useful if you want random sequences to
+
35 be different on each run of a sketch, by seeding with fairly random input, such
+
36 as analogRead() on an unconnected pin (as explained in the Arduino documentation
+
37 for randomSeed(). randSeed is the same as xorshift96Seed(), but easier to
+
38 remember.
+
39 @param seed a number to use as a seed.
+
40 */
+
41 inline void randSeed(uint32_t seed) { MozziPrivate::randSeed(seed); };
+
42 
+
43 /** @ingroup random
+
44 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used
+
45 in Mozzi's rand() function. This can be useful if you want random sequences to
+
46 be different on each run of a sketch, by seeding with a fairly random input.
+
47 randSeed() called without a parameter uses noise from reading the Arduino's
+
48 internal temperature as the seed, a technique discussed at
+
49 http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there
+
50 by Rob Tillaart.
+
51 
+
52 @note Intialization of the random seed is done differently on different MCUs,
+
53  but is nowhere near perfect for most (and for some it is not even implemented at all).
+
54  Many implementations (e.g. on AVR, STM32) simply rely on reading a (hopefully noisy)
+
55  internal temperature sensor.
+
56  You will often get better results by calling analogRead() - @em not mozziAnalogRead(0), in this case! -
+
57  on one or two floating (non-connected) analog pins.
+
58 */
+
59 inline void randSeed() { MozziPrivate::MozziRandPrivate::autoSeed(); };
+
60 
+
61 /** @ingroup random
+
62 Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number.
+
63 @param seed a number to use as a seed.
+
64 // TODO: duplicate deprecate / remove
+
65 */
+
66 inline void xorshiftSeed(uint32_t seed) { randSeed(seed); };
+
67 
+
68 /** @ingroup random
+
69 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
+
70 @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.
+
71 @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.
+
72 @return a random signed byte between minval and maxval-1 inclusive.
+
73 */
+ +
75 {
+
76  return (int8_t) ((((int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval;
+
77 }
+
78 
+
79 /** @ingroup random
+
80 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
+
81 @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.
+
82 @return a random signed byte between 0 and maxval-1 inclusive.
+
83 */
+
84 inline int8_t rand(int8_t maxval)
+
85 {
+
86  return (int8_t) ((((int) (lowByte(xorshift96()))) * maxval)>>8);
+
87 }
+
88 
+
89 /** @ingroup random
+
90 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
+
91 @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.
+
92 @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.
+
93 @return a random unsigned byte between minval and maxval-1 inclusive.
+
94 */
+ +
96 {
+
97  return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval;
+
98 }
+
99 
+
100 /** @ingroup random
+
101 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
+
102 @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.
+
103 @return a random unsigned byte between 0 and maxval-1 inclusive.
+
104 */
+
105 inline uint8_t rand(uint8_t maxval)
+
106 {
+
107  return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * maxval)>>8);
+
108 }
+
109 
+
110 /** @ingroup random
+
111 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
+
112 @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.
+
113 @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.
+
114 @return a random int between minval and maxval-1 inclusive.
+
115 
+
116 @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.
+
117 */
+
118 inline int rand(int minval, int maxval)
+
119 {
+
120  return (int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval);
+
121 }
+
122 
+
123 /** @ingroup random
+
124 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
+
125 @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.
+
126 @return a random int between 0 and maxval-1 inclusive.
+
127 
+
128 @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.
+
129 */
+
130 inline int rand(int maxval)
+
131 {
+
132  return (int) (((xorshift96() & 0xFFFF) * maxval)>>16);
+
133 }
+
134 
+
135 /** @ingroup random
+
136 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
+
137 @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.
+
138 @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.
+
139 @return a random unsigned int between minval and maxval-1 inclusive.
+
140 */
+
141 inline unsigned int rand(unsigned int minval, unsigned int maxval)
+
142 {
+
143  return (unsigned int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval);
+
144 }
+
145 
+
146 /** @ingroup random
+
147 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
+
148 @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.
+
149 @return a random unsigned int between 0 and maxval-1 inclusive.
+
150 
+
151 @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.
+
152 */
+
153 inline unsigned int rand(unsigned int maxval)
+
154 {
+
155  return (unsigned int) (((xorshift96() & 0xFFFF) * maxval)>>16);
+
156 }
+
157 
+
158 /** @ingroup random
+
159 Generates a random number in the range for midi notes.
+
160 @return a random value between 0 and 127 inclusive
+
161 */
+
162 inline uint8_t randMidiNote()
+
163 {
+
164  return lowByte(xorshift96())>>1;
+
165 }
+
166 
+
167 #endif /* MOZZI_RAND_H_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,20 +99,113 @@
mozzi_utils.h
-
1 
2 #ifndef UTILS_H_
3 #define UTILS_H_
4 
5 
6 #if ARDUINO >= 100
7  #include "Arduino.h"
8 #else
9  #include "WProgram.h"
10 #endif
11 
12 #include "hardware_defines.h"
13 
14 // macros for setting and clearing register bits
15 #ifndef cbi
16 #define cbi(sfr, bit) (_SFR_UINT8_T(sfr) &= ~_BV(bit))
17 #endif
18 #ifndef sbi
19 #define sbi(sfr, bit) (_SFR_UINT8_T(sfr) |= _BV(bit))
20 #endif
21 
22 
23 /** @ingroup util
24 Set digital pin 13 to output for testing timing with an oscilloscope.*/
25 inline
26 void setPin13Out()
27 {
28 #if IS_AVR()
29  DDRB |= B00100000;
30 #else
31  pinMode(13, OUTPUT);
32 #endif
33 }
34 
35 
36 /** @ingroup util
37 Set pin 13 high for testing timing with an oscilloscope.*/
38 inline
39 void setPin13High()
40 {
41 #if IS_AVR()
42  PORTB |= B00100000;
43 #else
44  digitalWrite(13, HIGH);
45 #endif
46 }
47 
48 
49 /** @ingroup util
50 Set pin 13 low for testing timing with an oscilloscope.*/
51 inline
52 void setPin13Low()
53 {
54 #if IS_AVR()
55  PORTB &= B11011111;
56 #else
57  digitalWrite(13, LOW);
58 #endif
59 }
60 
61 
62 constexpr uint8_t trailingZerosConst(unsigned long v) { return ((v % 2) ? 0 : 1+trailingZerosConst(v >> 1)); }
63 //uint8_t trailingZeros(uint16_t v);
64 unsigned int BPMtoMillis(float bpm);
65 
66 #endif /* UTILS_H_ */
void setPin13Out()
Set digital pin 13 to output for testing timing with an oscilloscope.
Definition: mozzi_utils.h:26
-
void setPin13High()
Set pin 13 high for testing timing with an oscilloscope.
Definition: mozzi_utils.h:39
-
#define IS_AVR()
-
void setPin13Low()
Set pin 13 low for testing timing with an oscilloscope.
Definition: mozzi_utils.h:52
+
1 /*
+
2  * mozzi_utils.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
+
7  *
+
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
+
9  *
+
10  */
+
11 
+
12 #ifndef UTILS_H_
+
13 #define UTILS_H_
+
14 
+
15 
+
16 #include <Arduino.h>
+
17 
+
18 #include "hardware_defines.h"
+
19 
+
20 // macros for setting and clearing register bits
+
21 #ifndef cbi
+
22 #define cbi(sfr, bit) (_SFR_UINT8_T(sfr) &= ~_BV(bit))
+
23 #endif
+
24 #ifndef sbi
+
25 #define sbi(sfr, bit) (_SFR_UINT8_T(sfr) |= _BV(bit))
+
26 #endif
+
27 
+
28 
+
29 /** @ingroup util
+
30 Set digital pin 13 to output for testing timing with an oscilloscope.*/
+
31 inline
+
32 void setPin13Out()
+
33 {
+
34 #if IS_AVR()
+
35  DDRB |= B00100000;
+
36 #else
+
37  pinMode(13, OUTPUT);
+
38 #endif
+
39 }
+
40 
+
41 
+
42 /** @ingroup util
+
43 Set pin 13 high for testing timing with an oscilloscope.*/
+
44 inline
+
45 void setPin13High()
+
46 {
+
47 #if IS_AVR()
+
48  PORTB |= B00100000;
+
49 #else
+
50  digitalWrite(13, HIGH);
+
51 #endif
+
52 }
+
53 
+
54 
+
55 /** @ingroup util
+
56 Set pin 13 low for testing timing with an oscilloscope.*/
+
57 inline
+
58 void setPin13Low()
+
59 {
+
60 #if IS_AVR()
+
61  PORTB &= B11011111;
+
62 #else
+
63  digitalWrite(13, LOW);
+
64 #endif
+
65 }
+
66 
+
67 
+
68 /** @ingroup util
+
69 Given a power of 2, work out the number to shift right by to do a divide by the number, or shift left to multiply.
+
70 @param a power of 2, or any other number for that matter
+
71 @return the number of trailing zeros on the right hand end
+
72 */
+
73 constexpr uint8_t trailingZerosConst(unsigned long v) { return ((v % 2) ? 0 : 1+trailingZerosConst(v >> 1)); }
+
74 /* NOTE: previous version of the above is super-nifty, but pulls in software float code on AVR (the platform where it makes a difference), leading to bloat and a compile time warning.
+
75  * Sine the only use-case I could find works on a compile-time constant (template-parameter), I added a constexpr function in mozzi_utils.h, instead. I renamed it, too,
+
76  * so, we'll learn about any use-case outside of this scope. If there are no reports of breakage, the following can probably be removed for good.
+
77 long trailingZeros(unsigned long v) {
+
78  // find the number of trailing zeros in v, from http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightFloatCast
+
79  // there are faster methods on the bit twiddling site, but this is short
+
80  float f = (float)(v & -v); // cast the least significant bit in v to a float
+
81  return (*(uint32_t *)&f >> 23) - 0x7f;
+
82 }
+
83 
+
84 Here's an alternate, trivial version:
+
85 uint8_t trailingZeros(uint16_t v) {
+
86  uint8_t ret = 0;
+
87  while ((v % 2) == 0) {
+
88  v = v >> 1;
+
89  ++ret;
+
90  }
+
91  return ret;
+
92 } */
+
93 
+
94 
+
95 /** Convert BPM to milliseconds, which can be used to set the delay between beats for Metronome.
+
96 @param bpm beats per minute
+
97 */
+
98 constexpr uint16_t BPMtoMillis(float bpm){
+
99  //float seconds_per_beat = 60.f/bpm;
+
100  return (uint16_t) (((float) 60.f/bpm)*1000);
+
101 }
+
102 
+
103 #endif /* UTILS_H_ */
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,253 @@
mult16x16.h
-
1 
2 /*
3 Norbert Pozar 2009
4 http://mekonik.wordpress.com/2009/03/18/arduino-avr-gcc-multiplication/
5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
7 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
8 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
9 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
10 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
11 
12 // longRes = intIn1 * intIn2
13 #define MultiU16X16to32(longRes, intIn1, intIn2) asm
14  volatile ( \
15 "clr r26 \n\t"\
16 "mul %A1, %A2 \n\t"\
17 "movw %A0, r0 \n\t"\
18 "mul %B1, %B2 \n\t"\
19 "movw %C0, r0 \n\t"\
20 "mul %B2, %A1 \n\t"\
21 "add %B0, r0 \n\t"\
22 "adc %C0, r1 \n\t"\
23 "adc %D0, r26 \n\t"\
24 "mul %B1, %A2 \n\t"\
25 "add %B0, r0 \n\t"\
26 "adc %C0, r1 \n\t"\
27 "adc %D0, r26 \n\t"\
28 "clr r1 \n\t"\
29 :\
30 "=&r"(longRes) \
31 :\
32 "a"(intIn1), \
33 "a"(intIn2) \
34 :\
35 "r26"\
36 )
37 
38 // intRes = intIn1 * intIn2 >> 16
39 // uses:
40 // r26 to store 0
41 // r27 to store the uint8_t 1 of the 32bit result
42 #define MultiU16X16toH16(intRes, intIn1, intIn2) asm
43  volatile ( \
44 "clr r26 \n\t"\
45 "mul %A1, %A2 \n\t"\
46 "mov r27, r1 \n\t"\
47 "mul %B1, %B2 \n\t"\
48 "movw %A0, r0 \n\t"\
49 "mul %B2, %A1 \n\t"\
50 "add r27, r0 \n\t"\
51 "adc %A0, r1 \n\t"\
52 "adc %B0, r26 \n\t"\
53 "mul %B1, %A2 \n\t"\
54 "add r27, r0 \n\t"\
55 "adc %A0, r1 \n\t"\
56 "adc %B0, r26 \n\t"\
57 "clr r1 \n\t"\
58 :\
59 "=&r"(intRes) \
60 :\
61 "a"(intIn1), \
62 "a"(intIn2) \
63 :\
64 "r26", "r27" \
65 )
66 
67 // intRes = intIn1 * intIn2 >> 16 + round
68 // uses:
69 // r26 to store 0
70 // r27 to store the uint8_t 1 of the 32bit result
71 // 21 cycles
72 #define MultiU16X16toH16Round(intRes, intIn1, intIn2) asm
73  volatile ( \
74 "clr r26 \n\t"\
75 "mul %A1, %A2 \n\t"\
76 "mov r27, r1 \n\t"\
77 "mul %B1, %B2 \n\t"\
78 "movw %A0, r0 \n\t"\
79 "mul %B2, %A1 \n\t"\
80 "add r27, r0 \n\t"\
81 "adc %A0, r1 \n\t"\
82 "adc %B0, r26 \n\t"\
83 "mul %B1, %A2 \n\t"\
84 "add r27, r0 \n\t"\
85 "adc %A0, r1 \n\t"\
86 "adc %B0, r26 \n\t"\
87 "lsl r27 \n\t"\
88 "adc %A0, r26 \n\t"\
89 "adc %B0, r26 \n\t"\
90 "clr r1 \n\t"\
91 :\
92 "=&r"(intRes) \
93 :\
94 "a"(intIn1), \
95 "a"(intIn2) \
96 :\
97 "r26", "r27" \
98 )
99 
100 
101 // signed16 * signed16
102 // 22 cycles
103 #define MultiS16X16to32(longRes, intIn1, intIn2) asm
104  volatile ( \
105 "clr r26 \n\t"\
106 "mul %A1, %A2 \n\t"\
107 "movw %A0, r0 \n\t"\
108 "muls %B1, %B2 \n\t"\
109 "movw %C0, r0 \n\t"\
110 "mulsu %B2, %A1 \n\t"\
111 "sbc %D0, r26 \n\t"\
112 "add %B0, r0 \n\t"\
113 "adc %C0, r1 \n\t"\
114 "adc %D0, r26 \n\t"\
115 "mulsu %B1, %A2 \n\t"\
116 "sbc %D0, r26 \n\t"\
117 "add %B0, r0 \n\t"\
118 "adc %C0, r1 \n\t"\
119 "adc %D0, r26 \n\t"\
120 "clr r1 \n\t"\
121 :\
122 "=&r"(longRes) \
123 :\
124 "a"(intIn1), \
125 "a"(intIn2) \
126 :\
127 "r26"\
128 )
129 
130 
131 // signed16 * signed 16 >> 16
132 #define MultiS16X16toH16(intRes, intIn1, intIn2) asm
133  volatile ( \
134 "clr r26 \n\t"\
135 "mul %A1, %A2 \n\t"\
136 "mov r27, r1 \n\t"\
137 "muls %B1, %B2 \n\t"\
138 "movw %A0, r0 \n\t"\
139 "mulsu %B2, %A1 \n\t"\
140 "sbc %B0, r26 \n\t"\
141 "add r27, r0 \n\t"\
142 "adc %A0, r1 \n\t"\
143 "adc %B0, r26 \n\t"\
144 "mulsu %B1, %A2 \n\t"\
145 "sbc %B0, r26 \n\t"\
146 "add r27, r0 \n\t"\
147 "adc %A0, r1 \n\t"\
148 "adc %B0, r26 \n\t"\
149 "clr r1 \n\t"\
150 :\
151 "=&r"(intRes) \
152 :\
153 "a"(intIn1), \
154 "a"(intIn2) \
155 :\
156 "r26","r27" \
157 )
158 
159 // multiplies a signed and unsigned 16 bit ints with a 32 bit result
160 #define MultiSU16X16to32(longRes, intIn1, intIn2) asm
161  volatile ( \
162 "clr r26 \n\t"\
163 "mul %A1, %A2 \n\t"\
164 "movw %A0, r0 \n\t"\
165 "mulsu %B1, %B2 \n\t"\
166 "movw %C0, r0 \n\t"\
167 "mul %B2, %A1 \n\t"\
168 "add %B0, r0 \n\t"\
169 "adc %C0, r1 \n\t"\
170 "adc %D0, r26 \n\t"\
171 "mulsu %B1, %A2 \n\t"\
172 "sbc %D0, r26 \n\t"\
173 "add %B0, r0 \n\t"\
174 "adc %C0, r1 \n\t"\
175 "adc %D0, r26 \n\t"\
176 "clr r1 \n\t"\
177 :\
178 "=&r"(longRes) \
179 :\
180 "a"(intIn1), \
181 "a"(intIn2) \
182 :\
183 "r26"\
184 )
185 
186 // multiplies signed x unsigned int and returns the highest 16 bits of the result
187 #define MultiSU16X16toH16(intRes, intIn1, intIn2) asm
188  volatile ( \
189 "clr r26 \n\t"\
190 "mul %A1, %A2 \n\t"\
191 "mov r27, r1 \n\t"\
192 "mulsu %B1, %B2 \n\t"\
193 "movw %A0, r0 \n\t"\
194 "mul %B2, %A1 \n\t"\
195 "add r27, r0 \n\t"\
196 "adc %A0, r1 \n\t"\
197 "adc %B0, r26 \n\t"\
198 "mulsu %B1, %A2 \n\t"\
199 "sbc %B0, r26 \n\t"\
200 "add r27, r0 \n\t"\
201 "adc %A0, r1 \n\t"\
202 "adc %B0, r26 \n\t"\
203 "clr r1 \n\t"\
204 :\
205 "=&r"(intRes) \
206 :\
207 "a"(intIn1), \
208 "a"(intIn2) \
209 :\
210 "r26","r27" \
211 )
212 
213 // multiplies signed x unsigned int and returns the highest 16 bits of the result
214 // rounds the result based on the MSB of the lower 16 bits
215 // 22 cycles
216 #define MultiSU16X16toH16Round(intRes, intIn1, intIn2) asm
217  volatile ( \
218 "clr r26 \n\t"\
219 "mul %A1, %A2 \n\t"\
220 "mov r27, r1 \n\t"\
221 "mulsu %B1, %B2 \n\t"\
222 "movw %A0, r0 \n\t"\
223 "mul %A1, %B2 \n\t"\
224 "add r27, r0 \n\t"\
225 "adc %A0, r1 \n\t"\
226 "adc %B0, r26 \n\t"\
227 "mulsu %B1, %A2 \n\t"\
228 "sbc %B0, r26 \n\t"\
229 "add r27, r0 \n\t"\
230 "adc %A0, r1 \n\t"\
231 "adc %B0, r26 \n\t"\
232 "lsl r27 \n\t"\
233 "adc %A0, r26 \n\t"\
234 "adc %B0, r26 \n\t"\
235 "clr r1 \n\t"\
236 :\
237 "=&r"(intRes) \
238 :\
239 "a"(intIn1), \
240 "a"(intIn2) \
241 :\
242 "r26","r27" \
243 )
+
1 
+
2 /*
+
3 Norbert Pozar 2009
+
4 http://mekonik.wordpress.com/2009/03/18/arduino-avr-gcc-multiplication/
+
5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
6 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
7 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
8 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
9 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
10 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
+
11 
+
12 // longRes = intIn1 * intIn2
+
13 #define MultiU16X16to32(longRes, intIn1, intIn2) asm
+
14  volatile ( \
+
15 "clr r26 \n\t"\
+
16 "mul %A1, %A2 \n\t"\
+
17 "movw %A0, r0 \n\t"\
+
18 "mul %B1, %B2 \n\t"\
+
19 "movw %C0, r0 \n\t"\
+
20 "mul %B2, %A1 \n\t"\
+
21 "add %B0, r0 \n\t"\
+
22 "adc %C0, r1 \n\t"\
+
23 "adc %D0, r26 \n\t"\
+
24 "mul %B1, %A2 \n\t"\
+
25 "add %B0, r0 \n\t"\
+
26 "adc %C0, r1 \n\t"\
+
27 "adc %D0, r26 \n\t"\
+
28 "clr r1 \n\t"\
+
29 :\
+
30 "=&r"(longRes) \
+
31 :\
+
32 "a"(intIn1), \
+
33 "a"(intIn2) \
+
34 :\
+
35 "r26"\
+
36 )
+
37 
+
38 // intRes = intIn1 * intIn2 >> 16
+
39 // uses:
+
40 // r26 to store 0
+
41 // r27 to store the uint8_t 1 of the 32bit result
+
42 #define MultiU16X16toH16(intRes, intIn1, intIn2) asm
+
43  volatile ( \
+
44 "clr r26 \n\t"\
+
45 "mul %A1, %A2 \n\t"\
+
46 "mov r27, r1 \n\t"\
+
47 "mul %B1, %B2 \n\t"\
+
48 "movw %A0, r0 \n\t"\
+
49 "mul %B2, %A1 \n\t"\
+
50 "add r27, r0 \n\t"\
+
51 "adc %A0, r1 \n\t"\
+
52 "adc %B0, r26 \n\t"\
+
53 "mul %B1, %A2 \n\t"\
+
54 "add r27, r0 \n\t"\
+
55 "adc %A0, r1 \n\t"\
+
56 "adc %B0, r26 \n\t"\
+
57 "clr r1 \n\t"\
+
58 :\
+
59 "=&r"(intRes) \
+
60 :\
+
61 "a"(intIn1), \
+
62 "a"(intIn2) \
+
63 :\
+
64 "r26", "r27" \
+
65 )
+
66 
+
67 // intRes = intIn1 * intIn2 >> 16 + round
+
68 // uses:
+
69 // r26 to store 0
+
70 // r27 to store the uint8_t 1 of the 32bit result
+
71 // 21 cycles
+
72 #define MultiU16X16toH16Round(intRes, intIn1, intIn2) asm
+
73  volatile ( \
+
74 "clr r26 \n\t"\
+
75 "mul %A1, %A2 \n\t"\
+
76 "mov r27, r1 \n\t"\
+
77 "mul %B1, %B2 \n\t"\
+
78 "movw %A0, r0 \n\t"\
+
79 "mul %B2, %A1 \n\t"\
+
80 "add r27, r0 \n\t"\
+
81 "adc %A0, r1 \n\t"\
+
82 "adc %B0, r26 \n\t"\
+
83 "mul %B1, %A2 \n\t"\
+
84 "add r27, r0 \n\t"\
+
85 "adc %A0, r1 \n\t"\
+
86 "adc %B0, r26 \n\t"\
+
87 "lsl r27 \n\t"\
+
88 "adc %A0, r26 \n\t"\
+
89 "adc %B0, r26 \n\t"\
+
90 "clr r1 \n\t"\
+
91 :\
+
92 "=&r"(intRes) \
+
93 :\
+
94 "a"(intIn1), \
+
95 "a"(intIn2) \
+
96 :\
+
97 "r26", "r27" \
+
98 )
+
99 
+
100 
+
101 // signed16 * signed16
+
102 // 22 cycles
+
103 #define MultiS16X16to32(longRes, intIn1, intIn2) asm
+
104  volatile ( \
+
105 "clr r26 \n\t"\
+
106 "mul %A1, %A2 \n\t"\
+
107 "movw %A0, r0 \n\t"\
+
108 "muls %B1, %B2 \n\t"\
+
109 "movw %C0, r0 \n\t"\
+
110 "mulsu %B2, %A1 \n\t"\
+
111 "sbc %D0, r26 \n\t"\
+
112 "add %B0, r0 \n\t"\
+
113 "adc %C0, r1 \n\t"\
+
114 "adc %D0, r26 \n\t"\
+
115 "mulsu %B1, %A2 \n\t"\
+
116 "sbc %D0, r26 \n\t"\
+
117 "add %B0, r0 \n\t"\
+
118 "adc %C0, r1 \n\t"\
+
119 "adc %D0, r26 \n\t"\
+
120 "clr r1 \n\t"\
+
121 :\
+
122 "=&r"(longRes) \
+
123 :\
+
124 "a"(intIn1), \
+
125 "a"(intIn2) \
+
126 :\
+
127 "r26"\
+
128 )
+
129 
+
130 
+
131 // signed16 * signed 16 >> 16
+
132 #define MultiS16X16toH16(intRes, intIn1, intIn2) asm
+
133  volatile ( \
+
134 "clr r26 \n\t"\
+
135 "mul %A1, %A2 \n\t"\
+
136 "mov r27, r1 \n\t"\
+
137 "muls %B1, %B2 \n\t"\
+
138 "movw %A0, r0 \n\t"\
+
139 "mulsu %B2, %A1 \n\t"\
+
140 "sbc %B0, r26 \n\t"\
+
141 "add r27, r0 \n\t"\
+
142 "adc %A0, r1 \n\t"\
+
143 "adc %B0, r26 \n\t"\
+
144 "mulsu %B1, %A2 \n\t"\
+
145 "sbc %B0, r26 \n\t"\
+
146 "add r27, r0 \n\t"\
+
147 "adc %A0, r1 \n\t"\
+
148 "adc %B0, r26 \n\t"\
+
149 "clr r1 \n\t"\
+
150 :\
+
151 "=&r"(intRes) \
+
152 :\
+
153 "a"(intIn1), \
+
154 "a"(intIn2) \
+
155 :\
+
156 "r26","r27" \
+
157 )
+
158 
+
159 // multiplies a signed and unsigned 16 bit ints with a 32 bit result
+
160 #define MultiSU16X16to32(longRes, intIn1, intIn2) asm
+
161  volatile ( \
+
162 "clr r26 \n\t"\
+
163 "mul %A1, %A2 \n\t"\
+
164 "movw %A0, r0 \n\t"\
+
165 "mulsu %B1, %B2 \n\t"\
+
166 "movw %C0, r0 \n\t"\
+
167 "mul %B2, %A1 \n\t"\
+
168 "add %B0, r0 \n\t"\
+
169 "adc %C0, r1 \n\t"\
+
170 "adc %D0, r26 \n\t"\
+
171 "mulsu %B1, %A2 \n\t"\
+
172 "sbc %D0, r26 \n\t"\
+
173 "add %B0, r0 \n\t"\
+
174 "adc %C0, r1 \n\t"\
+
175 "adc %D0, r26 \n\t"\
+
176 "clr r1 \n\t"\
+
177 :\
+
178 "=&r"(longRes) \
+
179 :\
+
180 "a"(intIn1), \
+
181 "a"(intIn2) \
+
182 :\
+
183 "r26"\
+
184 )
+
185 
+
186 // multiplies signed x unsigned int and returns the highest 16 bits of the result
+
187 #define MultiSU16X16toH16(intRes, intIn1, intIn2) asm
+
188  volatile ( \
+
189 "clr r26 \n\t"\
+
190 "mul %A1, %A2 \n\t"\
+
191 "mov r27, r1 \n\t"\
+
192 "mulsu %B1, %B2 \n\t"\
+
193 "movw %A0, r0 \n\t"\
+
194 "mul %B2, %A1 \n\t"\
+
195 "add r27, r0 \n\t"\
+
196 "adc %A0, r1 \n\t"\
+
197 "adc %B0, r26 \n\t"\
+
198 "mulsu %B1, %A2 \n\t"\
+
199 "sbc %B0, r26 \n\t"\
+
200 "add r27, r0 \n\t"\
+
201 "adc %A0, r1 \n\t"\
+
202 "adc %B0, r26 \n\t"\
+
203 "clr r1 \n\t"\
+
204 :\
+
205 "=&r"(intRes) \
+
206 :\
+
207 "a"(intIn1), \
+
208 "a"(intIn2) \
+
209 :\
+
210 "r26","r27" \
+
211 )
+
212 
+
213 // multiplies signed x unsigned int and returns the highest 16 bits of the result
+
214 // rounds the result based on the MSB of the lower 16 bits
+
215 // 22 cycles
+
216 #define MultiSU16X16toH16Round(intRes, intIn1, intIn2) asm
+
217  volatile ( \
+
218 "clr r26 \n\t"\
+
219 "mul %A1, %A2 \n\t"\
+
220 "mov r27, r1 \n\t"\
+
221 "mulsu %B1, %B2 \n\t"\
+
222 "movw %A0, r0 \n\t"\
+
223 "mul %A1, %B2 \n\t"\
+
224 "add r27, r0 \n\t"\
+
225 "adc %A0, r1 \n\t"\
+
226 "adc %B0, r26 \n\t"\
+
227 "mulsu %B1, %A2 \n\t"\
+
228 "sbc %B0, r26 \n\t"\
+
229 "add r27, r0 \n\t"\
+
230 "adc %A0, r1 \n\t"\
+
231 "adc %B0, r26 \n\t"\
+
232 "lsl r27 \n\t"\
+
233 "adc %A0, r26 \n\t"\
+
234 "adc %B0, r26 \n\t"\
+
235 "clr r1 \n\t"\
+
236 :\
+
237 "=&r"(intRes) \
+
238 :\
+
239 "a"(intIn1), \
+
240 "a"(intIn2) \
+
241 :\
+
242 "r26","r27" \
+
243 )
+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,98 @@
mult16x8.h
-
1 
2 /*
3 Norbert Pozar 2009
4 http://mekonik.wordpress.com/2009/03/18/arduino-avr-gcc-multiplication/
5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
7 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
8 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
9 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
10 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
11 
12 // multiplies 16 bit X 8 bit
13 // stores lower 16 bits
14 #define MultiSU16X8toL16(intRes, int16In, int8In) asm
15  volatile ( \
16 "mul %A1, %2 \n\t"\
17 "movw %A0, r0 \n\t"\
18 "mulsu %B1, %2 \n\t"\
19 "add %B0, r0 \n\t"\
20 "clr r1"\
21 :\
22 "=&r"(intRes) \
23 :\
24 "a"(int16In), \
25 "a"(int8In) \
26 )
27 
28 // multiplies 16 bit number X 8 bit constant
29 // saves lower 16 bit
30 // 8 cycles
31 #define MultiSU16XConst8toL16(intRes, int16In, int8In) asm
32  volatile ( \
33 "ldi r22, %2 \n\t"\
34 "mul %A1, r22 \n\t"\
35 "movw %A0, r0 \n\t"\
36 "mulsu %B1, r22 \n\t"\
37 "add %B0, r0 \n\t"\
38 "clr r1 \n\t"\
39 :\
40 "=&r"(intRes) \
41 :\
42 "a"(int16In), \
43 "M"(int8In) \
44 :\
45 "r22"\
46 )
47 
48 // multiplies 16 bit number X 8 bit and stores 2 high uint8_ts
49 #define MultiSU16X8toH16(intRes, int16In, int8In) asm
50  volatile ( \
51 "clr r26 \n\t"\
52 "mulsu %B1, %A2 \n\t"\
53 "movw %A0, r0 \n\t"\
54 "mul %A1, %A2 \n\t"\
55 "add %A0, r1 \n\t"\
56 "adc %B0, r26 \n\t"\
57 "clr r1 \n\t"\
58 :\
59 "=&r"(intRes) \
60 :\
61 "a"(int16In), \
62 "a"(int8In) \
63 :\
64 "r26"\
65 )
66 
67 // multiplies 16 bit signed number X 8 bit and stores 2 high uint8_ts
68 // rounds the number based on the MSB of the lowest uint8_t
69 #define MultiSU16X8toH16Round(intRes, int16In, int8In) asm
70  volatile ( \
71 "clr r26 \n\t"\
72 "mulsu %B1, %A2 \n\t"\
73 "movw %A0, r0 \n\t"\
74 "mul %A1, %A2 \n\t"\
75 "add %A0, r1 \n\t"\
76 "adc %B0, r26 \n\t"\
77 "lsl r0 \n\t"\
78 "adc %A0, r26 \n\t"\
79 "adc %B0, r26 \n\t"\
80 "clr r1 \n\t"\
81 :\
82 "=&r"(intRes) \
83 :\
84 "a"(int16In), \
85 "a"(int8In) \
86 :\
87 "r26"\
88 )
+
1 
+
2 /*
+
3 Norbert Pozar 2009
+
4 http://mekonik.wordpress.com/2009/03/18/arduino-avr-gcc-multiplication/
+
5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
6 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
7 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
8 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
9 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
10 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
+
11 
+
12 // multiplies 16 bit X 8 bit
+
13 // stores lower 16 bits
+
14 #define MultiSU16X8toL16(intRes, int16In, int8In) asm
+
15  volatile ( \
+
16 "mul %A1, %2 \n\t"\
+
17 "movw %A0, r0 \n\t"\
+
18 "mulsu %B1, %2 \n\t"\
+
19 "add %B0, r0 \n\t"\
+
20 "clr r1"\
+
21 :\
+
22 "=&r"(intRes) \
+
23 :\
+
24 "a"(int16In), \
+
25 "a"(int8In) \
+
26 )
+
27 
+
28 // multiplies 16 bit number X 8 bit constant
+
29 // saves lower 16 bit
+
30 // 8 cycles
+
31 #define MultiSU16XConst8toL16(intRes, int16In, int8In) asm
+
32  volatile ( \
+
33 "ldi r22, %2 \n\t"\
+
34 "mul %A1, r22 \n\t"\
+
35 "movw %A0, r0 \n\t"\
+
36 "mulsu %B1, r22 \n\t"\
+
37 "add %B0, r0 \n\t"\
+
38 "clr r1 \n\t"\
+
39 :\
+
40 "=&r"(intRes) \
+
41 :\
+
42 "a"(int16In), \
+
43 "M"(int8In) \
+
44 :\
+
45 "r22"\
+
46 )
+
47 
+
48 // multiplies 16 bit number X 8 bit and stores 2 high uint8_ts
+
49 #define MultiSU16X8toH16(intRes, int16In, int8In) asm
+
50  volatile ( \
+
51 "clr r26 \n\t"\
+
52 "mulsu %B1, %A2 \n\t"\
+
53 "movw %A0, r0 \n\t"\
+
54 "mul %A1, %A2 \n\t"\
+
55 "add %A0, r1 \n\t"\
+
56 "adc %B0, r26 \n\t"\
+
57 "clr r1 \n\t"\
+
58 :\
+
59 "=&r"(intRes) \
+
60 :\
+
61 "a"(int16In), \
+
62 "a"(int8In) \
+
63 :\
+
64 "r26"\
+
65 )
+
66 
+
67 // multiplies 16 bit signed number X 8 bit and stores 2 high uint8_ts
+
68 // rounds the number based on the MSB of the lowest uint8_t
+
69 #define MultiSU16X8toH16Round(intRes, int16In, int8In) asm
+
70  volatile ( \
+
71 "clr r26 \n\t"\
+
72 "mulsu %B1, %A2 \n\t"\
+
73 "movw %A0, r0 \n\t"\
+
74 "mul %A1, %A2 \n\t"\
+
75 "add %A0, r1 \n\t"\
+
76 "adc %B0, r26 \n\t"\
+
77 "lsl r0 \n\t"\
+
78 "adc %A0, r26 \n\t"\
+
79 "adc %B0, r26 \n\t"\
+
80 "clr r1 \n\t"\
+
81 :\
+
82 "=&r"(intRes) \
+
83 :\
+
84 "a"(int16In), \
+
85 "a"(int8In) \
+
86 :\
+
87 "r26"\
+
88 )
+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,89 @@
mult32x16.h
-
1 
2 /*
3 Norbert Pozar 2009
4 http://mekonik.wordpress.com/2009/03/18/arduino-avr-gcc-multiplication/
5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
7 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
8 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
9 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
10 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 // multiplies a signed long X unsigned int
14 // stores the high 4 uint8_ts of the result
15 // rounds the number up if the MSB of the 2 low uint8_ts is set
16 // 47 cycles
17 #define MultiSU32X16toH32Round(longRes, longIn1, intIn2) asm
18  volatile ( \
19 "clr r26 \n\t"\
20 \
21 \
22 "mul %A1, %A2 \n\t"\
23 "mov r27, r1 \n\t"\
24 \
25 "mul %B1, %B2 \n\t"\
26 "movw %A0, r0 \n\t"\
27 \
28 "mulsu %D1, %B2 \n\t"\
29 "movw %C0, r0 \n\t"\
30 \
31 "mulsu %D1, %A2 \n\t"\
32 "sbc %D0, r26 \n\t"\
33 "add %B0, r0 \n\t"\
34 "adc %C0, r1 \n\t"\
35 "adc %D0, r26 \n\t"\
36 \
37 \
38 "mul %B1, %A2 \n\t"\
39 "add r27, r0 \n\t"\
40 "adc %A0, r1 \n\t"\
41 "adc %B0, r26 \n\t"\
42 "adc %C0, r26 \n\t"\
43 "adc %D0, r26 \n\t"\
44 \
45 "mul %A1, %B2 \n\t"\
46 "add r27, r0 \n\t"\
47 "adc %A0, r1 \n\t"\
48 "adc %B0, r26 \n\t"\
49 "adc %C0, r26 \n\t"\
50 "adc %D0, r26 \n\t"\
51 \
52 "mul %C1, %A2 \n\t"\
53 "adc %A0, r0 \n\t"\
54 "adc %B0, r1 \n\t"\
55 "adc %C0, r26 \n\t"\
56 "adc %D0, r26 \n\t"\
57 \
58 "mul %C1, %B2 \n\t"\
59 "adc %B0, r0 \n\t"\
60 "adc %C0, r1 \n\t"\
61 "adc %D0, r26 \n\t"\
62 \
63 \
64 "lsl r27 \n\t"\
65 "adc %A0, r26 \n\t"\
66 "adc %B0, r26 \n\t"\
67 "adc %C0, r26 \n\t"\
68 "adc %D0, r26 \n\t"\
69 \
70 \
71 "clr r1 \n\t"\
72 :\
73 "=&r"(longRes) \
74 :\
75 "a"(longIn1), \
76 "a"(intIn2) \
77 :\
78 "r26","r27"\
79 )
+
1 
+
2 /*
+
3 Norbert Pozar 2009
+
4 http://mekonik.wordpress.com/2009/03/18/arduino-avr-gcc-multiplication/
+
5 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
6 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
7 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
8 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
9 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
10 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
11 */
+
12 
+
13 // multiplies a signed long X unsigned int
+
14 // stores the high 4 uint8_ts of the result
+
15 // rounds the number up if the MSB of the 2 low uint8_ts is set
+
16 // 47 cycles
+
17 #define MultiSU32X16toH32Round(longRes, longIn1, intIn2) asm
+
18  volatile ( \
+
19 "clr r26 \n\t"\
+
20 \
+
21 \
+
22 "mul %A1, %A2 \n\t"\
+
23 "mov r27, r1 \n\t"\
+
24 \
+
25 "mul %B1, %B2 \n\t"\
+
26 "movw %A0, r0 \n\t"\
+
27 \
+
28 "mulsu %D1, %B2 \n\t"\
+
29 "movw %C0, r0 \n\t"\
+
30 \
+
31 "mulsu %D1, %A2 \n\t"\
+
32 "sbc %D0, r26 \n\t"\
+
33 "add %B0, r0 \n\t"\
+
34 "adc %C0, r1 \n\t"\
+
35 "adc %D0, r26 \n\t"\
+
36 \
+
37 \
+
38 "mul %B1, %A2 \n\t"\
+
39 "add r27, r0 \n\t"\
+
40 "adc %A0, r1 \n\t"\
+
41 "adc %B0, r26 \n\t"\
+
42 "adc %C0, r26 \n\t"\
+
43 "adc %D0, r26 \n\t"\
+
44 \
+
45 "mul %A1, %B2 \n\t"\
+
46 "add r27, r0 \n\t"\
+
47 "adc %A0, r1 \n\t"\
+
48 "adc %B0, r26 \n\t"\
+
49 "adc %C0, r26 \n\t"\
+
50 "adc %D0, r26 \n\t"\
+
51 \
+
52 "mul %C1, %A2 \n\t"\
+
53 "adc %A0, r0 \n\t"\
+
54 "adc %B0, r1 \n\t"\
+
55 "adc %C0, r26 \n\t"\
+
56 "adc %D0, r26 \n\t"\
+
57 \
+
58 "mul %C1, %B2 \n\t"\
+
59 "adc %B0, r0 \n\t"\
+
60 "adc %C0, r1 \n\t"\
+
61 "adc %D0, r26 \n\t"\
+
62 \
+
63 \
+
64 "lsl r27 \n\t"\
+
65 "adc %A0, r26 \n\t"\
+
66 "adc %B0, r26 \n\t"\
+
67 "adc %C0, r26 \n\t"\
+
68 "adc %D0, r26 \n\t"\
+
69 \
+
70 \
+
71 "clr r1 \n\t"\
+
72 :\
+
73 "=&r"(longRes) \
+
74 :\
+
75 "a"(longIn1), \
+
76 "a"(intIn2) \
+
77 :\
+
78 "r26","r27"\
+
79 )
+
- - - + @@ -80,7 +76,7 @@
@@ -103,19 +99,82 @@
primes.h
-
1 /*
2  * Primes.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  /*
13 Inspired by PrimeSieve by Paul Badger 2009
14 http://playground.arduino.cc/Main/PrimeSieve
15 
16 Generates random primes up to 10000.
17 Takes up about 2.5k of progmem
18 */
19 
20 #ifndef PRIMES_H
21 #define PRIMES_H
22 
23 #include "mozzi_rand.h" // for rand()
24 #include "mozzi_pgmspace.h"
25 
26 static CONSTTABLE_STORAGE(unsigned int) primes[]={
27  2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523,
28  541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973,};
29 
30 static const unsigned int TOP_PRIME_INDEX = (sizeof(primes)/2);// - 1; //1228
31 
32 /*
33 unsigned int prime(){
34  return primes[rand(TOP_PRIME_INDEX)];
35 }
36 */
37 
38 /** @ingroup random
39 Generates a random prime number between 0 and the n-1th prime number.
40 This uses a stored array of primes, which takes about 2.5k of progmem.
41 @param n the maximum index in the series of primes up to which numbers will be returned.
42 The maximum is 1128.
43 @return random prime number between 0 and n-1th index in the series of primes.
44 @note This isn't included automatically with mozzi_rand.h,
45 because it takes up memory which might be needed for other things.
46 You need to "#include <primes.h>" separately to mozzi_rand.h.
47 */
48 inline
49 unsigned int randPrime(unsigned int n){
50  return FLASH_OR_RAM_READ<const unsigned int>(primes+rand(n));
51 }
52 
53 /** @ingroup random
54 Generates a random prime number between 0 and the given input number inclusive.
55 This uses a stored array of primes up to 10000, which takes about 2.5k of progmem.
56 @param n the upper limit of the random prime number to be generated.
57 The maximum is 10000.
58 @return random prime number between 0 and n.
59 @note This isn't included automatically with mozzi_utils.h,
60 because it takes up memory which might be needed for other things.
61 You need to "#include <primes.h>" separately to mozzi_utils.h.
62 */
63 inline
64 unsigned int randPrimeUpTo(unsigned int n){
65  unsigned int p;
66  do {
67  p = FLASH_OR_RAM_READ<const unsigned int>(primes+rand(TOP_PRIME_INDEX));
68  } while (p > n);
69  return p;
70 }
71 
72 #endif // #ifndef PRIMES_H
#define CONSTTABLE_STORAGE(X)
-
unsigned int randPrime(unsigned int n)
Generates a random prime number between 0 and the n-1th prime number.
Definition: primes.h:49
-
unsigned int randPrimeUpTo(unsigned int n)
Generates a random prime number between 0 and the given input number inclusive.
Definition: primes.h:64
+
1 /*
+
2  * primes.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 Inspired by PrimeSieve by Paul Badger 2009
+
14 http://playground.arduino.cc/Main/PrimeSieve
+
15 
+
16 Generates random primes up to 10000.
+
17 Takes up about 2.5k of progmem
+
18 */
+
19 
+
20 #ifndef PRIMES_H
+
21 #define PRIMES_H
+
22 
+
23 #include "mozzi_rand.h" // for rand()
+
24 #include "mozzi_pgmspace.h"
+
25 
+
26 static CONSTTABLE_STORAGE(unsigned int) primes[]={
+
27  2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523,
+
28  541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973,};
+
29 
+
30 static const unsigned int TOP_PRIME_INDEX = (sizeof(primes)/2);// - 1; //1228
+
31 
+
32 /*
+
33 unsigned int prime(){
+
34  return primes[rand(TOP_PRIME_INDEX)];
+
35 }
+
36 */
+
37 
+
38 /** @ingroup random
+
39 Generates a random prime number between 0 and the n-1th prime number.
+
40 This uses a stored array of primes, which takes about 2.5k of progmem.
+
41 @param n the maximum index in the series of primes up to which numbers will be returned.
+
42 The maximum is 1128.
+
43 @return random prime number between 0 and n-1th index in the series of primes.
+
44 @note This isn't included automatically with mozzi_rand.h,
+
45 because it takes up memory which might be needed for other things.
+
46 You need to "#include <primes.h>" separately to mozzi_rand.h.
+
47 */
+
48 inline
+
49 unsigned int randPrime(unsigned int n){
+
50  return FLASH_OR_RAM_READ<const unsigned int>(primes+rand(n));
+
51 }
+
52 
+
53 /** @ingroup random
+
54 Generates a random prime number between 0 and the given input number inclusive.
+
55 This uses a stored array of primes up to 10000, which takes about 2.5k of progmem.
+
56 @param n the upper limit of the random prime number to be generated.
+
57 The maximum is 10000.
+
58 @return random prime number between 0 and n.
+
59 @note This isn't included automatically with mozzi_utils.h,
+
60 because it takes up memory which might be needed for other things.
+
61 You need to "#include <primes.h>" separately to mozzi_utils.h.
+
62 */
+
63 inline
+
64 unsigned int randPrimeUpTo(unsigned int n){
+
65  unsigned int p;
+
66  do {
+
67  p = FLASH_OR_RAM_READ<const unsigned int>(primes+rand(TOP_PRIME_INDEX));
+
68  } while (p > n);
+
69  return p;
+
70 }
+
71 
+
72 #endif // #ifndef PRIMES_H
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,46 @@
sin1024_int8.py
-
1 
2 
3 
4 import array
5 import os
6 import textwrap
7 import math
8 
9 def generate(outfile, tablename, tablelength, samplerate):
10  fout = open(os.path.expanduser(outfile), "w")
11  fout.write('#ifndef ' + tablename + '_H_' + '\n')
12  fout.write('#define ' + tablename + '_H_' + '\n \n')
13  fout.write('#if ARDUINO >= 100'+'\n')
14  fout.write('#include "Arduino.h"'+'\n')
15  fout.write('#else'+'\n')
16  fout.write('#include "WProgram.h"'+'\n')
17  fout.write('#endif'+'\n')
18  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
19  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n')
20  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
21  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
22 
23  try:
24  for num in range(tablelength):
25 
26  x = float(num)/tablelength
27 
28  t_x = (math.cos(2*math.pi*x-math.pi)+1)/2
29 
30  scaled = int(math.floor(t_x*255.999))-128
31 
32  outstring += str(scaled) + ', '
33  finally:
34  outstring = textwrap.fill(outstring, 80)
35  outstring += '\n }; \n \n #endif /* ' + tablename + '_H_ */\n'
36  fout.write(outstring)
37  fout.close()
38  print "wrote " + outfile
39 
40 generate("~/Desktop/sin1024_int8.h", "SIN1024", 1024, "1024")
+
1 
+
2 
+
3 
+
4 import array
+
5 import os
+
6 import textwrap
+
7 import math
+
8 
+
9 def generate(outfile, tablename, tablelength, samplerate):
+
10  fout = open(os.path.expanduser(outfile), "w")
+
11  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
12  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
13  fout.write('#include <Arduino.h>'+'\n')
+
14  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
15  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n')
+
16  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
+
17  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
+
18 
+
19  try:
+
20  for num in range(tablelength):
+
21 
+
22  x = float(num)/tablelength
+
23 
+
24  t_x = (math.cos(2*math.pi*x-math.pi)+1)/2
+
25 
+
26  scaled = int(math.floor(t_x*255.999))-128
+
27 
+
28  outstring += str(scaled) + ', '
+
29  finally:
+
30  outstring = textwrap.fill(outstring, 80)
+
31  outstring += '\n }; \n \n #endif /* ' + tablename + '_H_ */\n'
+
32  fout.write(outstring)
+
33  fout.close()
+
34  print "wrote " + outfile
+
35 
+
36 generate("~/Desktop/sin1024_int8.h", "SIN1024", 1024, "1024")
+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,48 @@
sin8192_uint8.py
-
1 
2 
3 
4 import array
5 import os
6 import textwrap
7 import math
8 
9 def generate(outfile, tablename, tablelength, samplerate):
10  fout = open(os.path.expanduser(outfile), "w")
11  fout.write('#ifndef ' + tablename + '_H_' + '\n')
12  fout.write('#define ' + tablename + '_H_' + '\n \n')
13  fout.write('#if ARDUINO >= 100'+'\n')
14  fout.write('#include "Arduino.h"'+'\n')
15  fout.write('#else'+'\n')
16  fout.write('#include "WProgram.h"'+'\n')
17  fout.write('#endif'+'\n')
18  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
19  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n')
20  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
21  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
22  halftable = tablelength/2
23  try:
24  for num in range(tablelength):
25 
27  x = float(num)/tablelength
28 
29  t_x = (math.cos(2*math.pi*x-math.pi)+1)/2
30 
31  scaled = int(math.floor(t_x*255.999))
32 
33  outstring += str(scaled) + ', '
34 
36  finally:
37  outstring = textwrap.fill(outstring, 80)
38  outstring += '\n }; \n \n #endif /* ' + tablename + '_H_ */\n'
39  fout.write(outstring)
40  fout.close()
41  print "wrote " + outfile
42 
43 
44 generate("~/Desktop/sin8192_uint8.h", "sin8192_uint", 8192, "8192")
+
1 
+
2 
+
3 
+
4 import array
+
5 import os
+
6 import textwrap
+
7 import math
+
8 
+
9 def generate(outfile, tablename, tablelength, samplerate):
+
10  fout = open(os.path.expanduser(outfile), "w")
+
11  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
12  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
13  fout.write('#include <Arduino.h>'+'\n')
+
14  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
15  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n')
+
16  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
+
17  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
+
18  halftable = tablelength/2
+
19  try:
+
20  for num in range(tablelength):
+
21 
+
23  x = float(num)/tablelength
+
24 
+
25  t_x = (math.cos(2*math.pi*x-math.pi)+1)/2
+
26 
+
27  scaled = int(math.floor(t_x*255.999))
+
28 
+
29  outstring += str(scaled) + ', '
+
30 
+
32  finally:
+
33  outstring = textwrap.fill(outstring, 80)
+
34  outstring += '\n }; \n \n #endif /* ' + tablename + '_H_ */\n'
+
35  fout.write(outstring)
+
36  fout.close()
+
37  print "wrote " + outfile
+
38 
+
39 
+
40 generate("~/Desktop/sin8192_uint8.h", "sin8192_uint", 8192, "8192")
+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,53 @@
sin_multi_levels_int8.py
-
1 
3 
4 import array,os,textwrap,math
5 
6 
7 
8 def generate(outfile, tablename, tablelength, numtables):
9  fout = open(os.path.expanduser(outfile), "w")
10 
11 
12 
13  fout.write('#ifndef ' + tablename + '_H_' + '\n')
14  fout.write('#define ' + tablename + '_H_' + '\n \n')
15  fout.write('#if ARDUINO >= 100'+'\n')
16  fout.write('#include "Arduino.h"'+'\n')
17  fout.write('#else'+'\n')
18  fout.write('#include "WProgram.h"'+'\n')
19  fout.write('#endif'+'\n')
20  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
21  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength) +'\n')
22  fout.write('CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = { \n')
23 
24  try:
25  for tablenum in range(numtables):
26  try:
27  outstring = '\n'
28  for num in range(tablelength):
29 
30  x = float(num)/tablelength
31 
32  t_x = math.sin(2*math.pi*x)*(float(tablenum+1)/numtables)
33 
34  scaled = int16_t(math.floor(t_x*127.999))
35 
36  outstring += str(scaled) + ', '
37  finally:
38  outstring = textwrap.fill(outstring, 80)
39  outstring += '\n'
40  fout.write(outstring)
41  finally:
42 
43  fout.write('}; \n \n #endif /* ' + tablename + '_H_ */\n')
44  fout.close()
45  print "wrote " + outfile
46 
47 
48 generate("~/Desktop/sin_64level_int8.h", "SIN_64LEVEL", 256, 64)
+
1 
+
3 
+
4 import array,os,textwrap,math
+
5 
+
6 
+
7 
+
8 def generate(outfile, tablename, tablelength, numtables):
+
9  fout = open(os.path.expanduser(outfile), "w")
+
10 
+
11 
+
12 
+
13  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
14  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
15  fout.write('#include <Arduino.h>'+'\n')
+
16  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
17  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength) +'\n')
+
18  fout.write('CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = { \n')
+
19 
+
20  try:
+
21  for tablenum in range(numtables):
+
22  try:
+
23  outstring = '\n'
+
24  for num in range(tablelength):
+
25 
+
26  x = float(num)/tablelength
+
27 
+
28  t_x = math.sin(2*math.pi*x)*(float(tablenum+1)/numtables)
+
29 
+
30  scaled = int16_t(math.floor(t_x*127.999))
+
31 
+
32  outstring += str(scaled) + ', '
+
33  finally:
+
34  outstring = textwrap.fill(outstring, 80)
+
35  outstring += '\n'
+
36  fout.write(outstring)
+
37  finally:
+
38 
+
39  fout.write('}; \n \n #endif /* ' + tablename + '_H_ */\n')
+
40  fout.close()
+
41  print "wrote " + outfile
+
42 
+
43 
+
44 generate("~/Desktop/sin_64level_int8.h", "SIN_64LEVEL", 256, 64)
+
- - - + @@ -80,7 +76,7 @@
@@ -110,13 +106,8 @@ unsigned_type typedef (defined in IntegerType< 1 >)IntegerType< 1 >
- - - + @@ -80,7 +76,7 @@
@@ -103,10 +99,13 @@ Public Types | List of all members
-
IntegerType< 1 > Struct Template Reference
+
IntegerType< 1 > Struct Reference
- +

Detailed Description

+
+

Definition at line 27 of file IntegerType.h.

+

Public Types

@@ -116,22 +115,10 @@ typedef int8_t signed_type
 
-

Detailed Description

-

template<>
-struct IntegerType< 1 >

- - -

Definition at line 9 of file IntegerType.h.

-
+ - - - + @@ -80,7 +76,7 @@
@@ -110,13 +106,8 @@ unsigned_type typedef (defined in IntegerType< 2 >)IntegerType< 2 >
- - - + @@ -80,7 +76,7 @@
@@ -103,10 +99,13 @@ Public Types | List of all members
-
IntegerType< 2 > Struct Template Reference
+
IntegerType< 2 > Struct Reference
- +

Detailed Description

+
+

Definition at line 32 of file IntegerType.h.

+

Public Types

@@ -116,22 +115,10 @@ typedef int16_t signed_type
 
-

Detailed Description

-

template<>
-struct IntegerType< 2 >

- - -

Definition at line 14 of file IntegerType.h.

-
+ - - - + @@ -80,7 +76,7 @@
@@ -110,13 +106,8 @@ unsigned_type typedef (defined in IntegerType< 4 >)IntegerType< 4 >
- - - + @@ -80,7 +76,7 @@
@@ -103,10 +99,13 @@ Public Types | List of all members
-
IntegerType< 4 > Struct Template Reference
+
IntegerType< 4 > Struct Reference
- +

Detailed Description

+
+

Definition at line 37 of file IntegerType.h.

+

Public Types

@@ -116,22 +115,10 @@ typedef int32_t signed_type
 
-

Detailed Description

-

template<>
-struct IntegerType< 4 >

- - -

Definition at line 19 of file IntegerType.h.

-
+ - - - + @@ -80,7 +76,7 @@
@@ -110,13 +106,8 @@ unsigned_type typedef (defined in IntegerType< 8 >)IntegerType< 8 >
- - - + @@ -80,7 +76,7 @@
@@ -103,10 +99,13 @@ Public Types | List of all members
-
IntegerType< 8 > Struct Template Reference
+
IntegerType< 8 > Struct Reference
- +

Detailed Description

+
+

Definition at line 42 of file IntegerType.h.

+

Public Types

@@ -116,22 +115,10 @@ typedef int64_t signed_type
 
-

Detailed Description

-

template<>
-struct IntegerType< 8 >

- - -

Definition at line 24 of file IntegerType.h.

-
+ - - - + @@ -80,7 +76,7 @@
@@ -109,21 +105,18 @@ clip()MonoOutputinline from16Bit(int16_t l)MonoOutputinlinestatic from8Bit(int16_t l)MonoOutputinlinestatic - fromAlmostNBit(A bits, B l) (defined in MonoOutput)MonoOutputinlinestatic + fromAlmostNBit(A bits, B l)MonoOutputinlinestatic fromNBit(uint8_t bits, T l)MonoOutputinlinestatic - l() const (defined in MonoOutput)MonoOutputinline - MonoOutput(AudioOutputStorage_t l=0)MonoOutputinline - operator AudioOutput_t() constMonoOutputinline + fromSFix(SFix< NI, NF, RANGE > l)MonoOutputinlinestatic + l() const (defined in MonoOutput)MonoOutputinline + MonoOutput()MonoOutputinline + MonoOutput(AudioOutputStorage_t l)MonoOutputinline + operator AudioOutputStorage_t() constMonoOutputinline r() const (defined in MonoOutput)MonoOutputinline
- - - + @@ -80,7 +76,7 @@
@@ -112,16 +108,26 @@ More...

#include <AudioOutput.h>

- +

Detailed Description

+

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:

+

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), 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 different output methods, including external DACs. 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) found in some old sketches. 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 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.

+ +

Definition at line 111 of file AudioOutput.h.

+
- - - - - - + + + + + + + + + @@ -129,33 +135,62 @@ AudioOutputStorage_t  - +

Public Member Functions

MonoOutput (AudioOutputStorage_t l=0)
 Construct an audio frame from raw values (zero-centered)
 
 operator AudioOutput_t () const
 Conversion to int operator. More...
 
 MonoOutput ()
 Default constructor. More...
 
MonoOutput (AudioOutputStorage_t l)
 Construct an audio frame from raw values (zero-centered)
 
operator AudioOutputStorage_t () const
 Conversion to int operator.
 
AudioOutputStorage_t l () const
 
r () const
 
MonoOutputclip ()
 Clip frame to supported range. More...
 Clip frame to supported range. More...
 
- + - + - + - - + + + + + + +

Static Public Member Functions

template<typename T >
static MonoOutput fromNBit (uint8_t bits, T l)
 Construct an audio frame a zero-centered value known to be in the N bit range. More...
 Construct an audio frame a zero-centered value known to be in the N bit range. More...
 
static MonoOutput from8Bit (int16_t l)
 Construct an audio frame from a zero-centered value known to be in the 8 bit range. More...
 Construct an audio frame from a zero-centered value known to be in the 8 bit range. More...
 
static MonoOutput from16Bit (int16_t l)
 Construct an audio frame a zero-centered value known to be in the 16 bit range. More...
 Construct an audio frame from a zero-centered value known to be in the 16 bit range. More...
 
-template<typename A , typename B >
static MonoOutput fromAlmostNBit (A bits, B l)
template<int8_t NI, int8_t NF, uint64_t RANGE>
static MonoOutput fromSFix (SFix< NI, NF, RANGE > l)
 Construct an audio frame from a SFix type from FixMath. More...
 
template<typename A , typename B >
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 range, e.g. More...
 
-

Detailed Description

-

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:

-

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), 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 different output methods, including external DACs. 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) found in some old sketches. 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 different configurations.

+

Constructor & Destructor Documentation

+ +

◆ MonoOutput()

-

Definition at line 132 of file AudioOutput.h.

-

Member Function Documentation

+
+
+ + + + + +
+ + + + + + + +
MonoOutput::MonoOutput ()
+
+inline
+
+ +

Default constructor.

+

Does not initialize the sample!

+ +

Definition at line 113 of file AudioOutput.h.

+ +
+
+

Member Function Documentation

◆ clip()

@@ -182,7 +217,7 @@

Definition at line 148 of file AudioOutput.h.

+

Definition at line 129 of file AudioOutput.h.

@@ -210,10 +245,10 @@

-

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

+

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.

-

Definition at line 158 of file AudioOutput.h.

+

Definition at line 139 of file AudioOutput.h.

@@ -242,9 +277,56 @@

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 156 of file AudioOutput.h.

+

Definition at line 137 of file AudioOutput.h.

+ + + + +

◆ fromAlmostNBit()

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

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();
+
MonoOutput & clip()
Clip frame to supported range.
Definition: AudioOutput.h:129
+
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:153
+
+

Definition at line 153 of file AudioOutput.h.

@@ -287,34 +369,38 @@

Definition at line 153 of file AudioOutput.h.

+

Definition at line 134 of file AudioOutput.h.

- -

◆ operator AudioOutput_t()

+ +

◆ fromSFix()

+
+template<int8_t NI, int8_t NF, uint64_t RANGE>
+inlinestatic
- + - - + + +
MonoOutput::operator AudioOutput_t static MonoOutput MonoOutput::fromSFix () constSFix< NI, NF, RANGE > l)
-inline
-

Conversion to int operator.

+

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.

Definition at line 142 of file AudioOutput.h.

@@ -322,14 +408,8 @@

-
    - - -
+ diff --git a/extras/doc/html/struct_mono_output.js b/extras/doc/html/struct_mono_output.js index 1be65c92b..7eea7efb6 100644 --- a/extras/doc/html/struct_mono_output.js +++ b/extras/doc/html/struct_mono_output.js @@ -1,8 +1,9 @@ var struct_mono_output = [ - [ "MonoOutput", "struct_mono_output.html#a89428135a43dd00ea52a1bd49bbfece9", null ], + [ "MonoOutput", "struct_mono_output.html#a8a0bf7d9c4446b83f17ccd75433a828f", null ], + [ "MonoOutput", "struct_mono_output.html#a059352b524ac1356adececc104df6c74", null ], [ "clip", "struct_mono_output.html#a0e641cbab9732214c696cd1071e45de5", null ], [ "l", "struct_mono_output.html#aac4ac57932e39b02959cd55bdb5d394d", null ], - [ "operator AudioOutput_t", "struct_mono_output.html#a51fe3c13043c666f36d7fb7029c17a30", null ], + [ "operator AudioOutputStorage_t", "struct_mono_output.html#a1fa86997aa020097d6011b23ee35342a", null ], [ "r", "struct_mono_output.html#a3fe87c5d547ee10e8aeb2d6af95905e3", null ] ]; \ No newline at end of file diff --git a/extras/doc/html/struct_stereo_output-members.html b/extras/doc/html/struct_stereo_output-members.html index 01c8d5d8d..f7b14c1c9 100644 --- a/extras/doc/html/struct_stereo_output-members.html +++ b/extras/doc/html/struct_stereo_output-members.html @@ -1,9 +1,9 @@ - + - + Mozzi: Member 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 @@
@@ -111,21 +107,17 @@ 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 + fromSFix(SFix< NI, NF, RANGE > l, SFix< _NI, _NF, _RANGE > r)StereoOutputinlinestatic l() const (defined in StereoOutput)StereoOutputinline - portable() const __attribute__((deprecated("Sketch generates stereo outputStereoOutputinline + portable() const __attribute__((deprecated("Sketch generates stereo outputStereoOutputinline r() const (defined in StereoOutput)StereoOutputinline - StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r)StereoOutputinline - StereoOutput()StereoOutputinline + setting (defined in StereoOutput)StereoOutput + StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r)StereoOutputinline + StereoOutput()StereoOutputinline
- - - + @@ -80,7 +76,7 @@
@@ -113,20 +109,24 @@ More...

#include <AudioOutput.h>

- +

Detailed Description

+

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 .

+ +

Definition at line 161 of file AudioOutput.h.

+
- - + + - - - + + + @@ -134,35 +134,43 @@ AudioOutputStorage_t  +

Public Member Functions

 StereoOutput (AudioOutputStorage_t l, AudioOutputStorage_t r)
 Construct an audio frame from raw values (zero-centered)
 
StereoOutput ()
 Default contstructor.
 StereoOutput ()
 Default constructor. More...
 
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 compile time warning). More...
 
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 compile time warning). More...
 
AudioOutputStorage_t l () const
 
r () const
 
StereoOutputclip ()
 See MonoOutput::clip(). More...
 
- + + - + + - + + - + + + + + +

Static Public Member Functions

template<typename T >
+template<typename T >
static StereoOutput fromNBit (uint8_t bits, T l, T r)
 See MonoOutput::fromNBit(), stereo variant.
 
static StereoOutput from8Bit (int16_t l, int16_t r)
+static StereoOutput from8Bit (int16_t l, int16_t r)
 See MonoOutput::from8Bit(), stereo variant.
 
static StereoOutput from16Bit (int16_t l, int16_t r)
+static StereoOutput from16Bit (int16_t l, int16_t r)
 See MonoOutput::from16Bit(), stereo variant.
 
template<typename A , typename B >
template<int8_t NI, int8_t NF, uint64_t RANGE, int8_t _NI, int8_t _NF, uint64_t _RANGE>
static StereoOutput fromSFix (SFix< NI, NF, RANGE > l, SFix< _NI, _NF, _RANGE > r)
 See MonoOutput::fromSFix(), stereo variant. More...
 
+template<typename A , typename B >
static StereoOutput fromAlmostNBit (A bits, B l, B r)
 See MonoOutput::fromAlmostNBit(), stereo variant.
 
- - + +

Public Attributes

-AudioOutput_t but Mozzi is configured for mono Check mozzi_config h { return _l
 
+AudioOutput but Mozzi is configured for mono Check MOZZI_AUDIO_CHANNELS setting
 
-

Detailed Description

-

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 also
MonoOutput .
- -

Definition at line 89 of file AudioOutput.h.

-

Member Function Documentation

- -

◆ clip()

+

Constructor & Destructor Documentation

+ +

◆ StereoOutput()

- -

◆ from8Bit()

+

Member Function Documentation

+ +

◆ clip()

- -

◆ fromAlmostNBit()

- -
-
-
-template<typename A , typename B >
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
static StereoOutput StereoOutput::fromAlmostNBit (bits,
l,
r 
)
-
-inlinestatic
-
-
See also
MonoOutput::fromAlmostNBit(), stereo variant
- -

Definition at line 112 of file AudioOutput.h.

+

Definition at line 178 of file AudioOutput.h.

- -

◆ fromNBit()

+ +

◆ fromSFix()

-template<typename T >
+template<int8_t NI, int8_t NF, uint64_t RANGE, int8_t _NI, int8_t _NF, uint64_t _RANGE>
@@ -61,10 +57,10 @@
- + - - - - - - - + - + @@ -355,14 +265,16 @@

-
See also
MonoOutput::fromNBit(), stereo variant
-

Definition at line 106 of file AudioOutput.h.

+

See MonoOutput::fromSFix(), stereo variant.

+

Note that the two channels do not need to have the same number of bits.

+ +

Definition at line 188 of file AudioOutput.h.

- -

◆ portable()

+ +

◆ portable()

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

static StereoOutput StereoOutput::fromNBit static StereoOutput StereoOutput::fromSFix (uint8_t bits,
SFix< NI, NF, RANGE >  l,
SFix< _NI, _NF, _RANGE >  r 
- + @@ -385,20 +297,14 @@

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.

+

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.

- -

@@ -61,10 +57,10 @@
AudioOutput_t StereoOutput::portable AudioOutput StereoOutput::portable ( ) const
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)"/> - +
- + @@ -80,7 +76,7 @@
@@ -103,16 +99,36 @@
table_generator_template.py
-
1 import array
2 import os
3 import textwrap
4 
5 def generate(outfile, tablename, tablelength, samplerate):
6  fout = open(os.path.expanduser(outfile), "w")
7  fout.write('#ifndef ' + tablename + '_H_' + '\n')
8  fout.write('#define ' + tablename + '_H_' + '\n \n')
9  fout.write('#if ARDUINO >= 100'+'\n')
10  fout.write('#include "Arduino.h"'+'\n')
11  fout.write('#else'+'\n')
12  fout.write('#include "WProgram.h"'+'\n')
13  fout.write('#endif'+'\n')
14  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
15  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(len(values))+'\n')
16  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
17  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
18  try:
19  for num in range(tablelength):
20  outstring += str(num/32) + ", "
21  finally:
22  outstring += "};"
23  outstring = textwrap.fill(outstring, 80)
24  fout.write(outstring)
25  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
26  fout.close()
27  print "wrote " + outfile
28 
29 generate("~/Desktop/phasor8192_uint8.h", "phasor8192", 8192, "8192")
+
1 import array
+
2 import os
+
3 import textwrap
+
4 import random
+
5 
+
6 def generate(outfile, tablename, tablelength, samplerate):
+
7  fout = open(os.path.expanduser(outfile), "w")
+
8  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
9  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
10  fout.write('#include <Arduino.h>'+'\n')
+
11  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
12  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n')
+
13  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
+
14  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
+
15  try:
+
16  for num in range(tablelength):
+
17  outstring += str(random.randint(-128, 127)) + ", "
+
18  finally:
+
19  outstring += "};"
+
20  outstring = textwrap.fill(outstring, 80)
+
21  fout.write(outstring)
+
22  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
+
23  fout.close()
+
24  print("wrote " + outfile)
+
25 
+
26 generate("~/Desktop/whitenoise_4096_3_int8.h", "WHITENOISE_4096_3", 4096, 16384) # adjust to suit
+
- -
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)"/> - +
- +
@@ -80,7 +76,7 @@
@@ -103,16 +99,123 @@
teensyPinMap.h
-
1 /*
2  * teensyPinMap.h
3  *
4  * Copyright 2021 T. Combriat.
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 TEENSYPINMAP_H_
13 #define TEENSYPINMAP_H
14 
15 
16 #include "mozzi_config.h"
17 
18 
19 
20 inline uint8_t teensyPinMap(uint8_t pin)
21 {
22  if (pin < 24) return pin-14; // common to all teensys
23 
24 #if defined (__MK20DX128__) // Teensy 3.0
25  return pin - 24;
26 
27 #elif defined (__MK20DX256__) // Teensy 3.1/3.2
28 
29  switch (pin)
30  {
31  case 34:
32  return 10;
33  case 35:
34  return 11;
35  case 36:
36  return 12;
37  case 37:
38  return 13;
39  case 40:
40  return 14;
41  case 26:
42  return 15;
43  case 27:
44  return 16;
45  case 28:
46  return 17;
47  case 29:
48  return 18;
49  case 30:
50  return 19;
51  case 31:
52  return 20;
53  }
54 
55 
56 
57 
58 #elif defined (__MKL26Z64__) //TeensyLC
59  return pin-14;
60 
61 
62 #elif defined(__MK64FX512__) || defined(__MK66FX1M0__) // Teensy 3.5//3.6
63  switch (pin)
64  {
65  case 64:
66  return 10;
67  case 65:
68  return 11;
69  case 31:
70  return 12;
71  case 32:
72  return 13;
73  case 33:
74  return 14;
75  case 34:
76  return 15;
77  case 35:
78  return 16;
79  case 36:
80  return 17;
81  case 37:
82  return 18;
83  case 38:
84  return 19;
85  case 39:
86  return 20;
87  case 66:
88  return 21;
89  case 67:
90  return 22;
91  case 49:
92  return 23;
93  case 50:
94  return 24;
95  case 68:
96  return 25;
97  case 69:
98  return 26;
99  }
100 
101 #elif defined ARDUINO_TEENSY40
102  return pin-14;
103 
104 #elif defined ARDUINO_TEENSY41
105  if (pin< 28) return pin-14;
106  return pin-24;
107 #endif
108 
109 
110 
111 }
112 
113 
114 
115 
116 
117 #endif
+
1 /*
+
2  * teensyPinMap.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2021-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 #ifndef TEENSYPINMAP_H_
+
13 #define TEENSYPINMAP_H
+
14 
+
15 
+
16 inline uint8_t teensyPinMap(uint8_t pin)
+
17 {
+
18  if (pin < 24) return pin-14; // common to all teensys
+
19 
+
20 #if defined (__MK20DX128__) // Teensy 3.0
+
21  return pin - 24;
+
22 
+
23 #elif defined (__MK20DX256__) // Teensy 3.1/3.2
+
24 
+
25  switch (pin)
+
26  {
+
27  case 34:
+
28  return 10;
+
29  case 35:
+
30  return 11;
+
31  case 36:
+
32  return 12;
+
33  case 37:
+
34  return 13;
+
35  case 40:
+
36  return 14;
+
37  case 26:
+
38  return 15;
+
39  case 27:
+
40  return 16;
+
41  case 28:
+
42  return 17;
+
43  case 29:
+
44  return 18;
+
45  case 30:
+
46  return 19;
+
47  case 31:
+
48  return 20;
+
49  }
+
50 
+
51 
+
52 
+
53 
+
54 #elif defined (__MKL26Z64__) //TeensyLC
+
55  return pin-14;
+
56 
+
57 
+
58 #elif defined(__MK64FX512__) || defined(__MK66FX1M0__) // Teensy 3.5//3.6
+
59  switch (pin)
+
60  {
+
61  case 64:
+
62  return 10;
+
63  case 65:
+
64  return 11;
+
65  case 31:
+
66  return 12;
+
67  case 32:
+
68  return 13;
+
69  case 33:
+
70  return 14;
+
71  case 34:
+
72  return 15;
+
73  case 35:
+
74  return 16;
+
75  case 36:
+
76  return 17;
+
77  case 37:
+
78  return 18;
+
79  case 38:
+
80  return 19;
+
81  case 39:
+
82  return 20;
+
83  case 66:
+
84  return 21;
+
85  case 67:
+
86  return 22;
+
87  case 49:
+
88  return 23;
+
89  case 50:
+
90  return 24;
+
91  case 68:
+
92  return 25;
+
93  case 69:
+
94  return 26;
+
95  }
+
96 
+
97 #elif defined ARDUINO_TEENSY40
+
98  return pin-14;
+
99 
+
100 #elif defined ARDUINO_TEENSY41
+
101  if (pin< 28) return pin-14;
+
102  return pin-24;
+
103 #endif
+
104 
+
105 
+
106 
+
107 }
+
108 
+
109 
+
110 
+
111 
+
112 
+
113 #endif
+
- - - + @@ -80,7 +76,7 @@
@@ -103,16 +99,44 @@
triangle.py
-
1 import array
2 import os
3 import textwrap
4 import math
5 
6 def generate(outfile, tablename, tablelength, samplerate):
7  fout = open(os.path.expanduser(outfile), "w")
8  fout.write('#ifndef ' + tablename + '_H_' + '\n')
9  fout.write('#define ' + tablename + '_H_' + '\n \n')
10  fout.write('#if ARDUINO >= 100'+'\n')
11  fout.write('#include "Arduino.h"'+'\n')
12  fout.write('#else'+'\n')
13  fout.write('#include "WProgram.h"'+'\n')
14  fout.write('#endif'+'\n')
15  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
16  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n')
17  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
18  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
19  try:
20  for num in range(tablelength):
21 
22  x = float(num)/tablelength
23  if x<0.5:
24  t_x = 2 * x
25  else:
26  t_x = 2 - 2 * x
27 
28  scaled = int(math.floor(t_x*255.999))
29  outstring += str(scaled) + ', '
30  finally:
31  outstring += "};"
32  outstring = textwrap.fill(outstring, 80)
33  fout.write(outstring)
34  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
35  fout.close()
36  print "wrote " + outfile
37 
38 generate("~/Desktop/triangle512_uint8.h", "triange", 512, "512")
+
1 import array
+
2 import os
+
3 import textwrap
+
4 import math
+
5 
+
6 def generate(outfile, tablename, tablelength, samplerate):
+
7  fout = open(os.path.expanduser(outfile), "w")
+
8  fout.write('#ifndef ' + tablename + '_H_' + '\n')
+
9  fout.write('#define ' + tablename + '_H_' + '\n \n')
+
10  fout.write('#include <Arduino.h>'+'\n')
+
11  fout.write('#include "mozzi_pgmspace.h"'+'\n \n')
+
12  fout.write('#define ' + tablename + '_NUM_CELLS '+ str(tablelength)+'\n')
+
13  fout.write('#define ' + tablename + '_SAMPLERATE '+ str(samplerate)+'\n \n')
+
14  outstring = 'CONSTTABLE_STORAGE(int8_t) ' + tablename + '_DATA [] = {'
+
15  try:
+
16  for num in range(tablelength):
+
17 
+
18  x = float(num)/tablelength
+
19  if x<0.5:
+
20  t_x = 2 * x
+
21  else:
+
22  t_x = 2 - 2 * x
+
23 
+
24  scaled = int(math.floor(t_x*255.999))
+
25  outstring += str(scaled) + ', '
+
26  finally:
+
27  outstring += "};"
+
28  outstring = textwrap.fill(outstring, 80)
+
29  fout.write(outstring)
+
30  fout.write('\n \n #endif /* ' + tablename + '_H_ */\n')
+
31  fout.close()
+
32  print "wrote " + outfile
+
33 
+
34 generate("~/Desktop/triangle512_uint8.h", "triange", 512, "512")
+
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,108 @@
twi_nonblock.h
-
1 /*
2  * twi_nonblock.h
3  *
4  * Copyright 2012 Marije Baalman.
5  *
6  */
7 
8 #ifndef TWI_NONBLOCK_H_
9 #define TWI_NONBLOCK_H_
10 
11 #include <hardware_defines.h>
12 // Added by TB2014 for Teensy 3 port
13 #if IS_AVR() // this code is only for AVRs
14 
15 #include "Arduino.h"
16 #include <compat/twi.h>
17 
18 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
19 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
20 
21 // --- twi reading variables
22  #ifndef TWI_FREQ
23  #define TWI_FREQ 100000L
24  #endif
25 
26  #ifndef TWI_BUFFER_LENGTH
27  #define TWI_BUFFER_LENGTH 32
28  #endif
29 
30  #define TWI_READY 0
31  #define TWI_PRE_MRX 1
32  #define TWI_MRX 2
33  #define TWI_PRE_MTX 3
34  #define TWI_MTX 4
35  #define TWI_SRX 5
36  #define TWI_STX 6
37 
38 static volatile uint8_t twi_state;
39 static volatile uint8_t twi_oldstate;
40 // static uint8_t twiint_masrw;
41 static uint8_t twi_slarw;
42 
43 static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
44 static volatile uint8_t twi_masterBufferIndex;
45 static uint8_t twi_masterBufferLength;
46 
47 static volatile uint8_t twi_error;
48 
49 #define BUFFER_LENGTH 32
50 static uint8_t rxBuffer[BUFFER_LENGTH];
51 static uint8_t rxBufferIndex = 0;
52 static uint8_t rxBufferLength = 0;
53 
54 static uint8_t txAddress = 0;
55 static uint8_t txBuffer[BUFFER_LENGTH];
56 static uint8_t txBufferIndex = 0;
57 static uint8_t txBufferLength = 0;
58 
59 static uint8_t transmitting;
60 
61 
62 void initialize_twi_nonblock();
63 
64 uint8_t twowire_requestFrom(uint8_t address, uint8_t quantity);
65 void twowire_beginTransmission( uint8_t address );
66 void twowire_send( uint8_t data );
67 uint8_t twowire_endTransmission(void);
68 
69 /// non-blocking functions:
70 uint8_t twi_initiateReadFrom(uint8_t address, uint8_t length);
71 void twi_continueReadFrom();
72 
73 uint8_t twi_readMasterBuffer( uint8_t* data, uint8_t length );
74 
75 uint8_t twi_initiateWriteTo(uint8_t address, uint8_t* data, uint8_t length );
76 void twi_continueWriteTo();
77 
78 
79 void twi_reply(uint8_t ack);
80 void twi_stop(void);
81 void twi_releaseBus(void);
82 
83 /// blocking versions:
84 uint8_t twi_readFromBlocking(uint8_t address, uint8_t* data, uint8_t length);
85 uint8_t twi_writeToBlocking(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait);
86 
87 #endif
88 #endif
#define IS_AVR()
+
1 /*
+
2  * twi_nonblock.h
+
3  *
+
4  * This file is part of Mozzi.
+
5  *
+
6  * Copyright 2012-2024 Marije Baalman 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 TWI_NONBLOCK_H_
+
14 #define TWI_NONBLOCK_H_
+
15 
+
16 #include <hardware_defines.h>
+
17 // Added by TB2014 for Teensy 3 port
+
18 #if IS_AVR() // this code is only for AVRs
+
19 
+
20 #include "Arduino.h"
+
21 #include <compat/twi.h>
+
22 
+
23 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+
24 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+
25 
+
26 // --- twi reading variables
+
27  #ifndef TWI_FREQ
+
28  #define TWI_FREQ 100000L
+
29  #endif
+
30 
+
31  #ifndef TWI_BUFFER_LENGTH
+
32  #define TWI_BUFFER_LENGTH 32
+
33  #endif
+
34 
+
35  #define TWI_READY 0
+
36  #define TWI_PRE_MRX 1
+
37  #define TWI_MRX 2
+
38  #define TWI_PRE_MTX 3
+
39  #define TWI_MTX 4
+
40  #define TWI_SRX 5
+
41  #define TWI_STX 6
+
42 
+
43 static volatile uint8_t twi_state;
+
44 static volatile uint8_t twi_oldstate;
+
45 // static uint8_t twiint_masrw;
+
46 static uint8_t twi_slarw;
+
47 
+
48 static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
+
49 static volatile uint8_t twi_masterBufferIndex;
+
50 static uint8_t twi_masterBufferLength;
+
51 
+
52 static volatile uint8_t twi_error;
+
53 
+
54 #define BUFFER_LENGTH 32
+
55 static uint8_t rxBuffer[BUFFER_LENGTH];
+
56 static uint8_t rxBufferIndex = 0;
+
57 static uint8_t rxBufferLength = 0;
+
58 
+
59 static uint8_t txAddress = 0;
+
60 static uint8_t txBuffer[BUFFER_LENGTH];
+
61 static uint8_t txBufferIndex = 0;
+
62 static uint8_t txBufferLength = 0;
+
63 
+
64 static uint8_t transmitting;
+
65 
+
66 
+
67 void initialize_twi_nonblock();
+
68 
+
69 uint8_t twowire_requestFrom(uint8_t address, uint8_t quantity);
+
70 void twowire_beginTransmission( uint8_t address );
+
71 void twowire_send( uint8_t data );
+
72 uint8_t twowire_endTransmission(void);
+
73 
+
74 /// non-blocking functions:
+
75 uint8_t twi_initiateReadFrom(uint8_t address, uint8_t length);
+
76 void twi_continueReadFrom();
+
77 
+
78 uint8_t twi_readMasterBuffer( uint8_t* data, uint8_t length );
+
79 
+
80 uint8_t twi_initiateWriteTo(uint8_t address, uint8_t* data, uint8_t length );
+
81 void twi_continueWriteTo();
+
82 
+
83 
+
84 void twi_reply(uint8_t ack);
+
85 void twi_stop(void);
+
86 void twi_releaseBus(void);
+
87 
+
88 /// blocking versions:
+
89 uint8_t twi_readFromBlocking(uint8_t address, uint8_t* data, uint8_t length);
+
90 uint8_t twi_writeToBlocking(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait);
+
91 
+
92 #endif
+
93 
+
94 #if !defined _MOZZI_TWI_HEADER_ONLY
+
95 #include "internal/twi_nonblock.hpp"
+
96 #endif
+
97 
+
98 #endif
- - - + @@ -80,7 +76,7 @@
@@ -103,17 +99,651 @@
umpah_huff.h
-
1 // generated by Mozzi/extras/python/audio2huff.py
2 
3 #ifndef UMPAH_H_
4 #define UMPAH_H_
5 
6 #if ARDUINO >= 100
7 #include "Arduino.h"
8 #else
9 #include "WProgram.h"
10 #endif
11 
12 #include "mozzi_pgmspace.h"
13 
14 
15 #define UMPAH_SAMPLERATE 16384
16 #define UMPAH_SAMPLE_BITS 8
17 CONSTTABLE_STORAGE(int16_t) UMPAH_HUFFMAN[280] = {
18 277,169,67,0,1,64,46,28,25,7,4,0,-25,0,-26,0,-13,16,7,0,-31,4,0,-36,0,-39,7,0,20,4,0,-38,0,-35,0,-6,16,0,5,13,
19 10,0,13,7,0,31,4,0,39,0,-34,0,-10,16,0,4,13,10,4,0,16,0,-14,4,0,-15,0,15,0,-7,100,4,0,3,0,-2,94,52,49,43,
20 10,7,4,0,-37,0,36,0,-32,0,19,31,28,22,19,0,-43,16,0,44,13,10,4,0,46,0,-45,4,0,-46,0,-62,0,45,0,41,4,0,40,0,
21 37,0,17,4,0,9,0,8,0,-4,40,22,13,7,0,-16,4,0,32,0,-33,4,0,-18,0,-17,7,4,0,-19,0,18,0,-11,16,13,10,0,21,7,
22 4,0,-40,0,-41,0,35,0,-12,0,-8,106,4,0,-1,0,2,100,55,34,19,10,4,0,22,0,-23,4,0,23,0,-20,7,4,0,25,0,-21,0,10,
23 13,0,-9,10,4,0,-24,0,-29,4,0,28,0,24,19,16,0,6,13,0,11,10,7,0,34,4,0,38,0,-42,0,27,0,-5,43,40,19,7,4,0,
24 -22,0,-27,0,12,10,4,0,-30,0,29,4,0,30,0,26,19,16,13,0,-28,10,0,33,7,4,0,42,0,-44,0,43,0,14,0,7,0,-3,0,0
25 };
26 uint32_t const UMPAH_SOUNDDATA_BITS = 196860L;
27 CONSTTABLE_STORAGE(byte) UMPAH_SOUNDDATA[] = {
28 210,20,130,2,84,176,64,164,16,40,8,29,42,245,148,33,72,34,0,32,104,132,68,82,192,164,66,170,80,100,40,32,2,104,165,134,133,104,242,140,
29 60,194,228,96,20,116,96,79,41,213,219,49,158,86,27,9,182,8,180,122,58,107,156,155,98,8,22,112,138,113,114,152,128,140,117,60,130,208,161,20,
30 98,207,136,134,36,230,195,107,78,3,129,129,16,68,158,98,61,163,56,71,14,4,97,30,120,29,152,6,112,161,20,96,68,179,69,176,233,152,98,156,
31 7,3,20,205,62,98,196,122,156,66,45,169,206,34,204,38,19,200,206,99,48,14,144,28,109,104,93,194,233,140,51,163,166,58,5,197,176,183,6,176,
32 242,56,181,207,40,140,97,60,141,115,33,28,214,33,198,214,133,221,14,152,197,57,24,150,107,33,108,34,149,210,60,174,45,119,77,60,29,76,65,202,
33 100,121,12,10,8,243,18,33,112,186,119,1,200,196,186,25,24,179,142,214,8,227,39,43,91,58,158,15,43,93,140,71,58,83,4,192,178,16,90,209,
34 204,232,45,132,1,115,2,34,69,161,110,102,231,17,198,51,8,139,98,56,136,177,104,97,30,96,68,179,76,81,193,192,233,140,193,201,138,17,13,48,
35 34,60,97,104,69,186,179,207,43,8,112,121,5,166,134,0,192,188,68,49,67,150,97,137,112,14,133,179,52,73,139,17,228,22,132,115,139,16,242,30,
36 7,2,45,206,236,91,185,138,96,158,98,226,8,182,98,156,218,211,160,75,88,113,145,202,35,218,152,70,0,234,56,17,78,119,98,60,226,65,16,192,
37 139,136,6,41,138,112,49,76,209,38,4,91,145,202,34,154,153,226,44,194,99,17,206,115,49,20,113,35,144,243,100,32,53,163,145,201,173,8,34,230,
38 44,68,67,136,69,49,185,196,113,212,194,35,156,236,98,40,226,83,140,197,178,112,152,163,145,208,197,8,39,98,216,193,67,204,192,59,114,136,179,25,
39 224,242,181,218,132,113,196,167,25,230,219,53,173,14,88,38,41,152,57,22,198,9,173,96,138,20,206,17,206,44,33,22,97,28,8,183,43,65,30,233,
40 26,205,48,39,172,19,22,116,57,152,183,8,150,176,227,35,148,69,56,176,12,0,140,234,34,156,226,142,55,73,183,65,139,61,112,53,166,40,228,91,
41 51,71,152,177,30,41,204,121,12,103,129,22,194,22,8,231,48,163,0,98,196,136,134,36,116,204,116,193,0,114,98,140,23,158,98,61,163,152,71,14,
42 216,71,145,158,234,34,206,33,132,121,139,18,205,49,67,166,41,138,96,158,139,97,16,167,152,138,118,206,48,14,172,3,200,192,117,60,174,97,132,81,
43 230,37,154,214,135,44,17,108,193,29,53,167,32,243,2,35,212,90,60,130,198,123,91,96,14,15,35,153,160,142,48,47,48,76,80,229,152,98,88,167,
44 51,18,205,30,98,196,80,194,208,139,113,103,158,67,192,224,242,185,154,8,227,2,217,130,98,135,44,193,108,224,29,24,167,64,147,2,113,140,233,8,
45 225,99,156,242,179,199,7,148,90,20,35,140,9,162,220,196,142,68,7,78,193,29,58,119,33,173,104,71,138,116,143,35,171,17,173,176,135,103,145,204,
46 236,69,30,101,48,76,73,216,130,233,140,83,129,137,114,15,107,70,0,142,147,91,22,51,218,217,224,118,121,92,174,196,91,88,241,30,45,135,46,131,
47 18,224,98,152,151,32,185,138,48,0,214,30,87,22,113,136,48,12,45,109,202,100,35,143,56,143,22,204,157,6,36,232,195,49,46,19,209,108,45,222,
48 96,79,33,152,180,214,206,172,35,16,103,11,15,43,88,49,128,49,35,196,67,17,28,24,38,34,16,4,46,152,45,222,98,196,91,67,137,173,142,220,
49 238,154,231,28,30,83,205,160,143,49,69,17,12,68,122,204,49,29,152,57,116,195,4,73,129,17,195,11,71,148,88,207,60,172,33,216,139,114,187,48,
50 13,99,206,51,22,122,205,22,206,6,25,139,114,11,158,98,41,14,35,202,100,231,49,3,9,213,173,181,216,207,33,231,22,230,40,93,194,233,206,135,
51 71,78,232,23,49,34,42,121,158,70,54,115,91,58,176,26,219,157,213,173,158,100,17,198,37,144,136,98,35,163,20,196,78,17,11,167,22,229,22,194,
52 44,201,210,49,3,171,17,211,90,238,166,32,121,168,142,49,39,196,67,17,206,108,83,17,196,3,183,78,34,20,91,24,7,109,97,229,28,57,218,219,
53 156,118,121,90,193,140,3,90,18,34,24,147,128,128,233,196,17,209,138,22,227,207,51,200,70,185,136,56,152,93,52,70,113,49,6,184,161,22,121,182,
54 113,139,97,8,128,98,88,103,51,18,232,30,45,132,121,15,51,200,44,103,53,182,1,132,196,28,198,71,144,197,148,69,58,96,132,65,49,19,4,230,
55 233,196,65,230,40,71,16,243,107,98,198,187,166,176,142,166,32,230,50,17,102,44,167,25,137,61,16,29,59,20,230,233,220,131,197,177,128,20,214,30,
56 65,219,92,242,49,14,162,45,210,50,17,70,41,238,71,78,33,102,24,137,130,115,116,195,140,75,90,60,131,11,77,108,88,196,116,214,1,140,196,105,
57 204,40,196,12,8,241,28,98,142,78,67,18,225,97,152,161,110,125,173,8,178,53,141,109,213,156,98,12,243,9,229,56,140,132,112,182,67,140,196,157,
58 184,76,68,193,57,58,119,35,35,20,96,20,243,60,174,45,115,16,96,24,90,219,149,140,242,24,20,17,230,36,245,208,233,216,167,71,78,205,100,98,
59 68,80,30,103,145,169,174,233,167,131,9,136,57,88,196,113,139,3,5,211,178,102,24,140,28,142,6,34,16,71,152,163,140,15,49,22,212,215,107,102,
60 19,11,91,107,153,8,182,178,35,197,177,219,52,196,177,88,102,41,200,122,96,76,3,197,166,182,209,136,98,50,99,28,58,107,156,204,242,53,147,140,
61 91,50,16,93,57,204,228,233,130,3,35,20,113,207,49,28,100,206,107,102,19,11,91,107,177,136,182,178,113,152,182,78,19,18,114,58,24,145,4,236,
62 91,28,115,204,71,49,179,143,33,132,194,121,90,230,66,44,90,65,30,96,69,220,38,40,230,114,49,44,195,230,41,154,7,152,183,106,114,152,3,11,
63 0,69,181,220,68,81,196,65,110,98,199,186,5,177,205,134,45,132,3,214,180,96,149,172,48,14,220,162,44,118,35,30,70,3,81,228,103,1,128,56,
64 133,204,19,204,232,193,48,34,8,132,243,114,26,214,11,119,108,225,30,59,96,24,6,123,168,138,114,140,113,181,130,93,6,44,116,197,107,78,3,211,
65 22,205,53,172,22,237,25,198,0,118,120,17,204,1,97,128,115,12,45,207,54,221,2,216,116,197,49,76,17,9,139,114,54,233,8,161,76,225,22,44,
66 60,8,182,3,168,142,115,59,56,204,89,92,38,36,236,232,233,140,51,179,18,225,121,139,22,238,197,161,28,56,97,8,182,19,168,142,114,138,17,231,
67 152,151,35,90,29,48,69,179,48,116,96,76,17,226,208,139,6,33,136,25,24,93,52,194,212,121,89,195,8,166,176,214,104,182,16,177,76,83,12,66,
68 45,156,38,158,103,24,167,41,128,117,96,8,230,3,169,128,114,138,22,237,97,172,211,22,122,193,22,204,49,211,90,112,137,107,14,50,57,76,3,83,
69 0,69,136,206,162,57,174,40,71,186,70,179,76,9,235,128,197,157,7,77,105,152,217,129,114,10,22,140,17,99,156,91,158,12,98,221,156,100,96,186,
70 87,9,139,100,197,22,199,49,203,90,102,54,121,185,8,229,22,236,108,35,0,99,117,17,108,1,132,91,16,120,138,107,156,220,142,102,99,20,90,116,
71 29,139,66,32,57,78,54,166,33,198,97,48,156,110,118,161,16,90,87,65,230,125,192,96,78,3,163,205,192,125,210,116,92,166,9,155,8,71,142,12,
72 98,41,132,100,45,217,200,228,56,143,179,15,51,129,204,243,96,178,107,25,168,229,56,221,176,132,123,168,224,71,176,12,142,55,42,186,26,195,92,13,
73 104,244,114,214,142,130,76,91,48,142,147,161,141,156,34,24,207,7,27,61,196,227,115,43,145,210,30,32,30,99,163,147,88,204,61,115,24,34,88,130,
74 46,99,116,215,102,102,32,234,65,22,194,41,130,45,15,96,152,19,209,208,182,57,9,49,108,192,116,156,134,78,115,140,112,117,22,236,6,163,141,156,
75 174,67,136,123,48,243,29,28,207,55,0,187,164,232,43,148,68,104,207,22,238,166,49,30,120,99,22,237,112,17,5,161,226,3,164,58,57,53,142,3,
76 183,73,194,130,211,145,219,92,68,28,30,12,22,123,171,145,204,208,65,48,37,98,139,102,67,161,108,115,30,98,217,147,137,154,209,206,45,197,134,49,
77 20,117,50,17,76,40,143,98,29,152,44,71,3,161,158,205,98,179,206,49,118,32,143,86,33,198,234,192,114,51,199,14,129,104,200,65,107,46,3,204,
78 92,228,96,78,135,109,96,128,107,153,200,71,57,198,212,97,22,231,87,19,141,136,71,35,149,177,4,90,61,97,156,71,65,201,196,32,54,229,102,140,
79 196,17,26,132,99,140,194,212,113,179,198,114,57,94,32,58,76,142,71,152,228,92,192,157,10,121,179,26,11,78,17,219,61,208,192,28,58,26,230,110,
80 23,53,152,113,50,97,156,71,35,131,148,64,23,115,152,47,48,136,224,113,60,174,197,30,81,218,8,166,16,150,107,153,145,209,172,16,139,152,19,147,
81 218,198,8,206,103,67,83,8,68,49,142,204,22,19,183,35,94,225,56,153,48,206,33,208,232,226,96,143,115,58,44,65,17,216,140,113,142,221,78,51,
82 195,71,35,156,162,11,149,147,128,90,57,142,133,167,0,145,104,64,35,57,194,198,194,102,152,76,110,134,35,24,130,230,87,3,164,105,205,172,59,59,
83 107,14,70,186,76,18,53,220,38,71,135,35,171,169,130,97,20,34,30,13,17,24,3,166,105,225,130,193,60,51,71,76,1,16,214,3,145,217,225,154,
84 56,58,184,89,237,66,3,56,142,1,105,179,161,196,122,33,22,142,67,220,172,192,98,56,76,196,102,107,171,171,144,194,237,208,194,71,11,156,251,129,
85 156,58,56,51,152,167,218,226,5,136,232,118,35,57,5,142,172,211,11,183,67,61,89,140,230,206,66,208,185,235,164,112,108,226,97,145,156,193,106,103,
86 136,6,51,171,49,128,226,193,107,140,197,114,188,228,230,61,29,51,152,98,236,65,4,73,132,227,123,136,142,81,66,44,205,4,80,224,214,107,8,75,
87 21,204,46,122,113,14,91,56,142,128,206,96,187,97,8,34,195,27,132,70,99,16,89,228,96,181,219,58,57,79,71,44,227,152,187,93,130,107,9,194,
88 67,11,145,141,213,200,56,51,116,30,0,64,98,54,197,107,136,78,13,115,160,187,157,192,87,59,49,219,9,152,234,97,102,30,5,140,23,59,70,43,
89 153,14,103,16,147,179,136,244,72,180,115,179,156,14,216,66,3,136,225,154,56,118,205,49,160,136,117,61,17,7,14,7,8,225,194,197,58,185,25,24,
90 93,10,120,16,5,134,22,9,224,118,224,115,153,48,217,211,147,148,248,229,202,57,100,206,97,189,136,193,24,240,32,49,152,220,35,134,167,64,140,48,
91 130,194,53,152,196,61,58,49,14,103,172,70,43,108,246,96,30,28,38,99,135,64,177,169,208,35,12,204,103,163,21,156,36,116,230,59,62,45,14,138,
92 230,58,10,115,177,69,140,6,9,132,112,193,103,177,177,90,227,28,153,198,142,153,194,19,215,59,20,249,225,154,61,196,192,54,49,228,160,139,51,52,
93 227,49,154,204,115,137,28,139,76,135,156,66,20,115,28,134,115,176,88,196,97,0,118,44,16,12,46,216,44,32,97,185,196,156,26,231,167,173,115,144,
94 150,123,5,4,97,4,80,225,208,212,198,232,49,138,16,79,5,96,176,143,157,24,131,145,11,16,230,61,136,197,176,152,46,196,102,11,168,225,130,35,
95 49,177,88,131,28,153,200,33,22,132,159,22,142,202,230,29,12,215,58,25,48,24,34,193,96,130,59,104,232,49,182,205,117,56,8,130,193,1,194,226,
96 205,97,186,179,79,157,92,35,24,88,46,167,86,24,140,234,116,98,59,57,51,144,116,206,30,122,206,28,143,115,157,17,128,224,20,117,102,49,186,136,
97 35,179,54,97,132,28,12,6,206,140,33,113,211,8,224,201,132,195,52,240,193,83,24,128,102,226,32,139,29,179,12,36,98,176,138,115,98,31,61,115,
98 158,137,107,156,1,136,114,118,192,98,139,14,172,83,11,169,201,158,100,112,103,16,237,202,246,76,225,113,236,243,147,102,55,8,151,98,41,180,17,104,
99 36,71,10,62,34,11,15,184,24,7,207,89,194,230,179,143,85,174,112,118,194,58,56,152,216,163,135,23,0,140,41,138,192,67,147,60,120,229,158,33,
100 100,194,57,26,192,112,41,141,152,209,196,64,106,118,32,14,21,130,35,61,134,192,62,112,97,14,78,216,7,35,79,12,53,17,156,6,67,134,40,236,
101 88,195,60,25,156,153,234,112,107,154,118,215,62,219,148,236,25,195,167,108,67,152,176,70,58,14,197,142,3,24,204,195,171,98,8,236,230,225,106,16,
102 68,3,33,16,228,100,34,31,113,112,140,234,193,117,117,57,30,24,206,12,65,135,45,114,158,181,207,159,115,142,94,194,58,41,133,192,236,118,193,106,
103 106,96,142,197,49,76,40,195,96,15,56,30,15,79,79,7,33,230,22,41,76,108,17,133,140,198,54,54,8,237,163,12,70,3,155,8,209,11,61,147,
104 38,120,228,214,17,205,88,7,67,51,11,12,118,59,58,30,28,71,44,67,51,215,42,159,114,154,219,92,244,211,195,12,163,183,9,90,11,115,77,17,
105 200,118,34,133,30,185,5,135,103,67,192,185,246,32,189,206,33,20,194,56,49,152,78,66,193,97,208,198,100,116,17,136,115,96,26,57,97,31,23,96,
106 14,68,158,14,136,99,98,145,213,152,102,102,204,113,35,4,112,140,51,11,103,6,1,217,233,224,224,60,194,114,67,9,209,161,141,138,212,226,197,29,
107 153,156,143,3,14,89,232,118,196,18,61,206,202,215,23,104,196,16,184,176,7,35,131,25,192,198,100,116,49,163,128,118,118,204,99,96,136,34,153,174,
108 1,70,8,133,219,145,237,76,19,49,97,200,234,226,58,97,59,61,98,0,187,17,179,236,243,179,88,3,168,140,114,24,112,195,99,113,97,139,29,176,
109 199,0,116,58,182,112,58,157,136,78,167,6,70,51,161,163,134,26,186,177,76,218,152,174,34,152,99,176,57,8,197,28,176,4,178,97,11,182,194,16,
110 128,140,112,104,99,57,184,142,206,102,55,17,211,0,204,237,136,49,246,114,26,215,30,107,8,114,241,195,21,238,196,70,205,48,13,139,136,164,61,114,
111 25,178,97,152,207,178,97,9,43,157,144,166,120,132,204,194,112,99,117,57,139,12,142,70,49,142,102,24,228,240,36,236,240,46,36,70,29,60,198,114,
112 1,99,20,102,54,9,152,167,3,141,134,56,121,192,194,60,244,194,118,46,97,56,54,99,57,0,224,232,102,234,115,117,113,56,29,90,14,143,0,118,
113 194,53,147,60,121,172,246,74,194,59,51,96,30,139,12,39,163,135,83,129,140,81,208,112,219,21,168,230,32,140,225,16,20,68,58,12,228,100,100,204,
114 35,137,201,213,212,66,35,49,157,176,133,29,179,202,201,128,60,123,0,245,230,17,210,152,206,109,29,78,76,108,103,71,81,71,33,194,28,204,99,199,
115 70,51,211,179,25,192,120,224,228,142,172,49,154,152,102,110,216,110,35,29,7,8,58,58,154,118,120,30,37,128,46,243,192,132,134,17,209,152,224,224,
116 44,22,14,78,172,103,172,7,108,152,131,54,215,71,179,207,148,194,58,43,136,128,108,227,30,124,192,9,16,139,120,132,64,99,100,112,48,143,109,158,
117 36,24,140,154,48,15,76,204,99,150,167,19,131,171,179,129,141,71,39,82,157,136,195,207,136,199,109,157,71,72,59,57,43,83,12,81,155,20,200,102,
118 27,138,28,135,98,71,67,177,115,209,192,132,121,140,114,134,49,208,161,217,193,141,196,116,234,100,58,49,144,114,97,65,115,195,98,88,2,81,132,124,
119 83,9,147,25,224,92,118,99,61,28,49,142,135,10,115,113,62,224,118,195,16,85,154,204,136,135,50,8,45,153,176,218,53,14,71,110,39,98,49,152,
120 187,1,89,48,13,30,35,31,121,212,237,12,99,146,14,206,6,109,71,6,167,103,7,85,29,14,222,57,28,31,59,28,30,159,117,29,54,44,57,88,
121 206,131,25,157,12,133,28,220,84,116,56,67,211,169,167,204,35,222,97,101,58,158,140,59,29,25,139,7,66,198,161,9,212,205,145,225,163,108,242,21,
122 158,84,60,31,142,7,72,102,32,54,243,140,121,232,138,108,116,34,41,235,21,140,249,217,132,73,88,2,69,30,25,59,58,158,153,11,7,45,70,67,
123 145,96,194,17,216,30,152,222,200,234,125,179,24,185,71,98,16,22,28,6,50,57,187,24,232,101,57,53,26,112,22,15,59,29,178,30,59,61,109,212,
124 115,117,29,52,113,28,177,153,8,93,90,30,142,20,92,198,81,230,22,222,120,18,167,129,230,98,48,241,97,212,248,236,88,46,56,118,122,59,41,204,
125 200,114,193,6,96,130,241,17,138,247,65,232,206,9,152,233,169,168,92,198,212,124,194,208,121,134,60,194,37,179,171,34,142,14,213,212,66,41,196,114,
126 100,100,58,113,20,57,22,68,46,173,158,186,139,139,184,136,71,181,28,30,198,115,83,35,155,70,135,54,49,135,78,160,122,56,67,231,83,91,48,159,
127 67,24,186,142,207,69,11,4,38,77,71,162,195,33,115,171,65,236,1,141,97,74,35,54,131,131,212,50,58,55,116,31,100,34,31,59,102,148,93,138,
128 236,121,232,224,211,79,6,169,224,72,163,171,39,98,195,211,35,33,203,83,65,200,177,78,221,81,144,225,177,35,134,79,29,158,220,71,74,100,115,20,
129 40,230,236,135,51,34,156,24,219,16,184,143,100,59,100,104,236,236,29,79,70,22,8,76,204,132,45,77,15,93,72,118,59,159,49,154,217,141,178,157,
130 79,169,213,145,152,225,147,80,176,93,196,204,245,196,7,76,103,206,131,28,216,106,224,57,171,128,237,161,209,12,135,46,218,142,197,140,108,135,13,15,
131 142,0,248,225,227,199,3,205,117,23,65,97,233,28,68,46,204,132,38,77,4,45,74,122,226,135,162,193,34,238,34,227,220,68,45,177,156,16,204,224,
132 71,103,7,98,132,44,100,59,117,159,29,148,72,224,73,71,7,238,167,100,106,61,104,100,118,198,236,92,88,40,248,224,130,78,179,78,166,188,112,201,
133 28,71,47,20,197,109,226,1,163,216,40,37,134,237,177,8,177,226,76,102,161,213,181,28,31,24,88,46,209,140,244,205,161,235,25,15,92,98,226,199,
134 143,117,18,107,171,34,184,157,129,144,133,93,142,134,24,116,236,7,38,69,61,113,108,93,196,120,241,96,187,197,135,96,226,118,41,140,236,204,204,237,
135 168,97,119,16,100,234,81,46,166,154,59,18,131,179,228,117,100,237,196,92,200,200,237,140,99,214,55,142,93,178,56,12,58,29,12,115,59,20,112,123,
136 177,9,12,142,204,140,207,184,180,62,234,67,238,168,61,213,182,197,135,202,226,47,106,61,24,200,245,163,67,211,33,143,90,167,110,38,178,113,30,61,
137 169,147,108,103,168,102,33,87,98,17,154,8,76,212,237,142,201,196,163,197,143,53,212,73,69,140,129,168,92,140,103,174,221,139,153,52,23,113,33,241,
138 221,177,219,222,234,36,174,44,144,204,114,132,57,149,14,147,78,99,26,57,50,53,147,137,166,186,182,142,163,212,88,200,102,49,118,134,103,102,99,29,
139 177,128,187,81,79,184,182,37,196,123,218,143,163,25,218,153,158,140,208,66,208,135,166,115,179,39,178,106,18,61,168,121,173,66,232,198,118,166,66,226,
140 140,197,204,197,11,181,43,39,20,62,44,53,183,22,202,226,60,28,79,145,168,251,67,38,70,98,133,216,192,236,201,231,110,217,30,180,61,23,20,33,
141 18,40,66,142,206,198,118,46,102,209,147,81,7,184,196,184,189,183,17,47,106,62,141,66,224,100,118,51,179,183,99,29,153,3,35,36,62,198,104,246,
142 49,230,153,31,121,144,188,204,244,141,15,90,16,93,218,139,177,207,181,60,75,139,111,106,31,99,62,12,98,227,59,23,118,41,145,145,15,177,128,151,
143 20,108,88,107,218,132,149,140,94,208,246,163,156,116,71,136,90,60,92,201,226,90,141,123,136,155,136,245,50,62,51,182,77,5,11,187,32,185,148,251,
144 27,196,177,182,107,80,242,153,31,153,139,145,161,216,161,142,218,40,187,180,100,100,104,243,38,219,99,30,86,54,64,100,200,134,108,154,10,100,102,70,
145 70,64,125,140,162,88,205,53,168,73,90,143,169,145,241,140,217,52,104,201,217,25,25,217,25,182,201,217,246,77,5,196,180,59,43,177,117,104,200,83,
146 67,238,198,62,198,3,216,208,75,25,166,177,137,41,144,249,155,37,118,46,40,80,187,66,50,51,159,50,40,243,35,91,50,30,243,35,232,237,144,59,
147 23,32,161,113,68,23,51,159,50,65,44,102,154,198,217,88,196,204,143,169,155,33,154,50,118,67,230,106,60,202,37,141,230,177,182,83,33,232,237,148,
148 99,186,158,172,236,81,89,59,40,246,55,154,198,105,88,196,204,135,169,155,33,154,50,104,70,70,96,124,204,162,76,141,109,141,183,153,137,67,51,224,
149 209,145,5,50,20,172,157,207,187,67,230,70,137,50,18,243,49,40,102,125,93,159,24,81,246,131,31,51,83,230,72,36,201,237,153,26,243,33,40,100,
150 61,93,159,25,161,241,67,31,118,12,157,161,246,141,143,104,60,75,67,239,104,126,208,249,26,31,104,49,243,53,30,103,18,100,86,204,155,121,144,146,
151 153,143,187,62,162,143,140,49,246,128,61,220,121,155,219,50,108,211,49,40,236,125,219,34,12,124,132,62,40,15,153,160,147,50,182,100,247,153,54,134,
152 99,193,216,245,104,124,97,143,187,83,230,113,38,104,217,145,175,50,18,142,199,218,31,2,11,144,5,198,139,180,65,238,202,36,200,210,153,154,134,98,
153 65,216,242,10,30,48,199,197,40,247,104,37,217,91,51,52,211,54,202,236,77,217,245,104,124,131,31,20,163,218,71,153,189,183,102,154,102,36,174,196,
154 218,15,86,135,198,20,125,162,143,119,18,102,86,204,222,105,153,165,51,19,118,37,90,15,24,97,226,148,123,72,247,111,18,209,182,218,15,53,160,244,
155 20,125,69,15,32,195,218,16,123,176,18,238,217,155,205,51,53,230,98,81,216,240,20,60,132,30,49,15,180,1,238,209,183,111,52,204,215,187,109,29,
156 143,1,67,212,99,227,40,241,64,61,218,54,102,247,187,52,166,109,163,177,32,40,121,6,30,49,7,180,1,46,209,179,50,154,102,105,93,137,180,30,
157 2,143,169,25,16,15,141,30,41,4,187,121,166,102,149,219,119,98,65,160,146,12,60,82,137,20,2,90,32,151,101,109,217,175,118,218,52,18,2,132,
158 168,194,70,81,34,128,75,68,109,161,77,104,107,221,137,70,130,64,80,146,12,60,98,9,20,2,93,163,109,10,107,183,189,219,104,236,72,52,18,162,
159 132,140,162,69,0,150,136,37,163,219,104,105,173,4,148,80,148,20,37,70,30,49,4,138,1,46,208,214,136,107,179,74,237,180,104,220,80,149,24,121,
160 8,60,80,9,21,109,161,77,118,247,187,109,26,55,20,37,70,30,66,15,20,2,69,91,104,83,93,189,238,219,70,141,218,9,1,132,144,130,69,3,
161 98,129,182,136,107,183,149,161,168,41,184,161,234,65,234,67,227,0,241,162,90,20,214,133,123,67,81,163,96,40,74,138,18,66,9,25,68,138,182,208,
162 166,180,123,218,26,86,141,197,9,1,66,72,65,35,40,145,86,218,35,109,30,246,134,149,163,113,66,84,97,42,48,145,129,177,86,218,33,173,30,246,
163 143,43,67,98,155,1,66,72,48,145,129,177,128,72,164,109,163,205,20,107,218,9,140,216,12,37,70,18,50,137,21,109,162,26,208,175,104,242,180,110,
164 41,184,161,42,65,36,81,34,173,138,67,90,21,237,13,65,70,197,54,3,9,82,9,25,68,140,13,138,67,69,21,237,30,81,70,197,55,20,37,70,
165 18,69,108,84,209,83,90,21,237,30,86,141,160,166,192,97,32,65,36,1,35,91,26,219,66,188,83,202,208,212,20,216,12,218,145,178,43,99,3,98,
166 144,209,72,107,71,189,161,168,41,184,161,42,48,146,43,99,3,98,166,138,43,197,60,162,141,65,70,198,108,6,18,69,108,96,108,85,182,133,120,167,
167 149,161,168,40,208,25,181,25,178,43,99,3,99,91,20,87,140,242,138,52,162,155,140,216,12,36,138,216,192,216,211,69,35,197,21,237,13,65,70,198,
168 109,72,218,171,100,86,198,154,50,60,81,74,40,212,20,108,83,96,48,146,43,100,3,70,154,50,60,83,202,41,229,20,108,102,192,102,212,141,144,13,
169 24,13,20,143,20,82,138,122,12,108,102,192,141,170,182,64,108,147,70,71,138,121,69,60,162,141,140,216,12,218,145,178,43,99,1,163,35,198,41,70,
170 122,12,108,99,64,141,145,77,32,26,52,209,72,104,162,148,103,160,207,65,141,2,26,4,108,128,104,211,70,71,140,82,140,82,138,54,49,170,67,84,
171 141,145,77,36,209,145,227,20,163,60,163,61,6,54,67,64,141,144,13,32,26,50,60,98,148,83,208,103,198,54,51,106,166,170,182,52,209,145,227,35,
172 197,20,162,158,131,26,4,53,84,213,86,198,154,52,209,145,226,158,131,61,6,54,67,85,77,85,108,96,52,107,198,66,138,41,70,124,134,129,13,5,
173 53,64,210,77,25,30,50,60,98,148,103,160,198,200,104,16,213,83,72,15,37,227,35,198,41,70,122,12,108,99,64,134,170,154,64,52,107,198,41,70,
174 41,70,124,143,144,208,33,170,6,144,13,37,227,20,163,20,163,62,49,160,71,129,13,85,52,128,104,211,70,71,140,82,144,168,71,200,104,41,170,166,
175 168,26,75,200,133,24,165,24,168,51,228,120,43,193,77,32,26,73,163,35,198,66,140,84,25,242,62,67,85,77,32,26,75,200,133,34,20,133,66,62,
176 67,64,134,168,61,65,228,7,146,82,33,70,42,12,249,13,5,53,65,234,6,146,242,35,198,41,70,41,70,122,17,242,26,170,105,0,210,3,201,120,
177 200,82,21,8,249,31,33,170,166,170,154,64,121,47,24,165,24,168,71,200,249,13,5,120,41,164,188,136,82,33,72,84,25,242,60,8,240,87,170,154,
178 75,201,121,16,164,42,16,168,71,200,104,43,193,77,80,122,222,68,40,197,66,21,6,124,143,5,122,131,212,13,37,227,20,163,21,8,89,31,35,193,
179 77,85,52,151,145,10,68,41,10,132,124,143,171,193,94,160,245,7,146,82,74,68,40,197,66,62,71,213,234,15,91,201,121,16,164,42,16,168,71,213,
180 224,175,5,122,131,201,121,37,34,20,133,66,22,175,5,122,131,212,30,75,200,133,34,20,133,169,106,240,87,130,154,75,201,121,16,164,66,144,178,62,
181 71,129,30,10,245,7,168,60,136,82,33,72,84,33,106,240,87,128,61,111,89,86,242,34,16,168,66,200,240,87,168,61,65,228,188,136,82,33,72,90,
182 150,165,171,212,30,160,245,148,136,82,21,8,84,35,228,125,94,160,245,7,146,242,74,68,66,21,8,90,150,175,5,122,131,214,85,149,81,20,168,71,
183 213,224,175,0,40,1,84,30,73,72,136,168,132,124,143,169,64,30,160,245,7,145,10,68,41,10,132,42,17,224,175,5,120,3,212,30,68,41,16,164,
184 68,82,200,240,82,128,20,0,171,42,202,68,41,10,132,45,75,87,130,188,1,235,122,202,168,82,34,42,33,10,10,80,2,128,21,101,89,85,17,81,
185 20,181,45,75,87,168,61,101,89,85,17,81,20,181,45,75,87,168,61,64,171,41,17,21,16,133,169,106,90,188,21,235,42,202,178,170,34,149,8,250,
186 188,0,160,5,0,42,209,104,168,132,42,16,181,120,1,64,10,0,245,148,136,82,34,41,106,90,188,0,160,5,0,122,202,178,170,33,11,82,200,240,
187 82,128,20,0,171,42,202,68,41,11,82,212,181,120,1,66,85,66,172,170,136,168,132,45,74,10,80,2,172,171,42,202,168,138,136,165,169,106,80,2,
188 128,61,101,89,85,17,81,20,181,45,94,10,245,149,104,178,173,21,17,81,20,160,5,0,42,202,178,172,170,136,168,138,88,22,175,0,40,1,86,139,
189 41,17,21,42,90,150,5,0,40,1,64,10,168,138,136,168,138,90,150,5,0,40,1,66,85,149,101,84,169,106,80,2,128,21,104,20,84,69,68,84,
190 69,74,150,165,171,192,10,18,170,32,74,168,138,149,40,2,0,20,0,171,42,202,178,170,34,162,41,106,80,2,128,20,37,89,85,17,81,20,181,45,
191 75,4,129,86,85,162,162,42,34,165,75,82,128,20,0,171,42,208,40,8,138,136,165,129,96,80,2,173,2,139,69,68,84,169,106,88,36,10,178,172,
192 170,136,168,138,90,150,5,0,40,1,66,129,42,202,168,138,149,45,74,0,80,2,173,2,138,136,168,138,136,169,4,169,66,129,40,74,168,128,136,169,
193 4,169,64,16,0,160,5,89,86,128,144,72,36,10,0,80,2,133,2,85,149,81,21,17,75,82,193,32,129,64,160,81,81,21,32,149,40,1,64,10,
194 0,85,149,104,20,4,69,44,10,0,88,20,0,171,69,68,90,42,34,164,18,9,2,128,21,101,84,69,68,84,69,45,75,4,129,66,129,64,160,80,
195 18,9,82,212,160,5,0,64,160,81,81,21,17,82,9,4,130,4,161,64,68,10,2,34,164,18,165,0,64,2,172,171,64,160,36,18,9,2,128,20,
196 0,161,64,160,34,42,34,150,9,4,130,65,2,129,64,162,164,18,165,0,40,1,64,10,0,85,160,80,18,8,128,144,44,18,5,0,64,162,164,40,
197 169,4,130,65,2,129,64,149,82,9,4,129,96,144,40,1,66,129,64,160,36,18,9,82,128,20,0,171,64,160,81,82,9,4,130,65,32,80,2,132,
198 170,136,9,4,130,65,0,18,8,20,90,5,2,128,144,72,36,18,5,0,40,80,40,8,138,136,9,4,130,65,32,129,64,160,81,82,9,82,128,36,
199 18,8,20,10,2,65,17,75,4,129,66,144,64,160,80,48,162,160,2,0,20,40,18,130,32,34,2,65,32,144,72,32,80,40,20,84,133,2,138,144,
200 72,20,40,0,80,2,133,2,128,144,72,36,18,9,2,133,2,129,69,68,84,130,65,0,16,1,2,129,77,1,16,18,9,2,128,36,16,40,20,10,
201 5,21,32,88,36,19,64,148,40,9,4,130,65,0,16,1,32,129,64,162,165,82,9,4,130,65,52,208,37,10,2,65,32,144,72,36,16,40,20,84,
202 133,3,4,0,64,4,0,40,80,18,9,4,64,42,1,114,160,23,64,160,81,104,184,106,128,168,10,129,64,162,193,117,193,52,75,202,133,66,149,16,
203 180,64,68,10,46,176,88,45,66,11,80,5,0,88,46,9,2,162,61,10,105,94,217,94,242,148,180,134,176,80,82,85,65,64,21,64,128,4,0,88,
204 42,0,32,82,133,68,121,77,52,166,154,243,94,143,45,42,128,160,170,10,160,64,85,85,34,128,192,4,130,192,16,0,160,136,136,84,123,208,215,188,
205 211,74,107,209,229,164,17,86,69,2,2,145,64,138,170,170,160,170,0,176,194,128,137,41,111,42,26,242,154,247,154,242,189,16,188,0,21,64,128,170,
206 170,64,82,2,144,21,106,16,8,97,64,42,94,133,52,175,52,215,182,247,188,165,46,138,0,160,164,5,32,42,129,20,8,170,170,10,0,1,12,48,
207 68,149,10,242,189,178,154,107,222,105,74,84,68,13,106,73,20,21,85,84,8,160,64,85,0,88,44,21,20,16,37,149,229,121,175,108,211,91,52,166,
208 189,10,152,0,42,129,21,85,85,84,8,10,64,85,0,80,80,5,10,132,1,1,10,134,189,237,182,216,147,91,109,239,122,34,0,2,168,12,10,64,
209 82,2,144,20,128,170,4,80,34,130,128,40,2,224,148,123,222,219,98,79,137,18,60,211,77,42,32,0,16,20,138,66,1,8,4,32,17,85,84,21,
210 65,85,85,85,84,20,33,222,134,182,104,241,227,207,159,108,75,111,41,64,0,128,65,128,132,85,34,169,0,132,1,148,8,160,64,82,0,16,1,65,
211 67,162,61,179,68,143,30,124,120,241,237,154,106,36,20,8,69,25,84,101,82,42,145,84,138,164,0,80,85,82,40,17,65,66,8,146,189,237,182,36,
212 120,241,227,196,137,109,239,44,36,85,33,20,138,164,85,34,144,138,66,42,168,40,1,21,72,69,85,0,208,165,43,102,182,60,120,243,226,71,137,109,
213 239,68,170,169,20,132,82,16,8,64,33,20,132,85,85,80,85,85,85,82,2,172,41,71,188,209,45,143,30,60,248,241,45,182,87,164,0,138,163,1,
214 8,4,85,33,20,132,81,149,72,170,64,34,129,8,4,90,130,2,60,166,182,216,243,226,89,15,30,36,75,205,68,130,169,8,164,34,145,84,138,164,
215 85,34,144,138,164,2,16,8,69,33,21,64,1,10,134,137,108,249,241,226,231,199,159,109,179,81,32,170,50,144,101,82,42,144,20,138,164,82,17,84,
216 128,66,0,202,163,17,72,160,180,67,77,108,121,243,236,153,50,62,60,75,101,42,40,40,196,32,196,81,149,72,170,170,164,5,80,34,169,8,65,136,
217 65,136,66,0,6,134,189,177,227,207,139,159,100,200,120,246,222,244,0,81,136,65,136,49,20,138,164,80,32,42,168,17,84,101,32,202,65,136,66,2,
218 134,143,41,162,91,62,200,251,38,67,207,137,52,210,234,66,12,49,6,33,8,69,34,129,1,84,1,64,21,72,69,24,98,12,50,170,193,10,134,154,
219 216,241,227,217,50,62,124,123,98,94,136,10,163,16,130,136,66,17,72,10,64,85,2,40,17,64,138,4,34,140,66,17,84,2,133,121,173,137,30,200,
220 251,38,67,199,143,53,229,128,16,98,12,49,6,82,42,170,130,168,42,170,168,40,41,20,131,12,65,136,164,8,20,165,109,177,39,207,178,100,124,249,
221 246,219,53,16,21,72,48,196,24,132,85,32,42,168,42,170,128,16,8,66,16,98,12,49,8,170,0,136,87,154,36,120,243,236,153,50,62,60,73,175,
222 124,0,131,16,98,16,132,82,42,170,129,1,85,64,138,163,40,195,40,195,40,202,160,25,74,246,196,137,62,200,248,185,241,231,219,53,229,130,144,132,
223 24,132,34,145,85,85,84,20,128,69,85,34,140,66,12,48,195,16,132,0,161,94,219,99,207,178,100,46,200,249,241,45,154,137,34,144,98,12,50,144,
224 138,170,10,160,69,85,32,17,84,138,65,136,48,195,16,138,161,66,154,104,147,231,217,11,178,100,200,120,150,222,136,160,65,136,65,136,66,41,21,72,
225 160,64,85,0,85,82,16,130,136,48,162,12,66,40,64,175,53,177,227,217,11,139,139,178,62,61,179,94,128,4,24,130,134,32,196,34,144,21,64,128,
226 170,0,0,164,82,16,131,12,65,134,33,21,66,133,52,72,147,226,236,142,197,217,31,30,217,165,73,8,65,134,24,98,16,138,69,5,80,80,80,0,
227 5,82,16,131,12,48,195,12,50,170,232,243,91,30,201,144,184,187,33,115,226,68,188,168,10,65,134,24,81,6,34,145,85,84,1,64,22,160,4,33,
228 6,33,6,32,196,33,20,0,10,87,182,36,123,38,66,231,108,143,159,108,215,234,66,12,48,195,16,138,64,32,42,130,130,130,168,42,169,20,131,16,
229 97,68,20,66,40,80,166,182,36,249,243,177,113,113,118,67,196,154,82,130,144,130,136,40,132,25,84,128,170,160,64,85,0,85,82,16,131,16,131,40,
230 196,34,172,10,87,137,18,61,147,38,66,236,135,159,109,239,64,2,16,131,12,66,17,85,85,65,84,20,20,20,8,170,49,8,49,8,49,20,128,0,
231 136,83,77,18,124,123,38,76,135,159,109,183,151,85,32,196,32,202,69,85,5,5,80,80,80,5,5,82,16,98,16,132,82,2,134,87,189,177,35,207,
232 159,30,124,120,150,205,42,64,8,69,24,138,164,5,80,80,5,0,0,0,5,82,16,132,24,132,34,168,6,133,121,173,182,60,120,241,226,68,182,105,
233 74,144,85,33,8,164,85,85,5,0,88,44,20,1,85,85,85,85,85,84,0,17,16,166,154,219,98,71,137,108,73,175,121,104,170,4,34,145,85,64,
234 0,1,64,2,0,0,160,170,4,85,34,130,128,7,43,222,105,162,68,182,37,179,77,121,83,5,82,41,21,84,20,1,64,0,32,16,0,0,5,5,
235 80,85,5,8,81,10,247,182,217,162,91,52,211,74,82,192,1,84,138,170,10,0,0,0,1,8,4,0,20,1,65,85,65,96,9,71,149,230,154,219,
236 102,154,107,222,137,130,170,170,170,130,128,0,0,0,64,48,128,0,40,0,2,128,6,8,133,43,222,105,166,182,247,154,84,76,20,21,84,20,20,2,
237 0,1,12,2,16,0,5,0,80,5,135,66,149,239,53,230,154,243,74,84,76,20,21,84,20,22,161,0,134,24,64,0,0,0,0,2,1,162,33,94,
238 83,94,243,94,82,149,18,21,0,85,0,0,0,128,66,16,224,16,0,0,0,88,4,40,136,82,189,239,123,222,82,161,120,40,2,130,128,0,4,2,
239 16,193,3,8,0,64,0,2,26,34,20,165,123,202,242,148,168,156,0,20,0,0,2,16,134,28,33,8,64,2,176,12,17,17,10,87,149,229,41,74,
240 148,133,64,0,1,96,1,8,97,248,67,8,4,3,10,81,10,82,188,165,41,81,19,0,0,0,0,128,66,28,48,248,67,0,128,64,52,162,20,165,
241 41,74,133,68,225,0,0,0,0,128,67,15,254,24,64,33,133,40,136,82,148,165,68,68,64,192,32,0,16,8,97,193,2,129,240,132,32,16,232,136,
242 136,82,161,74,148,240,0,0,8,4,33,195,250,112,194,16,135,165,16,168,84,42,34,82,24,0,4,33,8,124,41,248,97,132,48,233,68,68,42,34,
243 34,80,48,128,4,2,16,195,244,254,28,33,224,148,162,21,17,17,41,194,16,132,33,135,255,252,48,195,10,104,136,136,137,68,248,4,32,16,195,15,
244 79,167,12,48,255,68,162,34,37,63,8,66,28,63,250,120,112,195,133,52,162,81,41,76,48,132,33,135,255,167,240,225,240,77,18,137,74,126,16,225,
245 195,254,159,225,195,135,77,41,74,83,134,24,67,15,255,79,248,112,253,52,162,83,160,120,97,240,160,122,127,240,225,255,74,105,79,134,24,120,127,211,
246 255,195,195,79,74,82,159,14,31,255,255,254,31,15,211,77,63,195,15,15,244,255,254,31,244,211,79,252,63,255,255,255,135,255,211,167,15,15,135,253,
247 63,208,60,33,250,104,148,74,127,12,60,63,15,254,31,255,233,165,52,240,225,225,255,195,78,31,15,250,82,148,211,252,56,127,15,255,255,167,79,79,
248 254,24,97,240,225,255,224,158,157,52,211,167,255,240,255,194,16,132,48,79,135,166,137,68,68,68,162,116,135,8,66,16,128,64,33,211,0,0,80,0,
249 8,83,66,161,74,242,148,165,42,34,34,83,225,0,0,0,0,0,0,0,80,80,85,0,80,5,8,122,33,74,242,188,215,154,243,94,242,149,18,129,
250 10,128,42,170,168,40,40,2,170,170,130,168,40,0,0,7,232,136,87,148,211,94,217,166,154,107,222,84,68,192,0,21,85,65,85,85,85,72,170,69,
251 85,85,5,0,128,67,74,21,10,82,189,239,53,230,154,107,222,247,161,83,128,2,170,170,170,170,169,21,85,84,138,160,170,0,0,16,244,162,21,10,
252 87,149,230,188,211,94,107,222,242,149,19,0,0,85,85,85,82,42,145,85,85,85,85,64,0,0,0,2,26,81,10,82,149,239,53,230,154,105,166,189,
253 229,41,104,16,80,85,85,32,42,170,170,145,85,72,170,160,160,0,16,195,232,136,87,149,230,188,211,77,52,211,94,242,161,104,16,5,85,85,85,85,
254 85,85,85,85,85,85,80,0,5,0,0,0,14,136,82,189,230,154,217,173,182,105,166,189,229,42,96,0,170,170,164,85,85,85,85,85,85,85,5,80,
255 85,0,80,80,0,0,209,10,83,77,52,75,98,68,137,109,182,222,242,162,64,21,84,138,69,82,42,170,170,169,21,85,85,84,138,170,170,160,160,0,
256 1,161,74,243,91,18,60,121,241,227,196,182,219,202,152,42,145,72,164,82,41,20,138,69,85,34,170,130,170,170,145,72,164,80,80,134,136,83,77,108,
257 120,243,231,217,31,30,36,75,222,144,2,41,8,66,16,138,66,41,21,72,164,82,42,169,21,85,85,85,85,85,64,0,40,133,123,109,137,62,61,145,
258 243,231,196,137,53,232,128,10,164,33,6,33,20,132,85,82,41,20,138,164,80,85,85,82,42,170,170,168,122,21,239,53,177,227,199,159,62,60,120,246,
259 205,121,112,82,16,132,33,8,69,82,41,20,138,66,16,138,160,160,170,164,82,16,138,170,1,68,71,188,214,196,143,30,124,249,241,227,196,182,105,82,
260 0,164,33,8,66,17,72,170,69,33,20,132,82,42,168,42,129,21,84,138,170,161,10,33,74,107,98,71,159,30,200,249,241,35,205,52,165,130,169,8,
261 66,16,138,164,85,34,145,72,69,33,21,72,164,82,42,145,72,170,170,29,10,243,91,18,60,249,243,236,143,143,18,36,215,162,0,41,8,66,16,132,
262 33,21,85,84,138,164,82,17,72,170,66,41,8,66,16,132,80,93,10,107,98,71,159,100,201,147,38,67,199,182,242,164,20,132,32,196,33,8,170,170,
263 170,170,164,82,41,20,138,69,33,8,66,16,131,17,85,66,133,52,209,227,207,139,178,23,23,100,124,120,147,74,144,33,8,48,195,16,132,34,170,170,
264 170,170,170,130,169,20,131,16,97,134,24,98,17,85,67,41,77,108,120,246,76,133,217,11,178,62,61,179,74,128,4,32,195,12,49,6,34,145,85,84,
265 21,84,21,65,72,66,12,66,12,65,134,33,8,0,20,66,154,104,145,231,217,50,23,100,200,248,246,219,122,85,70,24,97,134,24,98,17,85,85,84,
266 20,20,20,0,20,138,49,6,24,97,134,24,138,161,148,175,53,177,227,207,178,100,46,125,144,241,45,188,168,10,65,134,24,97,134,33,8,170,160,160,
267 10,160,170,170,170,69,82,16,131,12,49,21,84,2,82,189,182,199,159,62,46,201,147,35,227,219,53,233,2,16,97,134,20,66,16,138,170,10,10,10,
268 10,10,170,10,164,32,195,10,24,97,136,69,80,161,74,104,145,39,207,139,178,23,100,200,248,150,205,42,2,144,97,133,12,49,8,69,85,80,80,5,
269 80,80,85,85,33,6,24,97,134,24,98,16,128,0,136,83,91,18,61,147,38,66,226,236,143,143,18,107,210,170,65,134,24,97,136,69,32,42,130,130,
270 168,42,170,144,132,24,97,134,24,97,134,33,20,0,17,30,246,196,143,62,200,92,92,93,145,241,226,91,122,65,72,48,195,12,49,8,170,170,170,10,
271 170,10,170,164,33,8,65,136,40,80,194,136,50,170,130,20,173,182,60,123,33,113,113,118,76,143,143,18,105,82,170,48,195,12,65,136,69,85,5,5,
272 5,85,85,85,85,34,144,131,12,65,134,24,138,171,161,77,52,72,241,236,153,50,100,124,248,150,205,42,65,72,65,136,49,8,69,34,130,168,2,128,
273 0,0,42,169,8,66,12,49,6,33,21,67,66,188,214,196,137,62,124,249,243,227,219,109,229,72,41,8,49,6,33,21,85,64,0,0,0,0,0,1,
274 85,84,138,66,16,132,85,85,13,10,247,182,36,120,241,231,199,137,18,105,165,77,72,66,16,132,34,170,168,0,64,32,1,0,0,85,85,33,20,132,
275 82,2,134,136,87,154,216,145,34,68,143,108,73,175,122,32,2,144,132,82,17,84,20,0,32,16,132,32,10,10,170,170,164,80,80,88,81,10,247,154,
276 219,98,91,18,217,166,188,169,0,85,34,145,85,65,66,1,8,4,32,16,5,0,85,85,85,85,80,130,34,21,239,53,182,219,109,179,77,121,81,2,
277 170,170,69,80,80,0,8,66,24,66,0,160,160,170,10,160,160,1,208,165,123,205,52,214,205,53,239,122,38,10,10,170,170,0,1,8,97,194,0,0,
278 10,160,170,10,10,1,13,16,165,123,205,52,211,77,123,202,136,128,0,10,170,160,0,1,135,134,16,128,2,130,168,40,40,0,4,18,133,43,222,243,
279 94,107,222,242,162,96,0,160,160,160,16,135,135,224,21,5,5,85,5,0,12,18,84,41,94,247,189,239,43,209,19,128,40,2,128,4,56,127,128,64,
280 1,64,0,20,0,2,29,16,165,41,94,242,188,165,42,34,96,0,160,0,1,15,195,240,128,0,2,128,2,132,3,210,84,41,74,242,149,232,84,68,
281 192,0,0,0,33,135,248,112,128,0,0,0,0,4,3,209,16,165,41,74,82,148,168,137,192,0,0,32,24,127,195,128,64,0,0,32,0,16,233,66,
282 161,74,82,148,168,84,166,16,0,0,132,56,127,14,16,0,128,4,2,31,162,33,74,133,41,80,168,148,132,0,32,1,14,31,225,132,32,16,0,128,
283 67,210,136,84,41,80,165,68,74,97,0,0,8,67,15,254,24,4,2,16,135,233,66,162,21,10,136,136,158,1,0,8,66,31,254,24,64,33,8,67,
284 210,136,136,133,68,66,209,56,66,0,16,135,255,225,225,8,67,15,165,40,136,84,68,162,120,64,32,16,225,211,240,240,195,14,31,210,136,137,68,68,
285 208,56,64,33,225,167,255,135,12,56,127,74,81,17,41,78,24,66,24,127,79,225,248,112,225,250,82,136,148,211,134,24,127,255,255,134,28,63,244,162,
286 82,159,195,15,15,79,255,225,195,135,14,154,82,137,167,225,195,255,167,135,240,225,225,254,148,166,154,67,195,225,167,255,252,56,120,127,166,148,167,255,
287 135,255,255,240,248,126,29,58,105,167,240,255,255,255,15,248,127,253,41,167,255,15,255,255,225,254,31,253,58,127,255,255,254,31,255,195,254,157,58,127,
288 195,255,255,135,255,225,255,167,79,167,15,255,225,255,255,255,255,79,79,225,255,252,63,255,255,195,211,211,255,255,255,15,255,250,7,255,244,253,63,135,
289 254,31,255,255,132,63,165,40,148,167,240,195,135,12,56,127,167,255,211,166,154,127,252,56,97,15,15,255,166,154,125,63,252,63,195,15,255,74,105,166,
290 144,248,97,255,135,15,195,253,61,52,233,233,255,195,15,14,16,134,26,120,122,82,136,148,68,68,166,159,132,32,16,0,0,0,252,0,0,20,3,4,
291 162,33,74,87,148,165,66,149,18,148,248,0,0,0,40,2,128,40,42,170,168,40,2,132,52,149,30,87,154,243,77,52,215,189,232,84,225,5,5,85,
292 85,80,80,85,85,34,145,85,65,64,0,3,232,133,43,222,105,173,182,107,102,154,247,149,19,0,5,82,42,170,170,145,84,132,82,41,21,85,65,96,
293 1,232,133,41,74,243,94,105,173,154,217,166,189,229,68,224,160,164,85,34,144,138,69,34,145,72,170,170,10,1,0,244,68,66,148,175,121,166,154,217,
294 166,154,107,222,84,76,0,21,72,170,69,34,144,138,69,34,169,20,20,0,0,2,16,165,16,165,123,205,123,109,154,219,102,154,247,149,19,5,5,34,
295 169,21,72,164,82,41,8,69,34,170,128,0,66,28,18,84,43,222,105,173,154,217,173,154,107,202,84,68,8,40,41,21,84,138,69,82,41,8,170,69,
296 85,80,0,0,0,0,13,17,30,247,154,219,109,137,109,182,205,52,175,68,193,64,138,164,82,42,145,84,138,69,34,145,85,84,21,84,1,64,2,20,
297 41,94,246,219,18,60,72,241,34,91,53,239,68,10,170,145,72,69,34,169,20,138,69,82,41,20,138,66,42,170,170,128,0,65,10,87,182,216,241,231,
298 217,31,30,60,73,175,42,64,20,138,66,16,138,66,16,138,66,17,72,164,85,85,33,20,132,34,170,168,6,133,41,173,143,62,124,93,147,38,67,199,
299 154,242,193,84,131,16,132,33,8,66,17,72,69,33,8,69,34,145,72,69,85,34,170,168,0,80,175,108,72,243,236,133,217,11,159,30,36,215,150,10,
300 164,32,196,24,132,33,8,164,33,8,66,17,72,170,170,164,33,8,164,34,128,5,16,175,52,72,147,231,217,50,100,200,120,150,205,42,85,72,66,12,
301 66,16,132,33,20,132,32,196,33,8,170,170,170,65,136,66,16,138,1,68,123,205,18,60,249,246,66,236,143,159,30,217,165,74,170,140,66,12,66,17,
302 72,66,16,132,32,196,33,20,138,170,66,41,8,69,34,128,104,133,53,177,35,217,50,100,201,147,33,226,77,122,32,42,144,131,16,132,34,144,132,33,
303 8,65,136,65,148,132,33,8,66,41,8,69,32,0,80,175,108,72,243,231,197,217,11,178,62,60,73,165,44,21,72,65,136,65,148,132,34,144,132,32,
304 196,24,132,33,8,66,16,132,24,98,17,85,116,121,162,79,178,100,118,46,118,201,145,241,38,189,32,164,32,196,24,132,33,21,72,164,33,8,66,16,
305 132,33,8,66,12,65,136,48,196,34,174,83,91,30,125,145,217,217,217,217,219,33,226,77,42,2,144,131,12,48,196,33,8,69,34,144,138,66,41,20,
306 132,24,131,10,24,80,194,136,66,0,2,33,173,137,62,200,92,244,236,236,237,145,241,230,189,0,8,48,194,134,24,97,136,66,42,145,85,72,170,170,
307 65,136,48,195,12,48,195,12,50,168,4,165,123,99,207,178,23,59,59,59,23,100,124,73,175,64,33,6,20,40,97,67,16,98,41,21,84,138,170,10,
308 170,164,32,195,12,40,80,161,134,85,0,66,148,209,34,79,139,178,59,59,59,100,200,251,102,190,4,32,194,133,12,40,97,136,66,42,170,170,170,145,
309 84,138,66,41,6,24,97,134,25,85,66,133,53,177,39,217,11,157,157,157,139,178,30,36,210,160,16,130,134,20,40,97,134,34,145,85,85,85,84,138,
310 170,170,69,24,97,66,133,12,49,8,160,136,83,91,30,125,145,217,217,217,216,187,35,226,77,42,1,8,40,97,66,134,24,98,17,72,170,170,170,170,
311 170,170,65,134,24,97,67,10,24,98,42,130,33,77,18,60,251,35,179,179,179,177,118,71,196,154,84,5,24,97,133,12,48,196,24,138,69,85,82,42,
312 145,84,131,12,48,195,12,48,161,134,34,168,101,121,162,71,178,100,118,118,122,46,46,200,123,102,150,4,32,161,134,20,49,6,34,144,138,164,85,34,
313 145,72,66,12,65,134,20,40,80,161,136,69,90,21,182,199,178,23,59,61,59,61,59,100,124,75,101,64,82,12,48,161,67,16,98,41,21,85,72,164,
314 33,8,69,33,6,32,195,10,20,40,97,134,34,133,30,104,147,236,133,207,79,79,79,78,217,31,108,210,192,132,24,80,161,134,24,98,16,132,82,41,
315 21,85,85,84,131,16,80,194,154,10,20,48,196,34,229,53,177,44,153,30,158,158,158,158,139,178,30,219,210,66,12,40,80,161,67,12,66,17,85,84,
316 138,170,160,170,164,24,97,134,20,40,97,66,134,24,128,178,189,177,44,133,207,79,68,34,19,209,118,67,205,122,1,8,40,80,166,131,10,24,132,34,
317 145,65,85,84,20,1,72,65,133,12,41,160,161,66,133,16,139,149,237,143,100,46,122,33,61,16,157,157,159,30,107,208,8,48,161,66,133,10,24,98,
318 16,138,170,170,160,160,10,170,65,134,20,48,161,133,10,24,98,42,172,165,108,73,246,71,103,167,162,19,211,182,67,219,122,72,65,66,133,10,20,48,
319 196,33,21,85,85,85,85,85,85,72,66,12,48,161,66,154,10,24,101,90,60,209,231,217,29,136,68,34,19,211,177,113,237,154,146,16,97,66,133,10,
320 24,98,16,138,164,85,85,34,130,169,8,65,134,24,80,195,12,48,195,17,65,17,230,137,62,200,236,236,244,244,236,92,248,246,222,128,164,24,97,66,
321 134,24,132,34,145,85,85,85,65,85,84,132,24,97,133,12,48,196,33,21,65,17,230,137,30,200,92,92,236,236,93,144,241,38,149,1,72,65,133,16,
322 98,16,138,170,170,170,170,170,10,170,164,24,97,134,24,98,16,138,160,8,134,154,36,249,241,118,66,226,231,207,137,53,229,129,8,65,134,32,196,82,
323 42,170,168,40,2,128,2,129,8,48,195,12,48,196,82,0,4,165,53,182,199,159,62,200,249,241,226,91,52,169,5,33,6,32,202,66,42,130,130,128,
324 40,0,42,170,169,20,132,82,41,21,84,2,133,121,173,137,30,124,121,241,226,68,154,242,165,84,132,33,8,66,42,130,128,40,0,0,0,40,42,169,
325 20,132,82,40,40,0,34,35,205,108,72,145,227,199,137,109,179,74,136,0,164,33,20,138,69,5,5,0,0,0,0,0,0,85,85,85,85,32,40,0,
326 80,165,52,214,196,137,30,36,75,102,189,233,170,169,8,69,34,168,40,40,0,0,66,0,0,10,10,170,170,160,160,1,66,149,230,182,216,145,45,182,
327 217,175,42,64,21,72,164,85,80,80,5,0,0,128,4,32,10,160,170,10,160,0,28,165,123,205,109,182,219,108,211,74,84,64,5,82,42,145,65,65,
328 64,2,0,16,128,64,1,64,20,21,64,0,57,81,239,53,179,91,108,211,94,82,164,0,20,138,170,10,10,0,1,0,132,32,0,0,10,10,0,0,
329 0,26,33,74,107,205,52,214,222,247,148,188,21,85,84,20,20,0,2,1,8,112,0,0,0,80,5,0,14,136,143,123,205,121,166,189,229,42,36,0,
330 21,65,65,64,0,0,33,8,67,8,0,0,2,128,0,7,68,66,189,239,53,239,123,202,133,192,1,65,84,1,64,32,24,97,132,33,0,128,40,0,
331 66,8,136,82,189,239,123,222,82,162,36,0,1,64,20,0,2,1,14,28,33,0,128,0,64,33,209,16,175,121,94,242,189,17,56,2,128,40,0,4,
332 2,24,112,240,132,32,0,16,14,136,133,43,202,242,148,165,79,0,0,0,0,0,8,67,15,135,8,64,32,16,250,21,10,87,148,165,42,39,128,0,
333 0,0,0,4,48,255,135,8,64,32,31,68,41,74,82,161,74,148,194,0,0,0,16,132,60,63,194,16,128,67,10,81,10,133,41,74,136,137,224,0,
334 0,1,0,134,31,255,132,2,16,194,148,68,66,149,10,136,137,194,0,16,0,134,31,254,28,33,8,67,210,133,68,42,21,17,62,1,0,0,132,48,
335 254,159,134,16,132,62,137,42,33,81,17,52,12,0,32,16,195,135,79,240,194,16,195,165,17,17,10,136,148,240,8,4,2,24,127,167,248,97,8,125,
336 40,136,136,136,148,240,132,33,12,63,255,225,134,28,41,165,17,17,40,159,132,33,134,30,26,127,225,135,15,165,40,137,68,255,12,48,248,127,254,24,
337 97,253,41,68,68,167,240,135,15,135,255,248,97,195,166,148,162,83,76,56,124,63,255,195,134,28,62,154,37,18,154,97,195,15,255,255,135,12,63,244,
338 162,82,159,195,195,255,255,195,12,56,116,233,74,38,159,14,31,255,255,225,135,15,244,166,148,255,240,255,255,252,48,225,255,74,83,79,248,127,255,255,
339 195,15,15,167,77,62,152,116,255,225,255,195,135,15,211,166,159,255,255,255,255,15,15,254,158,159,255,211,255,195,225,225,255,244,250,127,255,255,255,240,
340 255,135,211,233,254,9,253,63,248,124,60,63,253,62,159,15,167,255,255,240,255,193,63,211,255,255,211,252,63,15,135,254,159,79,225,211,255,255,248,127,
341 255,253,63,255,255,255,252,63,15,253,63,79,255,255,255,240,255,255,254,159,255,167,240,255,135,255,15,250,127,79,255,255,252,63,255,255,255,79,250,127,
342 195,252,63,254,31,233,255,211,255,255,248,127,255,255,255,79,233,255,195,248,127,225,255,167,255,79,244,240,255,195,255,255,255,253,62,159,255,15,195,252,
343 63,253,63,253,62,159,225,252,63,255,255,255,233,244,255,248,126,31,135,255,233,255,211,233,255,15,248,127,255,255,254,158,159,255,195,240,252,63,255,233,
344 253,61,63,225,255,135,255,255,255,233,233,255,240,255,15,240,255,254,159,211,211,252,63,248,127,255,255,254,158,159,255,15,248,127,135,255,244,253,61,63,
345 195,255,195,255,255,255,233,233,255,240,255,135,248,127,255,211,211,211,255,15,252,63,255,255,255,78,159,255,135,252,63,15,255,250,125,62,159,248,127,195,
346 255,14,159,255,167,167,255,240,254,31,195,255,250,127,79,211,252,63,240,255,255,255,250,125,63,254,31,225,252,63,255,79,233,255,255,255,195,255,255,255,
347 211,211,255,240,255,15,240,255,255,167,167,167,254,31,225,255,255,195,233,250,116,250,67,248,126,31,195,255,255,167,167,167,255,135,225,254,31,79,195,167,
348 233,211,233,225,248,120,126,31,255,253,62,158,159,255,15,135,240,255,244,255,233,211,255,254,30,31,15,255,253,63,79,167,255,195,225,252,63,250,127,244,
349 244,255,255,15,135,225,255,254,159,211,233,255,195,240,255,195,250,127,253,61,63,255,15,135,255,135,254,159,244,250,127,195,240,255,255,255,255,167,233,255,
350 225,240,255,193,63,255,254,159,211,252,62,31,225,244,255,255,167,250,127,248,124,63,15,250,127,253,63,167,252,63,15,225,255,167,255,79,244,255,248,126,
351 31,135,255,211,253,63,79,255,15,135,225,255,250,127,167,244,255,254,30,31,135,255,244,254,159,211,255,195,195,240,255,250,127,244,254,159,255,135,195,240,
352 255,233,255,211,253,63,240,248,127,15,254,159,253,63,211,255,225,240,255,135,250,127,244,255,211,240,255,15,255,255,255,167,255,79,225,255,135,255,255,255,
353 211,255,255,248,127,255,255,255,211,255,255,254,31,255,255,255,250,127,255,252,63,255,255,255,244,255,255,255,15,255,255,255,253,63,255,254,31,255,255,255,
354 167,255,255,255,195,255,255,255,253,63,255,255,15,255,255,255,211,255,255,252,63,255,232,31,255,250,127,255,240,255,255,244,15,255,244,240,240,255,166,148,
355 211,233,135,225,135,15,195,250,7,240,225,250,105,166,158,159,233,255,195,254,30,28,48,195,167,211,233,254,157,63,255,211,225,225,195,255,15,254,159,255,
356 211,255,135,79,211,248,127,211,248,112,135,255,233,135,250,125,63,240,79,77,63,135,14,28,56,83,165,63,135,225,167,135,255,253,40,148,77,48,225,225,
357 15,255,167,160,124,33,8,64,0,2,1,8,116,68,66,161,81,10,133,68,68,74,127,134,24,4,0,63,194,0,0,0,1,0,128,2,168,0,116,162,
358 34,34,34,33,81,10,82,149,229,41,74,84,68,194,0,0,0,16,0,128,40,2,128,40,0,0,4,56,97,132,32,0,16,209,17,16,168,82,149,229,
359 53,239,123,202,82,149,48,130,130,128,40,0,0,0,0,2,130,130,130,128,0,0,0,6,148,74,66,24,105,165,17,10,133,41,74,82,188,165,41,74,
360 84,68,224,10,10,160,160,0,1,8,0,40,42,130,168,2,128,0,116,162,74,148,167,135,162,33,74,133,43,202,87,149,229,41,81,48,0,80,85,0,
361 0,0,132,1,65,85,85,84,20,2,16,254,157,41,68,162,81,16,168,84,41,74,133,41,74,84,42,34,80,32,10,10,10,1,0,128,2,128,42,170,
362 170,130,128,4,3,74,34,83,211,209,40,133,66,148,165,41,74,133,41,74,84,42,38,0,0,160,160,170,0,0,0,0,10,10,10,10,10,1,8,126,
363 148,233,250,34,34,20,165,41,74,242,188,175,41,74,84,68,192,21,65,85,85,85,64,0,1,64,20,20,0,0,2,31,165,41,8,67,135,162,34,20,
364 165,43,222,107,205,52,215,189,229,42,64,21,72,164,33,20,138,170,160,160,160,160,0,0,16,254,148,78,1,0,0,8,6,20,68,41,94,105,166,182,
365 216,150,219,52,215,189,16,1,72,65,134,24,98,12,66,42,170,128,40,0,4,0,63,210,136,148,134,0,0,0,10,1,208,165,121,166,182,36,72,145,
366 45,137,52,210,151,5,32,196,20,48,194,134,24,132,82,2,168,40,0,0,6,20,162,34,21,17,41,240,8,0,40,40,0,104,87,188,211,68,182,60,
367 72,145,45,154,242,224,164,32,195,10,24,97,134,24,132,33,21,65,64,33,253,40,84,68,66,162,83,8,0,0,2,168,40,6,82,148,211,91,18,60,
368 72,241,45,154,242,164,20,132,24,130,134,24,97,136,66,41,21,84,1,96,1,133,40,136,133,68,68,68,167,192,0,0,1,64,52,66,189,237,182,216,
369 145,34,68,154,105,75,0,82,12,48,194,134,24,98,16,138,170,160,0,0,1,12,58,81,18,136,136,137,78,144,130,130,170,128,81,30,246,219,18,60,
370 72,241,45,154,242,193,84,131,12,40,97,134,24,138,64,80,5,0,80,0,8,97,166,136,148,68,248,67,0,128,0,104,82,189,182,219,30,36,120,145,
371 38,188,169,82,16,97,133,10,24,80,196,33,21,65,64,32,16,255,255,192,33,255,8,6,136,87,154,216,241,227,207,159,30,37,183,165,72,48,161,77,
372 26,52,104,40,80,196,34,128,0,67,135,250,34,34,112,134,0,0,16,0,85,80,12,175,120,145,39,217,11,139,178,100,124,73,165,128,195,52,118,208,
373 205,219,182,141,26,12,48,202,170,1,244,68,162,34,81,17,41,211,0,128,0,2,170,145,85,66,82,182,217,246,71,103,103,103,108,143,137,53,1,70,
374 104,209,217,153,153,155,183,110,197,10,24,132,80,0,250,34,34,34,34,21,17,19,64,192,2,24,0,0,40,44,16,165,109,177,236,153,11,139,139,159,
375 30,217,80,8,48,167,110,221,153,153,187,118,208,80,195,17,72,10,16,210,136,84,66,161,80,168,148,252,41,224,10,10,170,161,41,77,18,60,251,35,
376 177,118,71,199,154,244,2,12,209,163,179,51,55,102,109,26,52,24,98,17,64,0,52,162,33,80,165,42,21,18,148,240,134,156,0,1,64,2,136,246,
377 196,143,62,46,201,147,33,45,189,1,70,20,41,219,179,55,110,221,138,104,48,195,17,85,64,61,17,10,133,121,74,82,162,39,132,0,61,3,0,0,
378 0,161,94,104,145,236,153,11,178,62,37,178,160,40,205,5,59,118,102,237,219,70,130,133,12,69,32,40,7,209,16,168,82,148,165,42,34,34,66,1,
379 15,194,10,1,161,94,219,99,199,178,62,124,72,151,150,4,25,160,167,109,29,180,104,208,97,134,85,80,0,195,166,136,136,84,68,45,41,15,165,18,
380 144,0,5,13,10,243,91,30,60,248,241,237,154,84,5,32,194,154,52,104,208,80,161,68,33,20,20,48,233,165,18,136,84,68,68,240,0,0,254,16,
381 232,133,121,162,68,143,30,60,123,102,149,42,65,134,104,209,163,65,66,133,12,50,170,128,127,210,136,136,136,136,136,148,8,66,20,254,16,229,41,77,
382 108,72,145,35,219,53,232,128,164,24,97,77,5,10,20,48,196,34,168,4,62,157,40,136,136,136,136,148,225,195,225,8,116,71,148,214,219,109,182,205,
383 121,82,10,65,136,40,97,133,16,98,17,84,22,31,166,148,74,34,34,37,19,8,66,31,195,209,10,87,154,107,102,182,247,189,53,82,16,131,12,49,
384 6,34,170,168,0,7,253,41,68,68,68,68,68,240,135,195,135,162,33,74,243,77,121,175,121,104,0,164,33,8,66,16,132,85,0,0,135,233,233,74,
385 34,81,17,52,14,31,134,30,136,133,43,205,123,222,82,166,10,170,69,33,20,138,10,0,16,248,126,154,81,40,148,167,15,254,26,81,16,165,43,222,
386 87,162,36,0,21,84,138,170,170,0,176,135,254,26,105,74,37,41,255,225,253,17,10,87,148,175,66,240,5,5,82,42,130,128,0,127,255,13,52,210,
387 154,127,240,240,165,37,71,148,165,41,83,128,2,170,170,130,128,0,127,79,15,15,167,79,233,233,255,74,33,74,82,149,17,56,2,130,170,130,128,0,
388 7,255,195,250,105,77,63,255,250,81,16,168,84,42,39,0,5,5,5,5,0,135,233,211,135,233,233,255,252,63,209,17,16,165,68,68,225,0,80,0,
389 80,8,67,211,254,31,211,167,195,255,233,165,17,10,133,68,79,0,0,0,80,0,8,67,255,255,244,211,250,127,255,165,17,17,17,62,1,0,0,0,
390 0,195,233,233,135,233,244,255,255,195,211,68,162,34,105,8,66,0,16,135,254,156,62,31,233,255,211,255,165,18,136,148,225,8,4,2,16,195,211,248,
391 127,244,253,63,233,254,154,82,159,8,64,33,12,61,58,127,240,254,159,10,127,255,166,148,167,240,194,16,195,233,233,225,225,240,255,211,211,211,211,74,
392 83,225,132,33,8,97,233,244,240,255,233,255,250,127,78,157,56,97,132,33,15,233,166,159,255,240,248,127,250,125,52,211,248,97,195,255,211,255,15,135,
393 240,250,122,116,211,78,159,135,8,97,135,255,211,255,255,255,211,250,126,156,60,56,97,225,167,166,159,255,255,135,255,255,211,211,240,254,31,250,127,240,
394 252,63,254,159,167,167,167,195,225,195,195,254,159,255,255,255,244,253,63,248,120,112,255,233,211,233,135,255,135,255,255,211,255,255,15,255,79,255,225,255,
395 15,250,122,116,255,252,56,120,127,211,250,127,255,225,255,244,244,252,62,30,31,250,116,233,255,135,248,124,63,244,244,255,255,240,255,167,255,240,255,248,
396 127,79,78,159,255,15,15,15,244,255,254,159,255,195,255,79,255,225,252,62,159,79,167,195,255,240,248,127,211,233,255,255,240,250,127,248,127,255,255,253,
397 58,127,195,252,63,15,79,255,254,159,210,31,195,250,127,225,255,255,244,250,124,63,255,195,225,254,159,79,255,255,255,255,248,127,255,255,254,157,63,225,
398 254,31,255,255,255,167,255,225,255,211,255,248,127,255,167,255,255,255,135,195,254,158,159,255,255,255,248,127,255,255,255,253,63,255,255,195,255,255,255,167,
399 255,248,127,244,255,195,255,255,79,255,255,255,248,124,62,159,250,127,255,255,15,255,254,159,254,31,253,63,255,255,248,127,255,253,63,255,225,255,255,255,
400 167,255,255,255,255,255,225,252,63,79,244,255,255,255,240,255,255,211,254,31,250,127,255,255,225,255,255,250,127,255,225,255,255,255,233,255,255,255,130,127,
401 255,135,240,255,167,233,253,60,63,252,63,255,244,255,252,63,255,211,255,255,225,255,255,211,255,255,15,255,255,253,63,255,255,195,233,255,255,15,240,254,
402 159,211,255,255,255,15,255,167,255,252,63,255,254,159,255,248,127,254,159,255,248,127,255,255,250,127,255,255,135,211,255,225,255,255,255,233,255,255,255,195,
403 255,167,255,255,195,255,255,211,255,135,255,211,255,255,225,255,255,255,253,63,255,255,255,255,240,255,255,255,167,255,255,255,15,255,233,255,255,225,255,255,
404 255,255,255,244,255,255,255,135,255,195,211,254,159,255,255,255,255,252,63,255,255,255,167,255,255,248,127,244,255,255,195,255,255,255,244,255,255,255,255,255,
405 135,255,255,255,244,255,255,252,63,211,255,135,255,255,211,252,63,250,127,240,255,233,255,255,248,127,255,255,255,253,63,255,255,255,135,255,255,255,233,255,
406 255,255,4,15,211,248,127,255,167,255,225,255,255,255,255,167,253,56,127,135,255,255,255,255,233,255,255,255,255,135,255,255,255,211,255,255,225,255,79,254,
407 31,254,159,255,15,255,253,63,225,255,167,255,255,195,255,255,255,255,244,255,255,255,254,31,255,255,255,255,79,255,252,63,253,60,63,250,127,255,240,255,
408 255,255,255,211,250,7,255,4,130,120,39,130,5,3,224,144,79,64,160,39,255,193,56,32,32,36,30,117,48,14,166,40,196,109,210,103,152,2,25,25,
409 157,34,49,167,9,224,75,21,217,132,75,13,197,212,114,118,234,59,96,139,185,218,8,3,220,195,8,133,116,132,186,24,216,130,238,131,27,61,134,197,
410 96,29,89,135,7,59,139,132,93,156,102,228,123,153,25,163,51,132,186,26,154,226,17,0,112,207,57,56,15,2,51,128,230,196,29,184,79,92,198,110,
411 70,220,192,34,43,152,123,144,201,156,33,112,142,217,231,38,97,224,240,204,57,177,7,110,19,214,115,27,144,75,152,130,32,57,141,114,59,115,29,186,
412 7,110,115,155,48,240,192,96,157,24,131,129,4,66,206,99,114,9,115,43,144,28,198,136,134,110,99,183,64,237,174,115,16,24,12,38,97,201,206,99,
413 112,136,92,173,66,32,151,48,198,10,28,70,152,46,220,199,172,209,99,56,228,32,136,204,38,11,13,136,99,102,142,92,198,66,32,247,49,12,25,196,
414 107,145,160,180,46,205,117,103,28,196,19,195,9,192,195,115,152,220,35,151,43,83,144,75,148,80,136,130,209,172,215,108,225,119,67,171,156,230,193,48,
415 176,24,167,70,17,212,64,28,181,218,156,39,220,173,28,133,115,35,52,103,48,246,107,83,56,114,225,49,179,216,174,6,1,212,64,57,181,220,89,162,
416 238,87,102,11,197,162,136,130,156,199,220,142,46,83,152,130,117,98,29,24,44,243,8,128,112,103,11,29,2,238,102,142,71,139,72,34,10,115,31,102,
417 181,51,135,34,8,225,158,195,98,136,198,23,1,201,206,44,112,139,181,204,221,6,185,129,154,51,152,248,130,212,231,61,102,14,25,231,70,24,140,97,
418 96,156,24,142,34,9,219,57,219,145,236,235,53,92,167,220,142,46,113,200,130,56,98,56,24,172,35,171,48,224,196,22,8,34,236,230,142,131,92,192,
419 34,10,114,143,116,25,53,207,68,1,99,16,232,224,96,29,88,39,54,32,176,64,59,107,153,51,77,114,131,52,142,86,220,38,77,115,177,0,112,207,
420 57,48,196,102,3,128,228,231,28,58,14,220,206,220,141,185,128,193,35,148,123,53,219,148,237,154,234,207,57,48,76,44,6,99,21,174,59,102,158,179,
421 140,217,162,92,164,102,220,207,114,25,185,69,221,3,182,185,204,64,17,152,12,83,163,0,198,32,142,92,238,46,134,78,86,142,68,22,138,228,104,229,
422 100,225,22,49,7,46,3,27,8,232,116,97,14,24,34,23,59,139,160,251,148,83,53,25,197,116,10,107,139,184,69,140,243,131,48,194,120,112,28,152,
423 67,177,4,114,196,50,102,159,114,168,136,142,98,152,38,98,208,133,194,56,115,156,216,39,131,195,128,228,196,28,56,68,44,230,55,32,145,104,134,8,
424 11,77,136,134,110,83,183,64,225,136,115,112,48,15,14,3,155,156,112,225,59,114,153,51,91,56,149,154,162,211,110,70,55,40,229,194,234,231,58,51,
425 24,2,48,128,115,115,186,179,69,217,205,25,162,92,160,113,220,167,196,71,109,113,203,160,118,196,58,48,88,12,6,9,205,206,117,112,158,185,152,217,
426 163,197,161,140,21,22,155,17,12,197,161,11,52,112,215,57,8,12,38,19,48,228,215,49,186,15,69,163,38,104,145,105,68,64,56,155,48,76,156,167,
427 174,17,195,92,228,204,103,176,156,7,38,112,225,194,122,230,99,48,91,56,144,193,7,49,243,140,205,158,115,114,56,176,24,162,9,212,234,204,97,185,
428 199,14,19,211,137,169,200,246,176,142,65,157,38,220,141,71,16,133,154,117,103,48,196,6,123,9,194,114,103,14,4,67,177,104,204,193,109,210,1,110,
429 51,164,125,200,212,230,29,56,78,172,67,155,5,128,192,102,28,154,231,86,104,133,210,99,17,30,233,41,130,51,164,60,193,50,115,14,132,65,219,61,
430 130,225,48,157,89,174,6,16,176,193,28,179,140,204,17,46,145,12,17,143,55,185,24,221,33,119,65,213,204,114,16,25,236,65,0,232,206,58,185,4,
431 39,19,25,130,36,226,83,141,78,33,38,11,183,48,133,200,234,215,57,8,39,134,123,48,232,215,48,186,7,78,103,17,16,251,164,208,227,3,205,238,
432 67,39,72,93,154,59,22,142,78,134,3,16,64,102,49,12,102,9,209,206,100,35,196,46,85,48,6,156,79,17,237,26,195,230,8,237,210,29,56,88,
433 76,231,3,21,156,120,16,71,78,97,219,144,92,226,118,96,149,210,41,130,208,90,23,114,56,179,142,14,19,171,17,192,193,98,24,92,39,6,112,177,
434 200,46,45,52,114,60,90,1,16,97,105,182,107,136,180,33,16,14,173,115,147,129,132,192,16,14,78,113,219,144,114,206,118,35,207,179,158,34,145,202,
435 46,113,187,115,14,153,166,54,185,209,130,196,97,48,78,110,99,27,132,236,226,106,17,13,107,20,193,24,226,18,228,50,115,30,179,71,108,230,24,130,
436 120,103,184,88,172,225,195,144,114,45,49,152,35,221,37,56,193,172,108,193,50,107,4,34,33,213,204,115,16,88,140,71,3,13,202,120,114,30,156,77,
437 71,24,147,136,4,84,90,62,34,133,51,142,7,24,177,158,224,116,24,88,66,11,21,174,117,112,142,93,39,23,35,103,152,161,17,90,199,136,134,71,
438 16,187,52,118,229,57,184,79,12,246,99,21,174,99,116,14,156,172,98,33,241,104,135,28,90,52,68,104,45,11,186,5,142,81,208,130,35,49,24,167,
439 71,57,132,64,16,185,133,142,19,238,147,177,17,14,34,156,109,28,199,166,11,83,156,232,96,152,207,14,17,4,240,99,114,29,25,206,38,11,38,177,
440 161,130,167,156,68,50,60,217,51,71,14,99,128,130,120,115,176,92,14,113,25,154,112,115,56,136,135,206,33,71,26,28,70,152,34,133,163,177,16,88,
441 206,57,56,79,12,246,99,21,174,99,116,14,78,38,161,16,214,176,80,136,49,230,246,107,27,88,118,232,49,179,152,98,9,224,240,225,96,179,197,135,
442 25,201,206,208,192,11,185,144,71,161,196,36,193,99,56,133,217,166,17,104,230,204,98,49,24,44,55,48,140,228,61,56,156,76,17,39,153,5,185,29,
443 38,206,51,33,104,66,34,14,217,204,87,65,225,132,225,112,53,204,110,65,208,180,212,96,143,60,198,56,193,172,120,136,198,214,11,186,14,167,17,205,
444 152,196,98,49,88,108,227,11,144,116,229,50,17,226,238,82,152,6,218,236,132,113,25,195,161,110,44,107,157,4,22,3,93,192,116,115,48,4,19,214,
445 177,213,154,217,230,208,68,83,204,209,16,200,226,59,114,14,25,199,71,9,225,128,32,48,88,134,49,16,224,229,50,22,227,220,196,22,243,136,209,16,
446 204,90,23,102,142,28,167,6,99,61,206,197,57,185,79,2,1,219,164,44,116,54,233,12,113,163,152,72,138,25,206,115,17,230,103,134,97,130,56,58,
447 184,89,140,241,195,160,66,45,11,29,15,48,46,221,2,143,59,161,169,210,100,32,142,28,167,6,97,225,132,193,98,177,12,108,211,131,56,200,193,100,
448 230,81,110,130,208,147,141,163,148,66,228,117,115,156,153,135,134,19,128,228,206,58,136,7,103,16,177,194,107,88,209,154,51,88,246,107,24,180,122,205,
449 117,103,177,93,6,51,27,53,152,35,49,152,39,38,32,163,4,251,149,92,138,113,21,194,212,113,31,102,29,92,163,150,43,1,136,195,57,53,204,98,
450 9,235,57,141,154,61,202,67,5,28,173,152,34,153,194,22,107,139,16,232,32,29,79,12,22,27,60,198,225,16,185,154,157,13,139,66,153,170,113,21,
451 194,100,230,30,32,14,25,195,151,1,225,132,197,97,179,221,93,7,6,123,67,4,245,158,130,220,214,32,145,16,102,185,216,130,44,107,142,88,167,134,
452 121,200,224,231,48,184,15,92,174,34,0,151,48,167,69,202,246,107,70,184,187,161,197,158,115,16,14,162,51,5,134,192,29,136,35,167,57,147,52,123,
453 56,142,75,152,174,131,39,51,33,0,118,206,29,49,79,12,35,161,205,206,117,102,30,179,154,153,163,217,202,96,189,174,60,227,35,16,114,96,177,176,
454 142,78,19,8,140,224,58,49,14,172,195,215,48,176,65,108,226,104,232,83,136,174,131,39,43,39,11,171,92,230,204,48,158,24,44,54,16,237,194,58,
455 115,153,57,15,185,84,68,185,91,114,52,114,157,186,29,92,227,166,97,225,132,197,57,181,206,172,195,183,43,139,133,177,104,103,64,57,158,205,104,206,
456 61,102,181,48,142,142,17,193,140,64,98,136,206,174,129,203,156,201,208,37,204,65,4,5,164,112,153,57,143,136,3,183,56,229,130,35,48,24,103,38,
457 16,224,64,16,185,216,217,163,218,234,228,181,205,114,59,115,157,136,46,44,243,131,4,234,35,49,78,76,35,27,48,245,174,212,32,182,229,24,65,7,
458 41,68,19,54,185,241,0,88,196,29,56,12,102,22,41,208,240,44,112,142,152,78,220,140,152,128,205,71,59,220,45,26,231,217,142,172,65,11,12,194,
459 192,58,28,24,70,54,9,219,157,140,64,18,215,35,133,26,239,112,138,115,139,136,45,76,33,211,4,112,35,49,78,71,135,86,8,229,136,100,32,137,
460 115,138,112,217,200,32,180,103,31,102,11,24,130,22,25,140,240,115,57,158,7,14,1,11,60,200,65,100,207,86,107,217,237,179,72,207,23,16,88,216,
461 67,150,41,140,70,57,28,24,3,134,41,219,17,169,130,37,174,40,64,181,208,64,20,231,62,32,53,48,135,44,81,217,132,232,114,17,157,88,34,22,
462 17,155,48,251,16,130,9,92,229,16,69,49,15,179,28,88,71,172,83,25,224,230,112,60,14,24,167,108,246,166,96,151,56,194,10,57,222,225,25,158,
463 46,225,50,60,28,25,142,167,86,25,200,194,59,112,30,179,218,153,141,181,198,102,3,93,25,142,216,131,216,46,44,33,11,20,198,97,58,28,196,97,
464 219,4,245,128,100,32,15,103,144,65,43,156,209,4,83,60,248,128,212,194,28,177,71,6,19,145,192,240,59,98,158,177,24,217,141,181,198,16,1,174,
465 86,99,70,33,246,11,81,224,114,224,29,152,216,167,67,11,83,48,66,120,51,16,71,177,8,32,92,229,102,59,115,143,96,139,25,227,147,161,140,70,
466 57,28,15,3,183,1,219,60,201,152,61,136,65,5,28,230,136,2,153,236,153,140,108,1,203,20,118,117,58,28,196,103,87,1,235,60,201,152,219,16,
467 102,101,206,86,11,70,32,247,3,83,8,66,116,28,29,78,71,3,11,171,4,66,192,118,32,31,96,43,132,172,39,136,34,153,231,216,45,76,35,214,
468 25,140,70,57,142,143,3,182,25,219,61,141,130,37,136,48,129,98,20,64,20,207,100,193,99,60,14,88,110,167,83,145,192,234,234,197,16,176,12,153,
469 130,89,228,16,44,242,176,69,51,199,184,26,152,7,167,65,193,212,224,58,17,157,88,98,236,3,38,8,150,17,4,2,176,158,32,145,128,46,193,51,
470 17,132,44,55,83,25,192,116,97,117,58,29,176,24,216,173,179,198,112,89,232,193,20,194,18,224,99,60,8,78,131,179,25,204,224,117,22,48,207,79,
471 6,108,17,44,2,48,81,128,86,8,204,33,238,3,35,193,217,209,212,234,112,29,29,71,103,67,182,1,147,20,75,8,83,5,25,229,96,140,192,30,
472 193,50,48,136,88,110,38,51,145,192,112,44,97,158,158,12,156,2,88,66,152,40,196,71,0,166,16,150,43,27,0,236,232,234,117,29,28,14,174,172,
473 51,179,193,155,128,123,0,102,98,48,10,193,25,128,125,192,100,35,30,157,29,76,103,1,209,212,88,116,23,17,140,152,173,176,6,112,88,72,224,20,
474 192,30,195,99,17,142,206,142,163,131,129,192,198,226,195,61,48,187,112,15,60,43,129,24,5,112,10,60,9,97,177,136,194,231,39,83,168,232,114,117,
475 22,28,133,196,99,54,24,150,1,28,8,192,43,128,99,192,246,41,145,132,244,228,44,28,28,7,35,129,97,208,92,194,102,195,18,120,35,21,24,5,
476 97,140,120,18,195,99,48,139,156,197,134,49,208,132,112,44,57,11,152,93,176,196,152,85,192,130,51,220,3,24,71,176,204,142,167,103,55,81,216,228,
477 66,99,22,28,197,196,99,51,163,103,130,48,231,130,176,197,24,68,176,204,142,167,103,49,96,236,116,57,28,53,28,153,29,93,176,219,17,149,139,17,
478 138,197,24,70,18,116,50,58,139,156,221,71,99,145,9,141,196,230,200,194,236,232,104,140,70,26,8,197,97,144,194,61,134,102,99,61,57,184,186,142,
479 132,35,134,163,152,185,132,204,232,217,224,140,57,225,24,99,30,4,157,12,142,162,231,49,96,236,114,33,29,184,156,133,204,46,216,109,152,72,195,67,
480 9,88,99,24,68,157,12,206,167,103,7,17,216,228,66,56,106,56,50,58,153,157,13,48,144,232,2,49,78,130,140,35,206,70,70,51,179,155,139,168,
481 232,114,59,99,57,139,152,221,157,4,136,202,116,136,197,58,10,48,137,57,49,152,197,199,78,35,177,201,232,225,168,230,200,234,236,232,105,133,88,115,
482 9,88,99,24,71,156,140,204,103,103,7,17,216,232,244,118,212,115,100,117,118,114,108,194,67,164,194,135,65,70,17,39,35,35,24,184,233,196,118,57,
483 16,142,218,142,98,230,54,135,70,206,170,195,67,11,206,131,24,68,156,140,140,98,227,167,17,216,228,244,112,212,112,100,117,118,114,52,194,67,164,194,
484 83,160,199,81,39,35,49,192,185,193,197,212,114,122,234,212,112,100,56,118,114,108,194,167,36,48,161,208,99,171,103,35,51,27,35,131,136,236,66,33,
485 29,184,156,25,24,221,156,196,152,84,232,135,82,157,8,117,30,114,51,28,11,156,26,157,68,39,163,182,163,129,243,27,179,155,102,17,142,147,10,28,
486 136,117,108,230,236,198,46,58,106,117,16,136,93,90,142,2,230,55,103,38,206,164,57,33,213,14,131,29,68,156,204,199,12,142,14,46,162,19,215,86,
487 161,211,35,27,179,153,167,82,28,144,194,83,144,198,49,39,55,99,182,71,6,49,96,132,66,234,198,58,100,56,118,115,108,234,49,201,12,40,114,24,
488 234,217,204,204,112,200,114,212,44,61,61,117,99,29,31,29,187,57,182,99,33,201,14,165,57,144,198,36,224,236,118,200,116,212,44,61,61,117,99,28,
489 178,28,59,56,54,117,33,205,12,115,144,198,54,206,14,199,108,135,44,98,195,211,215,22,49,211,33,219,179,155,99,130,28,208,198,135,2,14,13,56,
490 59,28,31,28,177,186,158,157,139,24,199,39,199,110,206,13,152,200,115,65,194,28,200,56,108,224,208,118,124,114,100,44,59,61,113,106,28,178,29,187,
491 56,54,99,33,192,166,57,204,134,51,78,13,7,99,199,76,98,195,179,183,22,161,203,33,219,179,128,145,193,14,101,28,78,106,56,108,116,208,118,124,
492 114,198,44,59,59,113,106,16,178,29,187,29,54,56,24,224,83,26,28,8,56,108,116,209,212,120,233,141,196,236,237,197,140,114,125,213,216,232,72,224,
493 135,4,28,33,193,71,6,142,154,58,143,28,177,184,139,157,184,177,136,89,14,221,142,155,29,140,112,40,226,112,81,217,167,6,142,167,199,38,66,195,
494 179,183,22,49,11,33,219,177,211,99,130,14,138,99,65,210,142,13,29,52,117,30,57,50,22,29,157,184,153,8,79,186,180,29,54,59,32,232,163,132,
495 56,16,118,104,232,83,168,241,9,147,136,185,219,83,25,233,241,99,177,203,99,177,135,69,28,78,4,29,154,57,20,234,60,66,102,226,46,122,212,198,
496 33,100,234,208,114,216,236,135,4,28,32,233,71,6,142,154,58,143,16,153,56,139,139,181,49,136,79,186,180,28,182,59,32,232,163,185,193,71,102,142,
497 69,58,143,16,153,184,139,157,184,153,30,178,117,104,57,53,212,97,209,71,17,210,142,205,28,180,117,30,33,51,113,100,118,212,100,122,124,88,208,114,
498 36,118,67,129,71,113,210,142,205,28,138,117,30,122,102,226,200,237,196,200,244,248,177,216,229,177,217,7,69,28,32,233,71,102,142,154,11,7,136,76,
499 154,133,197,218,140,143,79,139,26,14,77,117,32,233,7,113,210,142,205,28,180,22,9,16,153,53,50,59,106,99,61,62,44,104,33,109,212,131,164,117,
500 142,149,212,209,200,161,96,241,9,147,83,35,182,166,51,211,226,199,99,147,93,72,57,40,238,58,81,217,163,145,66,193,231,166,110,34,226,236,102,71,
501 163,220,90,8,91,117,32,229,29,99,162,58,154,57,104,44,30,122,102,226,46,46,212,100,122,124,88,208,66,219,169,7,40,235,28,171,169,163,150,142,
502 35,207,76,218,133,197,216,204,143,71,184,180,16,154,234,162,20,117,65,10,186,154,33,20,44,30,118,102,212,46,201,140,200,244,123,139,65,11,110,164,
503 28,149,214,57,87,83,68,34,156,68,158,153,181,11,178,99,50,61,30,226,208,66,107,170,136,81,213,4,42,44,120,132,83,136,147,211,54,161,118,76,
504 102,103,163,220,90,8,91,117,81,202,58,160,133,93,77,16,180,113,30,118,102,212,200,93,168,204,236,123,139,65,9,162,194,14,81,213,4,42,44,52,
505 66,41,196,73,233,155,27,38,76,102,103,99,220,69,30,154,44,32,230,44,65,9,5,134,136,90,56,143,59,51,99,100,201,140,204,236,123,136,163,211,
506 69,138,33,65,98,8,85,197,226,17,78,34,78,204,216,217,50,106,51,59,30,226,40,244,209,98,158,160,177,4,42,44,52,244,83,80,147,183,108,108,
507 153,49,153,157,143,113,20,122,104,177,68,40,44,136,84,88,105,232,167,17,39,102,102,71,217,49,153,157,143,113,20,122,104,177,68,40,44,65,9,28,
508 77,61,20,212,36,236,205,141,147,38,51,51,177,45,77,15,77,22,41,234,11,16,66,162,195,79,69,53,9,59,51,50,62,201,141,216,184,246,161,71,
509 102,184,169,234,11,16,66,162,195,79,69,53,9,23,118,198,200,249,145,153,216,150,161,71,175,113,83,212,22,33,234,184,154,118,41,168,73,217,153,145,
510 246,76,110,197,199,181,10,59,53,196,130,27,140,66,70,167,158,138,106,18,46,236,200,251,35,35,49,113,237,66,142,205,113,83,212,113,136,85,197,231,
511 162,154,132,139,187,50,62,124,201,216,184,150,161,71,175,113,83,212,113,158,171,139,207,69,53,9,23,118,198,200,249,145,152,184,246,161,71,175,106,83,
512 212,113,158,171,83,206,198,106,18,46,236,200,249,243,39,108,132,177,138,59,53,197,79,109,83,213,113,52,236,83,27,98,238,204,143,178,50,118,200,75,
513 24,163,179,90,136,122,142,40,118,173,79,59,25,168,75,38,140,103,207,153,59,23,18,212,40,236,214,162,30,163,138,29,131,83,206,198,106,18,46,236,
514 200,249,243,39,108,132,177,138,59,123,82,157,163,84,236,26,158,46,51,27,98,237,12,135,159,51,118,46,217,144,161,115,90,148,237,26,167,106,212,243,
515 177,154,132,178,104,100,60,249,147,177,118,216,198,23,123,25,14,209,169,14,213,169,231,99,49,182,46,208,200,249,243,38,140,132,177,138,23,53,169,78,
516 209,197,14,213,169,226,227,49,182,46,236,204,121,243,55,108,132,177,138,23,53,169,78,209,170,118,13,79,23,35,80,150,77,12,135,159,51,118,200,75,
517 24,163,183,177,144,237,26,167,96,212,241,113,152,196,178,104,100,60,249,155,182,66,76,133,11,154,212,162,232,199,23,6,167,139,140,198,219,38,134,99,
518 199,153,180,62,36,200,80,187,216,212,92,173,83,176,106,120,185,24,219,100,208,204,120,247,110,207,137,50,20,46,246,53,23,70,56,184,53,60,92,102,
519 54,217,52,51,30,61,219,182,77,153,12,200,214,53,23,70,56,184,49,189,145,24,219,100,208,204,73,243,55,108,155,50,25,147,216,212,93,24,231,106,
520 198,246,68,99,109,147,67,49,227,221,180,62,217,152,161,119,177,168,186,49,197,193,141,236,134,50,108,248,163,49,35,221,180,62,217,144,204,158,100,172,
521 144,202,46,12,101,23,24,201,182,77,12,199,137,118,208,251,102,67,50,123,26,139,163,28,92,24,222,200,99,51,89,52,51,30,61,219,67,237,153,12,
522 46,246,48,100,134,81,117,50,43,34,25,54,125,163,177,35,204,218,31,108,200,102,79,50,86,72,198,140,129,141,236,136,100,217,246,142,196,143,118,208,
523 251,102,99,31,121,146,139,204,172,128,200,172,136,100,105,241,78,196,137,104,208,123,102,99,50,121,146,178,67,40,186,153,149,145,12,155,62,209,216,145,
524 238,218,15,108,204,102,69,50,86,72,101,100,6,69,100,49,153,167,197,59,18,37,216,161,237,153,140,201,230,74,47,50,67,224,100,243,228,50,108,120,
525 167,98,68,180,104,61,179,49,153,60,201,89,33,149,144,25,60,249,12,205,62,41,216,145,45,26,31,52,204,135,222,100,172,144,202,201,76,138,200,99,
526 51,79,180,118,36,75,70,135,205,118,49,247,153,171,36,50,178,3,39,159,33,153,167,197,59,18,37,216,161,237,153,140,125,230,106,125,12,144,248,25,
527 60,249,12,205,30,41,216,145,45,5,15,53,216,199,222,102,172,166,118,74,102,83,228,51,52,120,167,98,68,180,104,61,179,50,31,41,154,178,67,43,
528 32,50,121,242,25,154,60,83,70,196,180,20,60,215,99,31,121,154,159,67,36,62,6,69,62,71,102,143,20,236,72,150,130,135,154,236,99,239,51,86,
529 83,59,32,50,120,242,59,52,120,167,98,91,104,40,121,166,100,30,243,53,62,134,115,224,102,83,228,118,104,241,77,27,18,208,80,243,93,144,249,76,
530 192,252,206,124,12,202,124,134,102,143,20,209,177,45,5,9,53,217,7,188,205,79,161,156,248,59,40,245,51,52,120,206,196,182,40,80,147,93,144,123,
531 204,212,250,25,207,171,180,62,71,102,137,25,163,98,90,10,30,107,178,15,121,154,159,67,57,240,51,41,242,59,120,241,77,27,18,208,80,147,93,144,
532 123,204,212,250,25,207,131,180,62,71,102,143,25,163,109,138,20,37,183,100,30,87,106,61,12,231,192,204,163,200,236,209,35,52,109,182,131,9,53,217,
533 7,188,204,7,163,185,240,51,41,242,59,52,72,205,27,108,80,161,38,187,32,242,187,81,232,103,62,6,101,30,174,205,18,51,70,219,20,40,121,174,
534 200,60,174,192,122,25,160,240,118,81,42,236,209,35,52,109,182,131,9,123,66,9,123,181,30,142,227,193,217,71,145,163,196,140,40,209,45,6,18,246,
535 132,30,87,106,61,29,199,131,180,30,174,205,18,51,70,219,20,40,73,173,8,60,174,192,122,59,143,7,101,30,70,143,18,48,163,91,20,40,73,174,
536 200,60,174,212,122,59,143,7,104,61,93,154,36,102,141,182,40,80,147,90,16,75,221,128,251,184,240,104,131,200,209,226,70,20,107,98,134,108,214,132,
537 18,86,138,61,29,199,131,178,143,35,67,68,140,209,182,197,12,217,173,8,36,173,20,125,218,9,6,136,60,141,30,36,97,70,182,40,102,205,104,65,
538 37,104,163,209,220,120,59,40,242,52,120,145,133,26,216,161,155,53,161,4,149,162,143,180,143,7,101,30,70,134,182,65,70,182,40,102,205,104,65,37,
539 104,163,237,34,65,161,68,145,163,196,140,40,211,69,12,37,237,20,73,90,40,251,72,240,118,81,42,209,226,70,20,217,162,134,18,246,138,36,174,192,
540 74,59,65,32,209,4,171,71,137,24,81,173,138,25,179,90,40,146,187,1,246,145,32,208,162,72,41,237,140,40,214,197,12,217,173,8,36,173,0,74,
541 59,143,6,136,37,90,60,72,194,141,108,80,205,188,81,4,149,160,9,71,104,36,26,32,149,104,241,35,10,53,177,67,54,241,68,18,86,128,37,26,
542 68,131,66,137,86,143,108,130,141,52,97,155,120,162,54,86,128,38,210,38,209,4,171,71,182,65,70,154,48,205,188,81,4,149,160,9,138,137,6,133,
543 18,173,30,217,5,26,104,162,26,107,69,108,173,0,77,164,77,162,9,81,69,108,130,141,108,81,13,53,162,182,81,74,37,26,68,131,66,182,162,138,
544 217,5,26,104,195,54,241,74,217,90,0,148,105,18,13,10,218,138,121,164,25,230,140,67,94,41,91,43,64,19,105,18,2,144,74,138,43,100,25,237,
545 138,35,111,20,65,37,104,2,109,17,176,20,141,168,167,154,65,70,154,48,205,188,81,4,160,160,19,21,110,208,173,168,162,182,65,158,104,196,53,227,
546 17,178,138,6,226,173,218,21,181,20,86,200,40,211,70,33,175,20,173,148,80,54,141,34,64,82,54,162,158,105,6,121,163,16,215,138,86,202,41,68,
547 197,68,128,164,109,69,60,210,12,243,70,33,175,20,173,160,160,109,5,91,1,72,216,10,43,100,20,105,163,12,219,197,43,101,20,13,163,68,108,5,
548 35,96,40,173,144,81,166,140,51,101,24,141,148,80,55,21,108,5,20,208,20,86,200,51,205,24,134,188,82,182,130,129,180,21,108,5,21,181,20,243,
549 72,51,205,24,134,188,82,182,81,64,220,85,176,20,86,212,83,205,32,207,52,98,26,241,148,210,138,6,226,173,197,35,106,40,173,144,103,154,49,13,
550 120,165,108,162,129,184,171,96,50,26,2,138,217,6,121,163,16,215,138,86,202,40,27,138,182,2,138,104,10,43,100,25,230,140,67,94,50,154,81,64,
551 220,105,177,72,218,138,121,164,25,239,33,13,40,202,105,69,3,104,42,216,12,134,128,162,182,65,158,104,196,53,227,41,165,20,13,198,155,20,141,168,
552 197,52,131,60,209,136,105,70,86,208,96,53,5,91,1,144,208,24,166,144,103,154,49,13,120,165,109,6,3,80,85,176,25,13,1,138,105,6,121,163,
553 16,215,140,166,160,192,106,10,182,3,33,160,41,230,144,103,154,49,13,41,8,218,12,6,160,171,96,50,26,3,20,210,17,239,33,30,241,148,212,24,
554 13,65,86,192,100,53,70,41,170,51,222,66,26,82,41,168,48,26,130,173,128,200,104,12,83,72,71,188,132,123,198,83,80,96,53,5,77,140,134,168,
555 197,53,70,123,200,67,74,69,53,6,6,227,77,1,144,208,24,166,144,143,121,8,247,140,166,160,192,106,10,67,64,100,52,6,43,212,103,188,132,52,
556 163,41,165,24,13,141,54,50,26,164,67,84,133,121,21,239,25,77,66,1,177,166,197,33,160,49,77,33,30,82,43,202,69,121,70,3,99,77,140,134,
557 169,10,245,33,94,69,121,72,166,160,192,106,13,52,6,67,64,98,189,72,87,145,94,82,41,168,48,26,131,77,1,144,208,24,175,82,60,170,71,148,
558 138,106,12,6,160,211,64,100,53,72,87,169,10,242,43,202,69,121,70,3,99,77,140,134,169,10,245,33,94,69,121,72,166,160,192,106,13,52,8,143,
559 2,33,170,51,222,66,60,164,83,80,96,53,6,190,50,60,6,43,212,143,42,145,229,32,61,8,6,201,124,100,52,6,43,212,143,121,8,242,145,77,
560 65,175,65,166,128,200,104,12,87,169,10,242,43,202,69,121,70,3,100,190,50,26,164,43,212,133,121,21,229,34,188,163,1,178,95,25,13,1,138,245,
561 35,202,164,121,72,175,40,192,108,151,201,52,6,43,212,133,121,21,229,34,154,132,7,160,211,64,147,84,133,122,144,175,34,148,164,7,161,1,232,52,
562 216,200,240,33,94,164,121,84,143,41,1,232,64,122,13,52,8,143,1,138,245,33,94,69,121,72,175,40,192,108,151,198,71,129,10,245,33,94,69,121,
563 72,175,40,192,108,151,201,52,6,43,212,133,121,21,229,34,154,132,7,160,215,201,53,72,87,169,10,242,43,202,69,121,70,3,100,190,50,26,164,43,
564 212,133,122,145,229,34,188,163,95,37,242,77,82,21,234,66,188,138,244,85,122,18,249,47,145,30,4,71,170,148,170,71,148,138,244,32,27,37,241,145,
565 224,66,148,8,82,170,188,164,87,148,128,249,47,145,30,4,71,169,10,245,35,202,64,41,70,190,75,228,188,8,87,169,10,245,35,202,69,122,16,30,
566 132,188,8,143,2,35,192,133,121,21,229,32,61,8,15,66,94,4,71,129,17,234,66,188,138,242,145,94,132,7,161,47,2,35,192,136,240,33,94,69,
567 121,72,5,41,1,242,95,37,224,66,148,8,82,170,188,164,2,148,128,249,47,145,30,4,71,170,148,170,165,41,0,168,160,249,47,146,240,33,74,4,
568 41,85,94,138,175,66,95,37,242,94,4,41,64,133,42,171,209,64,165,32,62,160,249,17,224,68,120,16,165,85,41,72,15,66,3,228,188,8,143,2,
569 35,213,74,85,82,148,128,244,32,61,9,124,136,80,84,122,169,74,170,82,144,30,132,7,201,124,136,89,17,234,165,42,169,74,64,42,18,249,47,5,
570 188,8,82,129,10,85,87,162,171,208,151,201,124,151,130,161,65,74,85,82,148,128,84,37,242,95,37,224,168,245,82,149,84,165,32,61,8,15,168,62,
571 68,40,42,20,8,82,170,148,164,7,161,1,245,150,68,120,16,165,5,41,85,74,82,3,208,128,250,203,34,20,21,30,170,133,80,42,40,21,9,124,
572 151,200,133,5,66,130,161,85,74,85,87,161,37,66,94,10,133,5,71,170,148,170,165,41,0,168,160,249,47,145,10,10,133,2,20,170,165,42,171,208,
573 146,161,47,145,11,34,61,84,165,85,41,72,5,69,2,161,37,173,224,66,148,21,10,160,84,80,42,40,62,68,44,136,80,84,40,41,81,64,168,160,
574 84,36,168,75,193,80,160,168,80,84,42,129,81,64,168,160,249,47,5,66,130,161,65,80,170,5,69,2,162,131,235,44,136,80,84,40,42,21,64,168,
575 160,84,36,181,150,183,130,161,65,80,170,5,69,7,214,90,203,89,100,66,130,161,84,10,138,5,66,75,89,107,120,42,20,21,10,160,84,80,42,40,
576 62,178,200,133,5,66,130,161,84,10,138,5,69,7,214,90,202,10,133,5,42,40,21,20,10,138,5,173,224,168,80,84,40,42,21,64,168,160,84,80,
577 125,101,5,66,130,161,84,16,170,8,85,2,161,37,69,150,178,213,10,160,133,80,68,89,107,44,151,130,203,84,64,82,160,2,21,64,168,160,84,89,
578 100,66,130,161,65,74,138,5,69,2,162,129,80,151,130,161,65,80,160,168,85,2,162,129,107,45,101,173,224,168,80,82,160,41,81,65,245,150,183,130,
579 161,65,81,1,74,128,165,69,2,162,203,89,106,137,89,65,81,1,81,20,11,89,107,45,101,169,74,10,82,168,21,0,10,139,45,111,0,148,1,16,
580 20,168,160,84,80,68,80,45,101,172,160,8,85,4,42,130,34,130,33,41,80,44,136,149,68,0,42,0,21,0,10,129,44,37,170,22,165,72,33,84,
581 10,138,8,138,5,5,148,22,80,84,64,4,64,4,64,2,162,203,89,107,40,42,32,42,21,65,17,65,17,64,181,148,2,88,33,66,133,0,42,0,
582 21,0,10,139,40,4,160,168,128,168,128,168,138,5,69,2,194,80,9,106,133,0,66,168,21,20,17,20,18,74,73,40,44,160,165,64,4,42,202,139,
583 42,42,22,23,128,33,64,16,170,5,128,34,45,43,40,4,160,8,128,5,64,2,162,129,81,64,176,2,214,128,168,138,168,138,169,80,74,129,107,44,
584 16,160,5,72,20,160,5,40,3,225,42,4,181,66,130,162,0,80,21,17,64,176,162,44,176,148,21,16,21,16,1,32,169,80,74,130,86,80,84,64,
585 4,64,2,160,81,2,88,95,4,124,10,88,21,0,17,20,18,160,80,0,40,4,160,8,128,5,64,2,160,1,107,64,90,1,40,11,69,13,85,32,
586 8,129,44,37,170,20,1,10,20,46,242,209,229,4,124,41,92,23,5,160,2,64,11,9,97,74,208,22,138,180,80,68,90,66,136,180,168,34,168,85,
587 82,0,136,18,166,106,35,205,41,94,105,80,175,130,34,172,8,176,32,65,65,1,65,0,40,0,136,0,136,20,64,165,105,90,87,5,72,42,84,53,
588 84,5,164,16,169,43,202,134,154,82,154,244,71,148,37,5,10,144,36,80,5,93,85,42,9,0,44,37,132,186,22,5,64,4,168,107,74,208,23,85,
589 10,174,160,136,18,150,83,94,87,154,242,189,229,148,160,26,146,4,80,2,4,9,130,210,168,128,8,129,66,133,16,41,9,97,64,4,128,37,66,10,
590 176,85,130,130,65,11,66,188,165,52,210,148,215,162,61,2,128,161,82,0,1,2,171,168,96,9,10,114,232,154,32,83,4,69,224,8,11,170,173,72,
591 21,92,37,74,61,232,83,94,87,154,84,43,210,136,1,5,36,8,176,85,64,80,214,128,8,128,5,64,149,1,10,128,136,129,74,224,180,85,130,172,
592 8,176,32,107,46,87,162,60,210,188,211,74,87,189,37,64,8,17,65,72,0,170,21,13,65,33,72,81,2,93,11,161,66,136,0,136,180,0,10,170,
593 130,145,65,72,21,10,111,42,20,215,189,237,154,87,154,84,41,97,169,1,72,170,4,88,42,234,26,210,18,132,168,146,150,133,46,88,80,0,32,176,
594 85,0,82,2,145,65,72,16,4,42,35,222,247,182,217,175,108,215,189,229,74,85,64,132,32,16,101,5,32,2,168,84,18,0,93,10,146,149,17,30,
595 148,46,136,0,149,8,42,212,101,2,12,170,66,40,40,82,134,188,166,137,108,214,196,137,123,102,189,10,80,0,82,12,164,20,50,144,98,42,145,64,
596 20,16,1,11,66,149,16,175,163,209,16,165,161,82,136,11,5,85,2,12,170,49,20,132,34,170,175,71,148,173,182,107,98,68,182,219,109,188,175,40,
597 4,8,69,32,162,16,97,149,70,34,130,168,64,17,40,82,202,242,161,94,136,87,162,21,16,17,1,96,69,0,34,130,140,160,49,8,164,25,65,65,
598 17,10,105,175,52,123,109,182,61,183,154,107,209,16,20,20,98,16,130,134,33,6,34,169,20,0,1,52,68,66,189,10,87,161,74,84,71,162,33,122,
599 1,1,72,50,128,196,85,24,132,81,149,85,67,68,53,239,109,182,219,30,37,179,91,108,165,42,0,84,132,33,5,12,65,134,34,144,128,170,184,80,
600 180,121,80,175,122,21,229,66,149,37,46,144,8,17,84,131,12,163,12,66,16,101,82,40,66,82,149,237,182,107,99,196,182,36,73,175,53,233,212,138,
601 163,12,66,10,25,72,66,42,145,96,0,137,66,149,10,242,148,175,42,61,17,10,148,72,106,69,82,17,84,98,41,8,69,82,40,0,2,36,166,189,
602 237,137,109,177,226,91,53,179,74,133,69,0,32,196,32,195,12,163,12,69,33,20,21,125,11,41,74,82,188,168,242,149,10,84,68,44,18,160,160,50,
603 170,140,164,32,196,81,136,64,34,251,222,83,68,137,108,72,241,45,137,108,215,148,168,0,4,33,8,48,162,16,80,202,65,136,170,171,0,162,74,82,
604 163,202,82,188,165,41,74,136,82,229,128,85,85,70,25,72,48,196,81,136,170,69,0,9,74,87,182,219,98,71,137,18,60,121,166,154,244,192,138,65,
605 133,12,65,66,134,32,195,42,144,128,10,9,162,21,10,242,148,166,148,175,121,80,175,162,36,53,80,81,136,164,24,132,32,162,40,196,32,17,116,67,
606 77,52,72,241,226,79,159,30,37,182,205,66,160,17,84,97,67,12,41,160,196,20,49,8,49,20,8,24,33,81,30,242,149,239,41,94,244,43,222,82,
607 188,186,2,168,16,132,32,194,136,48,194,136,48,195,41,21,122,26,243,68,143,18,60,251,33,227,199,137,53,239,74,130,138,24,97,154,10,20,40,80,
608 195,12,49,20,138,0,0,136,136,242,149,239,121,94,105,74,247,148,165,42,34,36,0,8,66,16,97,136,48,195,16,97,134,82,12,160,0,133,123,219,
609 18,36,75,35,227,207,159,30,107,102,151,144,131,16,83,65,66,133,52,24,97,67,16,131,40,40,105,41,74,87,154,87,188,210,189,239,41,94,84,68,
610 192,20,132,82,16,138,48,195,16,97,136,66,17,84,128,136,143,108,214,199,143,30,60,251,33,45,137,53,229,74,170,140,40,80,194,154,10,24,80,195,
611 16,97,149,84,3,161,80,175,121,94,107,202,247,188,165,52,168,82,250,170,168,196,33,6,33,8,48,202,48,196,82,17,64,47,123,219,18,60,73,243,
612 231,207,137,30,36,215,149,0,0,97,134,24,80,161,66,133,10,24,97,134,82,16,0,2,137,41,74,87,154,87,188,210,189,239,41,74,84,164,0,20,
613 132,81,134,33,6,24,131,12,49,8,49,21,86,143,43,109,137,30,61,145,243,231,207,137,53,183,151,82,16,97,133,10,20,40,80,161,134,20,66,16,
614 96,80,90,101,41,74,247,149,230,188,165,121,81,229,68,42,39,5,82,12,49,8,48,196,32,196,82,16,128,164,209,30,107,102,143,30,36,121,241,34,
615 91,109,229,68,5,85,24,97,136,48,162,12,48,202,65,136,10,171,133,17,10,242,163,222,82,188,165,41,74,84,41,116,0,80,85,85,33,8,66,12,
616 164,33,21,72,161,4,43,222,107,98,91,18,60,75,109,182,105,74,144,5,33,20,97,134,33,6,33,20,101,85,80,0,4,208,165,66,149,232,87,149,
617 10,82,161,94,146,160,64,21,85,72,170,66,17,72,69,85,32,2,130,34,20,211,77,52,75,109,137,109,183,189,233,192,138,164,24,138,49,8,164,34,
618 170,168,2,130,65,16,168,143,42,60,165,71,149,16,168,136,158,10,0,10,160,164,85,34,170,169,1,65,122,60,175,52,214,205,109,182,222,107,209,18,
619 10,10,66,41,8,69,82,42,170,128,2,240,68,73,74,136,242,162,20,178,149,17,19,72,0,0,40,42,170,170,170,170,168,40,4,40,82,148,215,154,
620 246,205,53,239,122,33,96,21,85,82,17,85,72,160,170,0,161,134,148,42,34,20,168,133,68,42,34,33,116,194,10,160,170,160,170,160,170,0,11,133,
621 17,17,229,123,205,123,222,247,161,81,3,80,80,82,2,170,168,42,128,44,33,77,17,37,44,168,90,21,40,154,36,40,0,21,0,85,0,80,80,0,
622 0,0,242,149,10,242,189,239,121,74,84,74,0,5,84,20,21,65,84,0,0,32,30,137,68,73,81,17,17,40,137,78,144,192,0,1,64,21,64,0,
623 2,1,130,34,74,82,148,175,41,74,82,162,97,0,80,5,0,5,0,0,0,128,126,148,74,34,34,37,17,52,211,240,10,128,0,0,0,0,64,48,
624 166,136,133,66,148,165,42,21,19,192,0,0,1,64,0,2,1,12,18,9,77,18,136,148,77,19,78,144,132,2,0,0,0,16,0,135,10,37,10,136,
625 82,149,10,90,80,48,0,0,0,0,0,128,97,195,78,148,165,17,52,77,52,248,6,161,0,0,0,192,56,38,136,136,136,84,66,162,34,120,66,0,
626 0,1,0,132,56,125,52,165,41,68,211,167,195,0,128,6,1,128,112,160,81,40,136,136,84,68,77,33,128,4,2,16,8,67,240,78,148,166,137,211,
627 79,72,112,8,6,1,0,225,250,81,40,84,68,68,211,192,33,0,128,66,24,127,211,74,105,74,116,255,14,1,128,66,24,97,166,148,68,74,34,37,
628 60,33,0,192,48,195,255,233,77,52,233,208,63,132,33,132,48,225,72,37,41,74,34,81,62,24,96,24,7,15,254,157,58,83,211,255,12,33,134,28,
629 63,210,148,74,82,159,195,0,195,135,240,79,233,211,167,255,248,112,225,195,255,77,41,74,122,67,132,48,195,255,253,58,126,159,255,15,195,135,135,244,
630 210,154,83,252,48,225,195,255,233,250,127,79,255,15,15,135,255,211,74,116,240,225,195,130,67,244,10,127,79,233,4,252,18,31,135,135,255,167,77,63,
631 240,225,255,130,96,159,253,63,167,252,18,28,60,63,255,77,52,255,225,195,255,255,254,159,255,208,63,195,240,255,160,39,78,159,240,225,255,255,255,79,
632 255,255,254,31,135,254,157,58,127,135,135,255,255,255,79,254,129,76,18,31,135,135,254,158,158,159,15,135,255,255,253,63,255,255,252,63,135,233,244,244,
633 240,252,63,255,255,254,159,255,208,63,240,240,255,167,211,255,254,31,255,255,254,159,255,255,240,254,9,10,127,79,255,240,255,255,255,244,255,254,129,255,
634 135,240,253,62,159,255,240,255,255,255,244,254,159,240,252,63,135,232,9,233,255,254,20,15,255,255,250,127,244,13,3,248,127,4,134,159,211,255,252,63,
635 255,255,253,1,63,253,33,252,63,240,164,41,250,127,255,194,129,255,255,250,2,127,255,255,195,255,255,211,255,252,63,255,255,253,63,255,255,225,255,255,
636 253,63,255,225,64,255,255,250,127,244,10,67,252,16,63,252,19,253,63,255,193,33,255,255,244,255,255,255,135,255,255,244,255,255,225,255,255,255,79,253,
637 48,72,127,15,254,9,255,211,255,255,225,255,255,233,255,164,40,31,225,255,255,253,63,255,240,64,255,255,253,63,244,248,127,15,252,19,255,211,255,255,
638 248,127,255,250,127,164,18,31,248,127,130,66,159,244,255,255,252,63,255,253,63,250,7,252,63,255,255,167,255,255,240,255,255,255,79,255,255,135,255,255,
639 250,127,255,252,63,255,255,167,255,255,135,255,255,211,255,255,224,129,255,255,250,2,127,255,252,63,255,255,211,255,254,9,13,3,255,255,211,255,255,225,
640 255,255,254,144,79,255,248,82,20,15,255,250,127,255,255,15,255,255,167,255,255,194,129,255,255,254,159,255,255,15,255,255,160,39,255,255,194,129,255,255,
641 250,2,127,255,224,129,255,255,244,255,255,130,67,255,255,253,63,255,255,4,15,255,255,167,255,255,135,255,255,211,255,255,254,31,255,254,159,255,195,255,
642 255,253,63,255,255,252,63,255,255,211,255,254,31,255,254,159,255,255,254,31,255,255,211,255,240,255,255,79,255,255,254,31,255,255,255,64,167,255,195,255,
643 254,128,159,255,255,240,164,48
644 };
645 #endif /* UMPAH_H_ */
#define CONSTTABLE_STORAGE(X)
+
1 // generated by Mozzi/extras/python/audio2huff.py
+
2 
+
3 #ifndef UMPAH_H_
+
4 #define UMPAH_H_
+
5 
+
6 #include <Arduino.h>
+
7 
+
8 #include "mozzi_pgmspace.h"
+
9 
+
10 
+
11 #define UMPAH_SAMPLERATE 16384
+
12 #define UMPAH_SAMPLE_BITS 8
+
13 CONSTTABLE_STORAGE(int16_t) UMPAH_HUFFMAN[280] = {
+
14 277,169,67,0,1,64,46,28,25,7,4,0,-25,0,-26,0,-13,16,7,0,-31,4,0,-36,0,-39,7,0,20,4,0,-38,0,-35,0,-6,16,0,5,13,
+
15 10,0,13,7,0,31,4,0,39,0,-34,0,-10,16,0,4,13,10,4,0,16,0,-14,4,0,-15,0,15,0,-7,100,4,0,3,0,-2,94,52,49,43,
+
16 10,7,4,0,-37,0,36,0,-32,0,19,31,28,22,19,0,-43,16,0,44,13,10,4,0,46,0,-45,4,0,-46,0,-62,0,45,0,41,4,0,40,0,
+
17 37,0,17,4,0,9,0,8,0,-4,40,22,13,7,0,-16,4,0,32,0,-33,4,0,-18,0,-17,7,4,0,-19,0,18,0,-11,16,13,10,0,21,7,
+
18 4,0,-40,0,-41,0,35,0,-12,0,-8,106,4,0,-1,0,2,100,55,34,19,10,4,0,22,0,-23,4,0,23,0,-20,7,4,0,25,0,-21,0,10,
+
19 13,0,-9,10,4,0,-24,0,-29,4,0,28,0,24,19,16,0,6,13,0,11,10,7,0,34,4,0,38,0,-42,0,27,0,-5,43,40,19,7,4,0,
+
20 -22,0,-27,0,12,10,4,0,-30,0,29,4,0,30,0,26,19,16,13,0,-28,10,0,33,7,4,0,42,0,-44,0,43,0,14,0,7,0,-3,0,0
+
21 };
+
22 uint32_t const UMPAH_SOUNDDATA_BITS = 196860L;
+
23 CONSTTABLE_STORAGE(byte) UMPAH_SOUNDDATA[] = {
+
24 210,20,130,2,84,176,64,164,16,40,8,29,42,245,148,33,72,34,0,32,104,132,68,82,192,164,66,170,80,100,40,32,2,104,165,134,133,104,242,140,
+
25 60,194,228,96,20,116,96,79,41,213,219,49,158,86,27,9,182,8,180,122,58,107,156,155,98,8,22,112,138,113,114,152,128,140,117,60,130,208,161,20,
+
26 98,207,136,134,36,230,195,107,78,3,129,129,16,68,158,98,61,163,56,71,14,4,97,30,120,29,152,6,112,161,20,96,68,179,69,176,233,152,98,156,
+
27 7,3,20,205,62,98,196,122,156,66,45,169,206,34,204,38,19,200,206,99,48,14,144,28,109,104,93,194,233,140,51,163,166,58,5,197,176,183,6,176,
+
28 242,56,181,207,40,140,97,60,141,115,33,28,214,33,198,214,133,221,14,152,197,57,24,150,107,33,108,34,149,210,60,174,45,119,77,60,29,76,65,202,
+
29 100,121,12,10,8,243,18,33,112,186,119,1,200,196,186,25,24,179,142,214,8,227,39,43,91,58,158,15,43,93,140,71,58,83,4,192,178,16,90,209,
+
30 204,232,45,132,1,115,2,34,69,161,110,102,231,17,198,51,8,139,98,56,136,177,104,97,30,96,68,179,76,81,193,192,233,140,193,201,138,17,13,48,
+
31 34,60,97,104,69,186,179,207,43,8,112,121,5,166,134,0,192,188,68,49,67,150,97,137,112,14,133,179,52,73,139,17,228,22,132,115,139,16,242,30,
+
32 7,2,45,206,236,91,185,138,96,158,98,226,8,182,98,156,218,211,160,75,88,113,145,202,35,218,152,70,0,234,56,17,78,119,98,60,226,65,16,192,
+
33 139,136,6,41,138,112,49,76,209,38,4,91,145,202,34,154,153,226,44,194,99,17,206,115,49,20,113,35,144,243,100,32,53,163,145,201,173,8,34,230,
+
34 44,68,67,136,69,49,185,196,113,212,194,35,156,236,98,40,226,83,140,197,178,112,152,163,145,208,197,8,39,98,216,193,67,204,192,59,114,136,179,25,
+
35 224,242,181,218,132,113,196,167,25,230,219,53,173,14,88,38,41,152,57,22,198,9,173,96,138,20,206,17,206,44,33,22,97,28,8,183,43,65,30,233,
+
36 26,205,48,39,172,19,22,116,57,152,183,8,150,176,227,35,148,69,56,176,12,0,140,234,34,156,226,142,55,73,183,65,139,61,112,53,166,40,228,91,
+
37 51,71,152,177,30,41,204,121,12,103,129,22,194,22,8,231,48,163,0,98,196,136,134,36,116,204,116,193,0,114,98,140,23,158,98,61,163,152,71,14,
+
38 216,71,145,158,234,34,206,33,132,121,139,18,205,49,67,166,41,138,96,158,139,97,16,167,152,138,118,206,48,14,172,3,200,192,117,60,174,97,132,81,
+
39 230,37,154,214,135,44,17,108,193,29,53,167,32,243,2,35,212,90,60,130,198,123,91,96,14,15,35,153,160,142,48,47,48,76,80,229,152,98,88,167,
+
40 51,18,205,30,98,196,80,194,208,139,113,103,158,67,192,224,242,185,154,8,227,2,217,130,98,135,44,193,108,224,29,24,167,64,147,2,113,140,233,8,
+
41 225,99,156,242,179,199,7,148,90,20,35,140,9,162,220,196,142,68,7,78,193,29,58,119,33,173,104,71,138,116,143,35,171,17,173,176,135,103,145,204,
+
42 236,69,30,101,48,76,73,216,130,233,140,83,129,137,114,15,107,70,0,142,147,91,22,51,218,217,224,118,121,92,174,196,91,88,241,30,45,135,46,131,
+
43 18,224,98,152,151,32,185,138,48,0,214,30,87,22,113,136,48,12,45,109,202,100,35,143,56,143,22,204,157,6,36,232,195,49,46,19,209,108,45,222,
+
44 96,79,33,152,180,214,206,172,35,16,103,11,15,43,88,49,128,49,35,196,67,17,28,24,38,34,16,4,46,152,45,222,98,196,91,67,137,173,142,220,
+
45 238,154,231,28,30,83,205,160,143,49,69,17,12,68,122,204,49,29,152,57,116,195,4,73,129,17,195,11,71,148,88,207,60,172,33,216,139,114,187,48,
+
46 13,99,206,51,22,122,205,22,206,6,25,139,114,11,158,98,41,14,35,202,100,231,49,3,9,213,173,181,216,207,33,231,22,230,40,93,194,233,206,135,
+
47 71,78,232,23,49,34,42,121,158,70,54,115,91,58,176,26,219,157,213,173,158,100,17,198,37,144,136,98,35,163,20,196,78,17,11,167,22,229,22,194,
+
48 44,201,210,49,3,171,17,211,90,238,166,32,121,168,142,49,39,196,67,17,206,108,83,17,196,3,183,78,34,20,91,24,7,109,97,229,28,57,218,219,
+
49 156,118,121,90,193,140,3,90,18,34,24,147,128,128,233,196,17,209,138,22,227,207,51,200,70,185,136,56,152,93,52,70,113,49,6,184,161,22,121,182,
+
50 113,139,97,8,128,98,88,103,51,18,232,30,45,132,121,15,51,200,44,103,53,182,1,132,196,28,198,71,144,197,148,69,58,96,132,65,49,19,4,230,
+
51 233,196,65,230,40,71,16,243,107,98,198,187,166,176,142,166,32,230,50,17,102,44,167,25,137,61,16,29,59,20,230,233,220,131,197,177,128,20,214,30,
+
52 65,219,92,242,49,14,162,45,210,50,17,70,41,238,71,78,33,102,24,137,130,115,116,195,140,75,90,60,131,11,77,108,88,196,116,214,1,140,196,105,
+
53 204,40,196,12,8,241,28,98,142,78,67,18,225,97,152,161,110,125,173,8,178,53,141,109,213,156,98,12,243,9,229,56,140,132,112,182,67,140,196,157,
+
54 184,76,68,193,57,58,119,35,35,20,96,20,243,60,174,45,115,16,96,24,90,219,149,140,242,24,20,17,230,36,245,208,233,216,167,71,78,205,100,98,
+
55 68,80,30,103,145,169,174,233,167,131,9,136,57,88,196,113,139,3,5,211,178,102,24,140,28,142,6,34,16,71,152,163,140,15,49,22,212,215,107,102,
+
56 19,11,91,107,153,8,182,178,35,197,177,219,52,196,177,88,102,41,200,122,96,76,3,197,166,182,209,136,98,50,99,28,58,107,156,204,242,53,147,140,
+
57 91,50,16,93,57,204,228,233,130,3,35,20,113,207,49,28,100,206,107,102,19,11,91,107,177,136,182,178,113,152,182,78,19,18,114,58,24,145,4,236,
+
58 91,28,115,204,71,49,179,143,33,132,194,121,90,230,66,44,90,65,30,96,69,220,38,40,230,114,49,44,195,230,41,154,7,152,183,106,114,152,3,11,
+
59 0,69,181,220,68,81,196,65,110,98,199,186,5,177,205,134,45,132,3,214,180,96,149,172,48,14,220,162,44,118,35,30,70,3,81,228,103,1,128,56,
+
60 133,204,19,204,232,193,48,34,8,132,243,114,26,214,11,119,108,225,30,59,96,24,6,123,168,138,114,140,113,181,130,93,6,44,116,197,107,78,3,211,
+
61 22,205,53,172,22,237,25,198,0,118,120,17,204,1,97,128,115,12,45,207,54,221,2,216,116,197,49,76,17,9,139,114,54,233,8,161,76,225,22,44,
+
62 60,8,182,3,168,142,115,59,56,204,89,92,38,36,236,232,233,140,51,179,18,225,121,139,22,238,197,161,28,56,97,8,182,19,168,142,114,138,17,231,
+
63 152,151,35,90,29,48,69,179,48,116,96,76,17,226,208,139,6,33,136,25,24,93,52,194,212,121,89,195,8,166,176,214,104,182,16,177,76,83,12,66,
+
64 45,156,38,158,103,24,167,41,128,117,96,8,230,3,169,128,114,138,22,237,97,172,211,22,122,193,22,204,49,211,90,112,137,107,14,50,57,76,3,83,
+
65 0,69,136,206,162,57,174,40,71,186,70,179,76,9,235,128,197,157,7,77,105,152,217,129,114,10,22,140,17,99,156,91,158,12,98,221,156,100,96,186,
+
66 87,9,139,100,197,22,199,49,203,90,102,54,121,185,8,229,22,236,108,35,0,99,117,17,108,1,132,91,16,120,138,107,156,220,142,102,99,20,90,116,
+
67 29,139,66,32,57,78,54,166,33,198,97,48,156,110,118,161,16,90,87,65,230,125,192,96,78,3,163,205,192,125,210,116,92,166,9,155,8,71,142,12,
+
68 98,41,132,100,45,217,200,228,56,143,179,15,51,129,204,243,96,178,107,25,168,229,56,221,176,132,123,168,224,71,176,12,142,55,42,186,26,195,92,13,
+
69 104,244,114,214,142,130,76,91,48,142,147,161,141,156,34,24,207,7,27,61,196,227,115,43,145,210,30,32,30,99,163,147,88,204,61,115,24,34,88,130,
+
70 46,99,116,215,102,102,32,234,65,22,194,41,130,45,15,96,152,19,209,208,182,57,9,49,108,192,116,156,134,78,115,140,112,117,22,236,6,163,141,156,
+
71 174,67,136,123,48,243,29,28,207,55,0,187,164,232,43,148,68,104,207,22,238,166,49,30,120,99,22,237,112,17,5,161,226,3,164,58,57,53,142,3,
+
72 183,73,194,130,211,145,219,92,68,28,30,12,22,123,171,145,204,208,65,48,37,98,139,102,67,161,108,115,30,98,217,147,137,154,209,206,45,197,134,49,
+
73 20,117,50,17,76,40,143,98,29,152,44,71,3,161,158,205,98,179,206,49,118,32,143,86,33,198,234,192,114,51,199,14,129,104,200,65,107,46,3,204,
+
74 92,228,96,78,135,109,96,128,107,153,200,71,57,198,212,97,22,231,87,19,141,136,71,35,149,177,4,90,61,97,156,71,65,201,196,32,54,229,102,140,
+
75 196,17,26,132,99,140,194,212,113,179,198,114,57,94,32,58,76,142,71,152,228,92,192,157,10,121,179,26,11,78,17,219,61,208,192,28,58,26,230,110,
+
76 23,53,152,113,50,97,156,71,35,131,148,64,23,115,152,47,48,136,224,113,60,174,197,30,81,218,8,166,16,150,107,153,145,209,172,16,139,152,19,147,
+
77 218,198,8,206,103,67,83,8,68,49,142,204,22,19,183,35,94,225,56,153,48,206,33,208,232,226,96,143,115,58,44,65,17,216,140,113,142,221,78,51,
+
78 195,71,35,156,162,11,149,147,128,90,57,142,133,167,0,145,104,64,35,57,194,198,194,102,152,76,110,134,35,24,130,230,87,3,164,105,205,172,59,59,
+
79 107,14,70,186,76,18,53,220,38,71,135,35,171,169,130,97,20,34,30,13,17,24,3,166,105,225,130,193,60,51,71,76,1,16,214,3,145,217,225,154,
+
80 56,58,184,89,237,66,3,56,142,1,105,179,161,196,122,33,22,142,67,220,172,192,98,56,76,196,102,107,171,171,144,194,237,208,194,71,11,156,251,129,
+
81 156,58,56,51,152,167,218,226,5,136,232,118,35,57,5,142,172,211,11,183,67,61,89,140,230,206,66,208,185,235,164,112,108,226,97,145,156,193,106,103,
+
82 136,6,51,171,49,128,226,193,107,140,197,114,188,228,230,61,29,51,152,98,236,65,4,73,132,227,123,136,142,81,66,44,205,4,80,224,214,107,8,75,
+
83 21,204,46,122,113,14,91,56,142,128,206,96,187,97,8,34,195,27,132,70,99,16,89,228,96,181,219,58,57,79,71,44,227,152,187,93,130,107,9,194,
+
84 67,11,145,141,213,200,56,51,116,30,0,64,98,54,197,107,136,78,13,115,160,187,157,192,87,59,49,219,9,152,234,97,102,30,5,140,23,59,70,43,
+
85 153,14,103,16,147,179,136,244,72,180,115,179,156,14,216,66,3,136,225,154,56,118,205,49,160,136,117,61,17,7,14,7,8,225,194,197,58,185,25,24,
+
86 93,10,120,16,5,134,22,9,224,118,224,115,153,48,217,211,147,148,248,229,202,57,100,206,97,189,136,193,24,240,32,49,152,220,35,134,167,64,140,48,
+
87 130,194,53,152,196,61,58,49,14,103,172,70,43,108,246,96,30,28,38,99,135,64,177,169,208,35,12,204,103,163,21,156,36,116,230,59,62,45,14,138,
+
88 230,58,10,115,177,69,140,6,9,132,112,193,103,177,177,90,227,28,153,198,142,153,194,19,215,59,20,249,225,154,61,196,192,54,49,228,160,139,51,52,
+
89 227,49,154,204,115,137,28,139,76,135,156,66,20,115,28,134,115,176,88,196,97,0,118,44,16,12,46,216,44,32,97,185,196,156,26,231,167,173,115,144,
+
90 150,123,5,4,97,4,80,225,208,212,198,232,49,138,16,79,5,96,176,143,157,24,131,145,11,16,230,61,136,197,176,152,46,196,102,11,168,225,130,35,
+
91 49,177,88,131,28,153,200,33,22,132,159,22,142,202,230,29,12,215,58,25,48,24,34,193,96,130,59,104,232,49,182,205,117,56,8,130,193,1,194,226,
+
92 205,97,186,179,79,157,92,35,24,88,46,167,86,24,140,234,116,98,59,57,51,144,116,206,30,122,206,28,143,115,157,17,128,224,20,117,102,49,186,136,
+
93 35,179,54,97,132,28,12,6,206,140,33,113,211,8,224,201,132,195,52,240,193,83,24,128,102,226,32,139,29,179,12,36,98,176,138,115,98,31,61,115,
+
94 158,137,107,156,1,136,114,118,192,98,139,14,172,83,11,169,201,158,100,112,103,16,237,202,246,76,225,113,236,243,147,102,55,8,151,98,41,180,17,104,
+
95 36,71,10,62,34,11,15,184,24,7,207,89,194,230,179,143,85,174,112,118,194,58,56,152,216,163,135,23,0,140,41,138,192,67,147,60,120,229,158,33,
+
96 100,194,57,26,192,112,41,141,152,209,196,64,106,118,32,14,21,130,35,61,134,192,62,112,97,14,78,216,7,35,79,12,53,17,156,6,67,134,40,236,
+
97 88,195,60,25,156,153,234,112,107,154,118,215,62,219,148,236,25,195,167,108,67,152,176,70,58,14,197,142,3,24,204,195,171,98,8,236,230,225,106,16,
+
98 68,3,33,16,228,100,34,31,113,112,140,234,193,117,117,57,30,24,206,12,65,135,45,114,158,181,207,159,115,142,94,194,58,41,133,192,236,118,193,106,
+
99 106,96,142,197,49,76,40,195,96,15,56,30,15,79,79,7,33,230,22,41,76,108,17,133,140,198,54,54,8,237,163,12,70,3,155,8,209,11,61,147,
+
100 38,120,228,214,17,205,88,7,67,51,11,12,118,59,58,30,28,71,44,67,51,215,42,159,114,154,219,92,244,211,195,12,163,183,9,90,11,115,77,17,
+
101 200,118,34,133,30,185,5,135,103,67,192,185,246,32,189,206,33,20,194,56,49,152,78,66,193,97,208,198,100,116,17,136,115,96,26,57,97,31,23,96,
+
102 14,68,158,14,136,99,98,145,213,152,102,102,204,113,35,4,112,140,51,11,103,6,1,217,233,224,224,60,194,114,67,9,209,161,141,138,212,226,197,29,
+
103 153,156,143,3,14,89,232,118,196,18,61,206,202,215,23,104,196,16,184,176,7,35,131,25,192,198,100,116,49,163,128,118,118,204,99,96,136,34,153,174,
+
104 1,70,8,133,219,145,237,76,19,49,97,200,234,226,58,97,59,61,98,0,187,17,179,236,243,179,88,3,168,140,114,24,112,195,99,113,97,139,29,176,
+
105 199,0,116,58,182,112,58,157,136,78,167,6,70,51,161,163,134,26,186,177,76,218,152,174,34,152,99,176,57,8,197,28,176,4,178,97,11,182,194,16,
+
106 128,140,112,104,99,57,184,142,206,102,55,17,211,0,204,237,136,49,246,114,26,215,30,107,8,114,241,195,21,238,196,70,205,48,13,139,136,164,61,114,
+
107 25,178,97,152,207,178,97,9,43,157,144,166,120,132,204,194,112,99,117,57,139,12,142,70,49,142,102,24,228,240,36,236,240,46,36,70,29,60,198,114,
+
108 1,99,20,102,54,9,152,167,3,141,134,56,121,192,194,60,244,194,118,46,97,56,54,99,57,0,224,232,102,234,115,117,113,56,29,90,14,143,0,118,
+
109 194,53,147,60,121,172,246,74,194,59,51,96,30,139,12,39,163,135,83,129,140,81,208,112,219,21,168,230,32,140,225,16,20,68,58,12,228,100,100,204,
+
110 35,137,201,213,212,66,35,49,157,176,133,29,179,202,201,128,60,123,0,245,230,17,210,152,206,109,29,78,76,108,103,71,81,71,33,194,28,204,99,199,
+
111 70,51,211,179,25,192,120,224,228,142,172,49,154,152,102,110,216,110,35,29,7,8,58,58,154,118,120,30,37,128,46,243,192,132,134,17,209,152,224,224,
+
112 44,22,14,78,172,103,172,7,108,152,131,54,215,71,179,207,148,194,58,43,136,128,108,227,30,124,192,9,16,139,120,132,64,99,100,112,48,143,109,158,
+
113 36,24,140,154,48,15,76,204,99,150,167,19,131,171,179,129,141,71,39,82,157,136,195,207,136,199,109,157,71,72,59,57,43,83,12,81,155,20,200,102,
+
114 27,138,28,135,98,71,67,177,115,209,192,132,121,140,114,134,49,208,161,217,193,141,196,116,234,100,58,49,144,114,97,65,115,195,98,88,2,81,132,124,
+
115 83,9,147,25,224,92,118,99,61,28,49,142,135,10,115,113,62,224,118,195,16,85,154,204,136,135,50,8,45,153,176,218,53,14,71,110,39,98,49,152,
+
116 187,1,89,48,13,30,35,31,121,212,237,12,99,146,14,206,6,109,71,6,167,103,7,85,29,14,222,57,28,31,59,28,30,159,117,29,54,44,57,88,
+
117 206,131,25,157,12,133,28,220,84,116,56,67,211,169,167,204,35,222,97,101,58,158,140,59,29,25,139,7,66,198,161,9,212,205,145,225,163,108,242,21,
+
118 158,84,60,31,142,7,72,102,32,54,243,140,121,232,138,108,116,34,41,235,21,140,249,217,132,73,88,2,69,30,25,59,58,158,153,11,7,45,70,67,
+
119 145,96,194,17,216,30,152,222,200,234,125,179,24,185,71,98,16,22,28,6,50,57,187,24,232,101,57,53,26,112,22,15,59,29,178,30,59,61,109,212,
+
120 115,117,29,52,113,28,177,153,8,93,90,30,142,20,92,198,81,230,22,222,120,18,167,129,230,98,48,241,97,212,248,236,88,46,56,118,122,59,41,204,
+
121 200,114,193,6,96,130,241,17,138,247,65,232,206,9,152,233,169,168,92,198,212,124,194,208,121,134,60,194,37,179,171,34,142,14,213,212,66,41,196,114,
+
122 100,100,58,113,20,57,22,68,46,173,158,186,139,139,184,136,71,181,28,30,198,115,83,35,155,70,135,54,49,135,78,160,122,56,67,231,83,91,48,159,
+
123 67,24,186,142,207,69,11,4,38,77,71,162,195,33,115,171,65,236,1,141,97,74,35,54,131,131,212,50,58,55,116,31,100,34,31,59,102,148,93,138,
+
124 236,121,232,224,211,79,6,169,224,72,163,171,39,98,195,211,35,33,203,83,65,200,177,78,221,81,144,225,177,35,134,79,29,158,220,71,74,100,115,20,
+
125 40,230,236,135,51,34,156,24,219,16,184,143,100,59,100,104,236,236,29,79,70,22,8,76,204,132,45,77,15,93,72,118,59,159,49,154,217,141,178,157,
+
126 79,169,213,145,152,225,147,80,176,93,196,204,245,196,7,76,103,206,131,28,216,106,224,57,171,128,237,161,209,12,135,46,218,142,197,140,108,135,13,15,
+
127 142,0,248,225,227,199,3,205,117,23,65,97,233,28,68,46,204,132,38,77,4,45,74,122,226,135,162,193,34,238,34,227,220,68,45,177,156,16,204,224,
+
128 71,103,7,98,132,44,100,59,117,159,29,148,72,224,73,71,7,238,167,100,106,61,104,100,118,198,236,92,88,40,248,224,130,78,179,78,166,188,112,201,
+
129 28,71,47,20,197,109,226,1,163,216,40,37,134,237,177,8,177,226,76,102,161,213,181,28,31,24,88,46,209,140,244,205,161,235,25,15,92,98,226,199,
+
130 143,117,18,107,171,34,184,157,129,144,133,93,142,134,24,116,236,7,38,69,61,113,108,93,196,120,241,96,187,197,135,96,226,118,41,140,236,204,204,237,
+
131 168,97,119,16,100,234,81,46,166,154,59,18,131,179,228,117,100,237,196,92,200,200,237,140,99,214,55,142,93,178,56,12,58,29,12,115,59,20,112,123,
+
132 177,9,12,142,204,140,207,184,180,62,234,67,238,168,61,213,182,197,135,202,226,47,106,61,24,200,245,163,67,211,33,143,90,167,110,38,178,113,30,61,
+
133 169,147,108,103,168,102,33,87,98,17,154,8,76,212,237,142,201,196,163,197,143,53,212,73,69,140,129,168,92,140,103,174,221,139,153,52,23,113,33,241,
+
134 221,177,219,222,234,36,174,44,144,204,114,132,57,149,14,147,78,99,26,57,50,53,147,137,166,186,182,142,163,212,88,200,102,49,118,134,103,102,99,29,
+
135 177,128,187,81,79,184,182,37,196,123,218,143,163,25,218,153,158,140,208,66,208,135,166,115,179,39,178,106,18,61,168,121,173,66,232,198,118,166,66,226,
+
136 140,197,204,197,11,181,43,39,20,62,44,53,183,22,202,226,60,28,79,145,168,251,67,38,70,98,133,216,192,236,201,231,110,217,30,180,61,23,20,33,
+
137 18,40,66,142,206,198,118,46,102,209,147,81,7,184,196,184,189,183,17,47,106,62,141,66,224,100,118,51,179,183,99,29,153,3,35,36,62,198,104,246,
+
138 49,230,153,31,121,144,188,204,244,141,15,90,16,93,218,139,177,207,181,60,75,139,111,106,31,99,62,12,98,227,59,23,118,41,145,145,15,177,128,151,
+
139 20,108,88,107,218,132,149,140,94,208,246,163,156,116,71,136,90,60,92,201,226,90,141,123,136,155,136,245,50,62,51,182,77,5,11,187,32,185,148,251,
+
140 27,196,177,182,107,80,242,153,31,153,139,145,161,216,161,142,218,40,187,180,100,100,104,243,38,219,99,30,86,54,64,100,200,134,108,154,10,100,102,70,
+
141 70,64,125,140,162,88,205,53,168,73,90,143,169,145,241,140,217,52,104,201,217,25,25,217,25,182,201,217,246,77,5,196,180,59,43,177,117,104,200,83,
+
142 67,238,198,62,198,3,216,208,75,25,166,177,137,41,144,249,155,37,118,46,40,80,187,66,50,51,159,50,40,243,35,91,50,30,243,35,232,237,144,59,
+
143 23,32,161,113,68,23,51,159,50,65,44,102,154,198,217,88,196,204,143,169,155,33,154,50,118,67,230,106,60,202,37,141,230,177,182,83,33,232,237,148,
+
144 99,186,158,172,236,81,89,59,40,246,55,154,198,105,88,196,204,135,169,155,33,154,50,104,70,70,96,124,204,162,76,141,109,141,183,153,137,67,51,224,
+
145 209,145,5,50,20,172,157,207,187,67,230,70,137,50,18,243,49,40,102,125,93,159,24,81,246,131,31,51,83,230,72,36,201,237,153,26,243,33,40,100,
+
146 61,93,159,25,161,241,67,31,118,12,157,161,246,141,143,104,60,75,67,239,104,126,208,249,26,31,104,49,243,53,30,103,18,100,86,204,155,121,144,146,
+
147 153,143,187,62,162,143,140,49,246,128,61,220,121,155,219,50,108,211,49,40,236,125,219,34,12,124,132,62,40,15,153,160,147,50,182,100,247,153,54,134,
+
148 99,193,216,245,104,124,97,143,187,83,230,113,38,104,217,145,175,50,18,142,199,218,31,2,11,144,5,198,139,180,65,238,202,36,200,210,153,154,134,98,
+
149 65,216,242,10,30,48,199,197,40,247,104,37,217,91,51,52,211,54,202,236,77,217,245,104,124,131,31,20,163,218,71,153,189,183,102,154,102,36,174,196,
+
150 218,15,86,135,198,20,125,162,143,119,18,102,86,204,222,105,153,165,51,19,118,37,90,15,24,97,226,148,123,72,247,111,18,209,182,218,15,53,160,244,
+
151 20,125,69,15,32,195,218,16,123,176,18,238,217,155,205,51,53,230,98,81,216,240,20,60,132,30,49,15,180,1,238,209,183,111,52,204,215,187,109,29,
+
152 143,1,67,212,99,227,40,241,64,61,218,54,102,247,187,52,166,109,163,177,32,40,121,6,30,49,7,180,1,46,209,179,50,154,102,105,93,137,180,30,
+
153 2,143,169,25,16,15,141,30,41,4,187,121,166,102,149,219,119,98,65,160,146,12,60,82,137,20,2,90,32,151,101,109,217,175,118,218,52,18,2,132,
+
154 168,194,70,81,34,128,75,68,109,161,77,104,107,221,137,70,130,64,80,146,12,60,98,9,20,2,93,163,109,10,107,183,189,219,104,236,72,52,18,162,
+
155 132,140,162,69,0,150,136,37,163,219,104,105,173,4,148,80,148,20,37,70,30,49,4,138,1,46,208,214,136,107,179,74,237,180,104,220,80,149,24,121,
+
156 8,60,80,9,21,109,161,77,118,247,187,109,26,55,20,37,70,30,66,15,20,2,69,91,104,83,93,189,238,219,70,141,218,9,1,132,144,130,69,3,
+
157 98,129,182,136,107,183,149,161,168,41,184,161,234,65,234,67,227,0,241,162,90,20,214,133,123,67,81,163,96,40,74,138,18,66,9,25,68,138,182,208,
+
158 166,180,123,218,26,86,141,197,9,1,66,72,65,35,40,145,86,218,35,109,30,246,134,149,163,113,66,84,97,42,48,145,129,177,86,218,33,173,30,246,
+
159 143,43,67,98,155,1,66,72,48,145,129,177,128,72,164,109,163,205,20,107,218,9,140,216,12,37,70,18,50,137,21,109,162,26,208,175,104,242,180,110,
+
160 41,184,161,42,65,36,81,34,173,138,67,90,21,237,13,65,70,197,54,3,9,82,9,25,68,140,13,138,67,69,21,237,30,81,70,197,55,20,37,70,
+
161 18,69,108,84,209,83,90,21,237,30,86,141,160,166,192,97,32,65,36,1,35,91,26,219,66,188,83,202,208,212,20,216,12,218,145,178,43,99,3,98,
+
162 144,209,72,107,71,189,161,168,41,184,161,42,48,146,43,99,3,98,166,138,43,197,60,162,141,65,70,198,108,6,18,69,108,96,108,85,182,133,120,167,
+
163 149,161,168,40,208,25,181,25,178,43,99,3,99,91,20,87,140,242,138,52,162,155,140,216,12,36,138,216,192,216,211,69,35,197,21,237,13,65,70,198,
+
164 109,72,218,171,100,86,198,154,50,60,81,74,40,212,20,108,83,96,48,146,43,100,3,70,154,50,60,83,202,41,229,20,108,102,192,102,212,141,144,13,
+
165 24,13,20,143,20,82,138,122,12,108,102,192,141,170,182,64,108,147,70,71,138,121,69,60,162,141,140,216,12,218,145,178,43,99,1,163,35,198,41,70,
+
166 122,12,108,99,64,141,145,77,32,26,52,209,72,104,162,148,103,160,207,65,141,2,26,4,108,128,104,211,70,71,140,82,140,82,138,54,49,170,67,84,
+
167 141,145,77,36,209,145,227,20,163,60,163,61,6,54,67,64,141,144,13,32,26,50,60,98,148,83,208,103,198,54,51,106,166,170,182,52,209,145,227,35,
+
168 197,20,162,158,131,26,4,53,84,213,86,198,154,52,209,145,226,158,131,61,6,54,67,85,77,85,108,96,52,107,198,66,138,41,70,124,134,129,13,5,
+
169 53,64,210,77,25,30,50,60,98,148,103,160,198,200,104,16,213,83,72,15,37,227,35,198,41,70,122,12,108,99,64,134,170,154,64,52,107,198,41,70,
+
170 41,70,124,143,144,208,33,170,6,144,13,37,227,20,163,20,163,62,49,160,71,129,13,85,52,128,104,211,70,71,140,82,144,168,71,200,104,41,170,166,
+
171 168,26,75,200,133,24,165,24,168,51,228,120,43,193,77,32,26,73,163,35,198,66,140,84,25,242,62,67,85,77,32,26,75,200,133,34,20,133,66,62,
+
172 67,64,134,168,61,65,228,7,146,82,33,70,42,12,249,13,5,53,65,234,6,146,242,35,198,41,70,41,70,122,17,242,26,170,105,0,210,3,201,120,
+
173 200,82,21,8,249,31,33,170,166,170,154,64,121,47,24,165,24,168,71,200,249,13,5,120,41,164,188,136,82,33,72,84,25,242,60,8,240,87,170,154,
+
174 75,201,121,16,164,42,16,168,71,200,104,43,193,77,80,122,222,68,40,197,66,21,6,124,143,5,122,131,212,13,37,227,20,163,21,8,89,31,35,193,
+
175 77,85,52,151,145,10,68,41,10,132,124,143,171,193,94,160,245,7,146,82,74,68,40,197,66,62,71,213,234,15,91,201,121,16,164,42,16,168,71,213,
+
176 224,175,5,122,131,201,121,37,34,20,133,66,22,175,5,122,131,212,30,75,200,133,34,20,133,169,106,240,87,130,154,75,201,121,16,164,66,144,178,62,
+
177 71,129,30,10,245,7,168,60,136,82,33,72,84,33,106,240,87,128,61,111,89,86,242,34,16,168,66,200,240,87,168,61,65,228,188,136,82,33,72,90,
+
178 150,165,171,212,30,160,245,148,136,82,21,8,84,35,228,125,94,160,245,7,146,242,74,68,66,21,8,90,150,175,5,122,131,214,85,149,81,20,168,71,
+
179 213,224,175,0,40,1,84,30,73,72,136,168,132,124,143,169,64,30,160,245,7,145,10,68,41,10,132,42,17,224,175,5,120,3,212,30,68,41,16,164,
+
180 68,82,200,240,82,128,20,0,171,42,202,68,41,10,132,45,75,87,130,188,1,235,122,202,168,82,34,42,33,10,10,80,2,128,21,101,89,85,17,81,
+
181 20,181,45,75,87,168,61,101,89,85,17,81,20,181,45,75,87,168,61,64,171,41,17,21,16,133,169,106,90,188,21,235,42,202,178,170,34,149,8,250,
+
182 188,0,160,5,0,42,209,104,168,132,42,16,181,120,1,64,10,0,245,148,136,82,34,41,106,90,188,0,160,5,0,122,202,178,170,33,11,82,200,240,
+
183 82,128,20,0,171,42,202,68,41,11,82,212,181,120,1,66,85,66,172,170,136,168,132,45,74,10,80,2,172,171,42,202,168,138,136,165,169,106,80,2,
+
184 128,61,101,89,85,17,81,20,181,45,94,10,245,149,104,178,173,21,17,81,20,160,5,0,42,202,178,172,170,136,168,138,88,22,175,0,40,1,86,139,
+
185 41,17,21,42,90,150,5,0,40,1,64,10,168,138,136,168,138,90,150,5,0,40,1,66,85,149,101,84,169,106,80,2,128,21,104,20,84,69,68,84,
+
186 69,74,150,165,171,192,10,18,170,32,74,168,138,149,40,2,0,20,0,171,42,202,178,170,34,162,41,106,80,2,128,20,37,89,85,17,81,20,181,45,
+
187 75,4,129,86,85,162,162,42,34,165,75,82,128,20,0,171,42,208,40,8,138,136,165,129,96,80,2,173,2,139,69,68,84,169,106,88,36,10,178,172,
+
188 170,136,168,138,90,150,5,0,40,1,66,129,42,202,168,138,149,45,74,0,80,2,173,2,138,136,168,138,136,169,4,169,66,129,40,74,168,128,136,169,
+
189 4,169,64,16,0,160,5,89,86,128,144,72,36,10,0,80,2,133,2,85,149,81,21,17,75,82,193,32,129,64,160,81,81,21,32,149,40,1,64,10,
+
190 0,85,149,104,20,4,69,44,10,0,88,20,0,171,69,68,90,42,34,164,18,9,2,128,21,101,84,69,68,84,69,45,75,4,129,66,129,64,160,80,
+
191 18,9,82,212,160,5,0,64,160,81,81,21,17,82,9,4,130,4,161,64,68,10,2,34,164,18,165,0,64,2,172,171,64,160,36,18,9,2,128,20,
+
192 0,161,64,160,34,42,34,150,9,4,130,65,2,129,64,162,164,18,165,0,40,1,64,10,0,85,160,80,18,8,128,144,44,18,5,0,64,162,164,40,
+
193 169,4,130,65,2,129,64,149,82,9,4,129,96,144,40,1,66,129,64,160,36,18,9,82,128,20,0,171,64,160,81,82,9,4,130,65,32,80,2,132,
+
194 170,136,9,4,130,65,0,18,8,20,90,5,2,128,144,72,36,18,5,0,40,80,40,8,138,136,9,4,130,65,32,129,64,160,81,82,9,82,128,36,
+
195 18,8,20,10,2,65,17,75,4,129,66,144,64,160,80,48,162,160,2,0,20,40,18,130,32,34,2,65,32,144,72,32,80,40,20,84,133,2,138,144,
+
196 72,20,40,0,80,2,133,2,128,144,72,36,18,9,2,133,2,129,69,68,84,130,65,0,16,1,2,129,77,1,16,18,9,2,128,36,16,40,20,10,
+
197 5,21,32,88,36,19,64,148,40,9,4,130,65,0,16,1,32,129,64,162,165,82,9,4,130,65,52,208,37,10,2,65,32,144,72,36,16,40,20,84,
+
198 133,3,4,0,64,4,0,40,80,18,9,4,64,42,1,114,160,23,64,160,81,104,184,106,128,168,10,129,64,162,193,117,193,52,75,202,133,66,149,16,
+
199 180,64,68,10,46,176,88,45,66,11,80,5,0,88,46,9,2,162,61,10,105,94,217,94,242,148,180,134,176,80,82,85,65,64,21,64,128,4,0,88,
+
200 42,0,32,82,133,68,121,77,52,166,154,243,94,143,45,42,128,160,170,10,160,64,85,85,34,128,192,4,130,192,16,0,160,136,136,84,123,208,215,188,
+
201 211,74,107,209,229,164,17,86,69,2,2,145,64,138,170,170,160,170,0,176,194,128,137,41,111,42,26,242,154,247,154,242,189,16,188,0,21,64,128,170,
+
202 170,64,82,2,144,21,106,16,8,97,64,42,94,133,52,175,52,215,182,247,188,165,46,138,0,160,164,5,32,42,129,20,8,170,170,10,0,1,12,48,
+
203 68,149,10,242,189,178,154,107,222,105,74,84,68,13,106,73,20,21,85,84,8,160,64,85,0,88,44,21,20,16,37,149,229,121,175,108,211,91,52,166,
+
204 189,10,152,0,42,129,21,85,85,84,8,10,64,85,0,80,80,5,10,132,1,1,10,134,189,237,182,216,147,91,109,239,122,34,0,2,168,12,10,64,
+
205 82,2,144,20,128,170,4,80,34,130,128,40,2,224,148,123,222,219,98,79,137,18,60,211,77,42,32,0,16,20,138,66,1,8,4,32,17,85,84,21,
+
206 65,85,85,85,84,20,33,222,134,182,104,241,227,207,159,108,75,111,41,64,0,128,65,128,132,85,34,169,0,132,1,148,8,160,64,82,0,16,1,65,
+
207 67,162,61,179,68,143,30,124,120,241,237,154,106,36,20,8,69,25,84,101,82,42,145,84,138,164,0,80,85,82,40,17,65,66,8,146,189,237,182,36,
+
208 120,241,227,196,137,109,239,44,36,85,33,20,138,164,85,34,144,138,66,42,168,40,1,21,72,69,85,0,208,165,43,102,182,60,120,243,226,71,137,109,
+
209 239,68,170,169,20,132,82,16,8,64,33,20,132,85,85,80,85,85,85,82,2,172,41,71,188,209,45,143,30,60,248,241,45,182,87,164,0,138,163,1,
+
210 8,4,85,33,20,132,81,149,72,170,64,34,129,8,4,90,130,2,60,166,182,216,243,226,89,15,30,36,75,205,68,130,169,8,164,34,145,84,138,164,
+
211 85,34,144,138,164,2,16,8,69,33,21,64,1,10,134,137,108,249,241,226,231,199,159,109,179,81,32,170,50,144,101,82,42,144,20,138,164,82,17,84,
+
212 128,66,0,202,163,17,72,160,180,67,77,108,121,243,236,153,50,62,60,75,101,42,40,40,196,32,196,81,149,72,170,170,164,5,80,34,169,8,65,136,
+
213 65,136,66,0,6,134,189,177,227,207,139,159,100,200,120,246,222,244,0,81,136,65,136,49,20,138,164,80,32,42,168,17,84,101,32,202,65,136,66,2,
+
214 134,143,41,162,91,62,200,251,38,67,207,137,52,210,234,66,12,49,6,33,8,69,34,129,1,84,1,64,21,72,69,24,98,12,50,170,193,10,134,154,
+
215 216,241,227,217,50,62,124,123,98,94,136,10,163,16,130,136,66,17,72,10,64,85,2,40,17,64,138,4,34,140,66,17,84,2,133,121,173,137,30,200,
+
216 251,38,67,199,143,53,229,128,16,98,12,49,6,82,42,170,130,168,42,170,168,40,41,20,131,12,65,136,164,8,20,165,109,177,39,207,178,100,124,249,
+
217 246,219,53,16,21,72,48,196,24,132,85,32,42,168,42,170,128,16,8,66,16,98,12,49,8,170,0,136,87,154,36,120,243,236,153,50,62,60,73,175,
+
218 124,0,131,16,98,16,132,82,42,170,129,1,85,64,138,163,40,195,40,195,40,202,160,25,74,246,196,137,62,200,248,185,241,231,219,53,229,130,144,132,
+
219 24,132,34,145,85,85,84,20,128,69,85,34,140,66,12,48,195,16,132,0,161,94,219,99,207,178,100,46,200,249,241,45,154,137,34,144,98,12,50,144,
+
220 138,170,10,160,69,85,32,17,84,138,65,136,48,195,16,138,161,66,154,104,147,231,217,11,178,100,200,120,150,222,136,160,65,136,65,136,66,41,21,72,
+
221 160,64,85,0,85,82,16,130,136,48,162,12,66,40,64,175,53,177,227,217,11,139,139,178,62,61,179,94,128,4,24,130,134,32,196,34,144,21,64,128,
+
222 170,0,0,164,82,16,131,12,65,134,33,21,66,133,52,72,147,226,236,142,197,217,31,30,217,165,73,8,65,134,24,98,16,138,69,5,80,80,80,0,
+
223 5,82,16,131,12,48,195,12,50,170,232,243,91,30,201,144,184,187,33,115,226,68,188,168,10,65,134,24,81,6,34,145,85,84,1,64,22,160,4,33,
+
224 6,33,6,32,196,33,20,0,10,87,182,36,123,38,66,231,108,143,159,108,215,234,66,12,48,195,16,138,64,32,42,130,130,130,168,42,169,20,131,16,
+
225 97,68,20,66,40,80,166,182,36,249,243,177,113,113,118,67,196,154,82,130,144,130,136,40,132,25,84,128,170,160,64,85,0,85,82,16,131,16,131,40,
+
226 196,34,172,10,87,137,18,61,147,38,66,236,135,159,109,239,64,2,16,131,12,66,17,85,85,65,84,20,20,20,8,170,49,8,49,8,49,20,128,0,
+
227 136,83,77,18,124,123,38,76,135,159,109,183,151,85,32,196,32,202,69,85,5,5,80,80,80,5,5,82,16,98,16,132,82,2,134,87,189,177,35,207,
+
228 159,30,124,120,150,205,42,64,8,69,24,138,164,5,80,80,5,0,0,0,5,82,16,132,24,132,34,168,6,133,121,173,182,60,120,241,226,68,182,105,
+
229 74,144,85,33,8,164,85,85,5,0,88,44,20,1,85,85,85,85,85,84,0,17,16,166,154,219,98,71,137,108,73,175,121,104,170,4,34,145,85,64,
+
230 0,1,64,2,0,0,160,170,4,85,34,130,128,7,43,222,105,162,68,182,37,179,77,121,83,5,82,41,21,84,20,1,64,0,32,16,0,0,5,5,
+
231 80,85,5,8,81,10,247,182,217,162,91,52,211,74,82,192,1,84,138,170,10,0,0,0,1,8,4,0,20,1,65,85,65,96,9,71,149,230,154,219,
+
232 102,154,107,222,137,130,170,170,170,130,128,0,0,0,64,48,128,0,40,0,2,128,6,8,133,43,222,105,166,182,247,154,84,76,20,21,84,20,20,2,
+
233 0,1,12,2,16,0,5,0,80,5,135,66,149,239,53,230,154,243,74,84,76,20,21,84,20,22,161,0,134,24,64,0,0,0,0,2,1,162,33,94,
+
234 83,94,243,94,82,149,18,21,0,85,0,0,0,128,66,16,224,16,0,0,0,88,4,40,136,82,189,239,123,222,82,161,120,40,2,130,128,0,4,2,
+
235 16,193,3,8,0,64,0,2,26,34,20,165,123,202,242,148,168,156,0,20,0,0,2,16,134,28,33,8,64,2,176,12,17,17,10,87,149,229,41,74,
+
236 148,133,64,0,1,96,1,8,97,248,67,8,4,3,10,81,10,82,188,165,41,81,19,0,0,0,0,128,66,28,48,248,67,0,128,64,52,162,20,165,
+
237 41,74,133,68,225,0,0,0,0,128,67,15,254,24,64,33,133,40,136,82,148,165,68,68,64,192,32,0,16,8,97,193,2,129,240,132,32,16,232,136,
+
238 136,82,161,74,148,240,0,0,8,4,33,195,250,112,194,16,135,165,16,168,84,42,34,82,24,0,4,33,8,124,41,248,97,132,48,233,68,68,42,34,
+
239 34,80,48,128,4,2,16,195,244,254,28,33,224,148,162,21,17,17,41,194,16,132,33,135,255,252,48,195,10,104,136,136,137,68,248,4,32,16,195,15,
+
240 79,167,12,48,255,68,162,34,37,63,8,66,28,63,250,120,112,195,133,52,162,81,41,76,48,132,33,135,255,167,240,225,240,77,18,137,74,126,16,225,
+
241 195,254,159,225,195,135,77,41,74,83,134,24,67,15,255,79,248,112,253,52,162,83,160,120,97,240,160,122,127,240,225,255,74,105,79,134,24,120,127,211,
+
242 255,195,195,79,74,82,159,14,31,255,255,254,31,15,211,77,63,195,15,15,244,255,254,31,244,211,79,252,63,255,255,255,135,255,211,167,15,15,135,253,
+
243 63,208,60,33,250,104,148,74,127,12,60,63,15,254,31,255,233,165,52,240,225,225,255,195,78,31,15,250,82,148,211,252,56,127,15,255,255,167,79,79,
+
244 254,24,97,240,225,255,224,158,157,52,211,167,255,240,255,194,16,132,48,79,135,166,137,68,68,68,162,116,135,8,66,16,128,64,33,211,0,0,80,0,
+
245 8,83,66,161,74,242,148,165,42,34,34,83,225,0,0,0,0,0,0,0,80,80,85,0,80,5,8,122,33,74,242,188,215,154,243,94,242,149,18,129,
+
246 10,128,42,170,168,40,40,2,170,170,130,168,40,0,0,7,232,136,87,148,211,94,217,166,154,107,222,84,68,192,0,21,85,65,85,85,85,72,170,69,
+
247 85,85,5,0,128,67,74,21,10,82,189,239,53,230,154,107,222,247,161,83,128,2,170,170,170,170,169,21,85,84,138,160,170,0,0,16,244,162,21,10,
+
248 87,149,230,188,211,94,107,222,242,149,19,0,0,85,85,85,82,42,145,85,85,85,85,64,0,0,0,2,26,81,10,82,149,239,53,230,154,105,166,189,
+
249 229,41,104,16,80,85,85,32,42,170,170,145,85,72,170,160,160,0,16,195,232,136,87,149,230,188,211,77,52,211,94,242,161,104,16,5,85,85,85,85,
+
250 85,85,85,85,85,85,80,0,5,0,0,0,14,136,82,189,230,154,217,173,182,105,166,189,229,42,96,0,170,170,164,85,85,85,85,85,85,85,5,80,
+
251 85,0,80,80,0,0,209,10,83,77,52,75,98,68,137,109,182,222,242,162,64,21,84,138,69,82,42,170,170,169,21,85,85,84,138,170,170,160,160,0,
+
252 1,161,74,243,91,18,60,121,241,227,196,182,219,202,152,42,145,72,164,82,41,20,138,69,85,34,170,130,170,170,145,72,164,80,80,134,136,83,77,108,
+
253 120,243,231,217,31,30,36,75,222,144,2,41,8,66,16,138,66,41,21,72,164,82,42,169,21,85,85,85,85,85,64,0,40,133,123,109,137,62,61,145,
+
254 243,231,196,137,53,232,128,10,164,33,6,33,20,132,85,82,41,20,138,164,80,85,85,82,42,170,170,168,122,21,239,53,177,227,199,159,62,60,120,246,
+
255 205,121,112,82,16,132,33,8,69,82,41,20,138,66,16,138,160,160,170,164,82,16,138,170,1,68,71,188,214,196,143,30,124,249,241,227,196,182,105,82,
+
256 0,164,33,8,66,17,72,170,69,33,20,132,82,42,168,42,129,21,84,138,170,161,10,33,74,107,98,71,159,30,200,249,241,35,205,52,165,130,169,8,
+
257 66,16,138,164,85,34,145,72,69,33,21,72,164,82,42,145,72,170,170,29,10,243,91,18,60,249,243,236,143,143,18,36,215,162,0,41,8,66,16,132,
+
258 33,21,85,84,138,164,82,17,72,170,66,41,8,66,16,132,80,93,10,107,98,71,159,100,201,147,38,67,199,182,242,164,20,132,32,196,33,8,170,170,
+
259 170,170,164,82,41,20,138,69,33,8,66,16,131,17,85,66,133,52,209,227,207,139,178,23,23,100,124,120,147,74,144,33,8,48,195,16,132,34,170,170,
+
260 170,170,170,130,169,20,131,16,97,134,24,98,17,85,67,41,77,108,120,246,76,133,217,11,178,62,61,179,74,128,4,32,195,12,49,6,34,145,85,84,
+
261 21,84,21,65,72,66,12,66,12,65,134,33,8,0,20,66,154,104,145,231,217,50,23,100,200,248,246,219,122,85,70,24,97,134,24,98,17,85,85,84,
+
262 20,20,20,0,20,138,49,6,24,97,134,24,138,161,148,175,53,177,227,207,178,100,46,125,144,241,45,188,168,10,65,134,24,97,134,33,8,170,160,160,
+
263 10,160,170,170,170,69,82,16,131,12,49,21,84,2,82,189,182,199,159,62,46,201,147,35,227,219,53,233,2,16,97,134,20,66,16,138,170,10,10,10,
+
264 10,10,170,10,164,32,195,10,24,97,136,69,80,161,74,104,145,39,207,139,178,23,100,200,248,150,205,42,2,144,97,133,12,49,8,69,85,80,80,5,
+
265 80,80,85,85,33,6,24,97,134,24,98,16,128,0,136,83,91,18,61,147,38,66,226,236,143,143,18,107,210,170,65,134,24,97,136,69,32,42,130,130,
+
266 168,42,170,144,132,24,97,134,24,97,134,33,20,0,17,30,246,196,143,62,200,92,92,93,145,241,226,91,122,65,72,48,195,12,49,8,170,170,170,10,
+
267 170,10,170,164,33,8,65,136,40,80,194,136,50,170,130,20,173,182,60,123,33,113,113,118,76,143,143,18,105,82,170,48,195,12,65,136,69,85,5,5,
+
268 5,85,85,85,85,34,144,131,12,65,134,24,138,171,161,77,52,72,241,236,153,50,100,124,248,150,205,42,65,72,65,136,49,8,69,34,130,168,2,128,
+
269 0,0,42,169,8,66,12,49,6,33,21,67,66,188,214,196,137,62,124,249,243,227,219,109,229,72,41,8,49,6,33,21,85,64,0,0,0,0,0,1,
+
270 85,84,138,66,16,132,85,85,13,10,247,182,36,120,241,231,199,137,18,105,165,77,72,66,16,132,34,170,168,0,64,32,1,0,0,85,85,33,20,132,
+
271 82,2,134,136,87,154,216,145,34,68,143,108,73,175,122,32,2,144,132,82,17,84,20,0,32,16,132,32,10,10,170,170,164,80,80,88,81,10,247,154,
+
272 219,98,91,18,217,166,188,169,0,85,34,145,85,65,66,1,8,4,32,16,5,0,85,85,85,85,80,130,34,21,239,53,182,219,109,179,77,121,81,2,
+
273 170,170,69,80,80,0,8,66,24,66,0,160,160,170,10,160,160,1,208,165,123,205,52,214,205,53,239,122,38,10,10,170,170,0,1,8,97,194,0,0,
+
274 10,160,170,10,10,1,13,16,165,123,205,52,211,77,123,202,136,128,0,10,170,160,0,1,135,134,16,128,2,130,168,40,40,0,4,18,133,43,222,243,
+
275 94,107,222,242,162,96,0,160,160,160,16,135,135,224,21,5,5,85,5,0,12,18,84,41,94,247,189,239,43,209,19,128,40,2,128,4,56,127,128,64,
+
276 1,64,0,20,0,2,29,16,165,41,94,242,188,165,42,34,96,0,160,0,1,15,195,240,128,0,2,128,2,132,3,210,84,41,74,242,149,232,84,68,
+
277 192,0,0,0,33,135,248,112,128,0,0,0,0,4,3,209,16,165,41,74,82,148,168,137,192,0,0,32,24,127,195,128,64,0,0,32,0,16,233,66,
+
278 161,74,82,148,168,84,166,16,0,0,132,56,127,14,16,0,128,4,2,31,162,33,74,133,41,80,168,148,132,0,32,1,14,31,225,132,32,16,0,128,
+
279 67,210,136,84,41,80,165,68,74,97,0,0,8,67,15,254,24,4,2,16,135,233,66,162,21,10,136,136,158,1,0,8,66,31,254,24,64,33,8,67,
+
280 210,136,136,133,68,66,209,56,66,0,16,135,255,225,225,8,67,15,165,40,136,84,68,162,120,64,32,16,225,211,240,240,195,14,31,210,136,137,68,68,
+
281 208,56,64,33,225,167,255,135,12,56,127,74,81,17,41,78,24,66,24,127,79,225,248,112,225,250,82,136,148,211,134,24,127,255,255,134,28,63,244,162,
+
282 82,159,195,15,15,79,255,225,195,135,14,154,82,137,167,225,195,255,167,135,240,225,225,254,148,166,154,67,195,225,167,255,252,56,120,127,166,148,167,255,
+
283 135,255,255,240,248,126,29,58,105,167,240,255,255,255,15,248,127,253,41,167,255,15,255,255,225,254,31,253,58,127,255,255,254,31,255,195,254,157,58,127,
+
284 195,255,255,135,255,225,255,167,79,167,15,255,225,255,255,255,255,79,79,225,255,252,63,255,255,195,211,211,255,255,255,15,255,250,7,255,244,253,63,135,
+
285 254,31,255,255,132,63,165,40,148,167,240,195,135,12,56,127,167,255,211,166,154,127,252,56,97,15,15,255,166,154,125,63,252,63,195,15,255,74,105,166,
+
286 144,248,97,255,135,15,195,253,61,52,233,233,255,195,15,14,16,134,26,120,122,82,136,148,68,68,166,159,132,32,16,0,0,0,252,0,0,20,3,4,
+
287 162,33,74,87,148,165,66,149,18,148,248,0,0,0,40,2,128,40,42,170,168,40,2,132,52,149,30,87,154,243,77,52,215,189,232,84,225,5,5,85,
+
288 85,80,80,85,85,34,145,85,65,64,0,3,232,133,43,222,105,173,182,107,102,154,247,149,19,0,5,82,42,170,170,145,84,132,82,41,21,85,65,96,
+
289 1,232,133,41,74,243,94,105,173,154,217,166,189,229,68,224,160,164,85,34,144,138,69,34,145,72,170,170,10,1,0,244,68,66,148,175,121,166,154,217,
+
290 166,154,107,222,84,76,0,21,72,170,69,34,144,138,69,34,169,20,20,0,0,2,16,165,16,165,123,205,123,109,154,219,102,154,247,149,19,5,5,34,
+
291 169,21,72,164,82,41,8,69,34,170,128,0,66,28,18,84,43,222,105,173,154,217,173,154,107,202,84,68,8,40,41,21,84,138,69,82,41,8,170,69,
+
292 85,80,0,0,0,0,13,17,30,247,154,219,109,137,109,182,205,52,175,68,193,64,138,164,82,42,145,84,138,69,34,145,85,84,21,84,1,64,2,20,
+
293 41,94,246,219,18,60,72,241,34,91,53,239,68,10,170,145,72,69,34,169,20,138,69,82,41,20,138,66,42,170,170,128,0,65,10,87,182,216,241,231,
+
294 217,31,30,60,73,175,42,64,20,138,66,16,138,66,16,138,66,17,72,164,85,85,33,20,132,34,170,168,6,133,41,173,143,62,124,93,147,38,67,199,
+
295 154,242,193,84,131,16,132,33,8,66,17,72,69,33,8,69,34,145,72,69,85,34,170,168,0,80,175,108,72,243,236,133,217,11,159,30,36,215,150,10,
+
296 164,32,196,24,132,33,8,164,33,8,66,17,72,170,170,164,33,8,164,34,128,5,16,175,52,72,147,231,217,50,100,200,120,150,205,42,85,72,66,12,
+
297 66,16,132,33,20,132,32,196,33,8,170,170,170,65,136,66,16,138,1,68,123,205,18,60,249,246,66,236,143,159,30,217,165,74,170,140,66,12,66,17,
+
298 72,66,16,132,32,196,33,20,138,170,66,41,8,69,34,128,104,133,53,177,35,217,50,100,201,147,33,226,77,122,32,42,144,131,16,132,34,144,132,33,
+
299 8,65,136,65,148,132,33,8,66,41,8,69,32,0,80,175,108,72,243,231,197,217,11,178,62,60,73,165,44,21,72,65,136,65,148,132,34,144,132,32,
+
300 196,24,132,33,8,66,16,132,24,98,17,85,116,121,162,79,178,100,118,46,118,201,145,241,38,189,32,164,32,196,24,132,33,21,72,164,33,8,66,16,
+
301 132,33,8,66,12,65,136,48,196,34,174,83,91,30,125,145,217,217,217,217,219,33,226,77,42,2,144,131,12,48,196,33,8,69,34,144,138,66,41,20,
+
302 132,24,131,10,24,80,194,136,66,0,2,33,173,137,62,200,92,244,236,236,237,145,241,230,189,0,8,48,194,134,24,97,136,66,42,145,85,72,170,170,
+
303 65,136,48,195,12,48,195,12,50,168,4,165,123,99,207,178,23,59,59,59,23,100,124,73,175,64,33,6,20,40,97,67,16,98,41,21,84,138,170,10,
+
304 170,164,32,195,12,40,80,161,134,85,0,66,148,209,34,79,139,178,59,59,59,100,200,251,102,190,4,32,194,133,12,40,97,136,66,42,170,170,170,145,
+
305 84,138,66,41,6,24,97,134,25,85,66,133,53,177,39,217,11,157,157,157,139,178,30,36,210,160,16,130,134,20,40,97,134,34,145,85,85,85,84,138,
+
306 170,170,69,24,97,66,133,12,49,8,160,136,83,91,30,125,145,217,217,217,216,187,35,226,77,42,1,8,40,97,66,134,24,98,17,72,170,170,170,170,
+
307 170,170,65,134,24,97,67,10,24,98,42,130,33,77,18,60,251,35,179,179,179,177,118,71,196,154,84,5,24,97,133,12,48,196,24,138,69,85,82,42,
+
308 145,84,131,12,48,195,12,48,161,134,34,168,101,121,162,71,178,100,118,118,122,46,46,200,123,102,150,4,32,161,134,20,49,6,34,144,138,164,85,34,
+
309 145,72,66,12,65,134,20,40,80,161,136,69,90,21,182,199,178,23,59,61,59,61,59,100,124,75,101,64,82,12,48,161,67,16,98,41,21,85,72,164,
+
310 33,8,69,33,6,32,195,10,20,40,97,134,34,133,30,104,147,236,133,207,79,79,79,78,217,31,108,210,192,132,24,80,161,134,24,98,16,132,82,41,
+
311 21,85,85,84,131,16,80,194,154,10,20,48,196,34,229,53,177,44,153,30,158,158,158,158,139,178,30,219,210,66,12,40,80,161,67,12,66,17,85,84,
+
312 138,170,160,170,164,24,97,134,20,40,97,66,134,24,128,178,189,177,44,133,207,79,68,34,19,209,118,67,205,122,1,8,40,80,166,131,10,24,132,34,
+
313 145,65,85,84,20,1,72,65,133,12,41,160,161,66,133,16,139,149,237,143,100,46,122,33,61,16,157,157,159,30,107,208,8,48,161,66,133,10,24,98,
+
314 16,138,170,170,160,160,10,170,65,134,20,48,161,133,10,24,98,42,172,165,108,73,246,71,103,167,162,19,211,182,67,219,122,72,65,66,133,10,20,48,
+
315 196,33,21,85,85,85,85,85,85,72,66,12,48,161,66,154,10,24,101,90,60,209,231,217,29,136,68,34,19,211,177,113,237,154,146,16,97,66,133,10,
+
316 24,98,16,138,164,85,85,34,130,169,8,65,134,24,80,195,12,48,195,17,65,17,230,137,62,200,236,236,244,244,236,92,248,246,222,128,164,24,97,66,
+
317 134,24,132,34,145,85,85,85,65,85,84,132,24,97,133,12,48,196,33,21,65,17,230,137,30,200,92,92,236,236,93,144,241,38,149,1,72,65,133,16,
+
318 98,16,138,170,170,170,170,170,10,170,164,24,97,134,24,98,16,138,160,8,134,154,36,249,241,118,66,226,231,207,137,53,229,129,8,65,134,32,196,82,
+
319 42,170,168,40,2,128,2,129,8,48,195,12,48,196,82,0,4,165,53,182,199,159,62,200,249,241,226,91,52,169,5,33,6,32,202,66,42,130,130,128,
+
320 40,0,42,170,169,20,132,82,41,21,84,2,133,121,173,137,30,124,121,241,226,68,154,242,165,84,132,33,8,66,42,130,128,40,0,0,0,40,42,169,
+
321 20,132,82,40,40,0,34,35,205,108,72,145,227,199,137,109,179,74,136,0,164,33,20,138,69,5,5,0,0,0,0,0,0,85,85,85,85,32,40,0,
+
322 80,165,52,214,196,137,30,36,75,102,189,233,170,169,8,69,34,168,40,40,0,0,66,0,0,10,10,170,170,160,160,1,66,149,230,182,216,145,45,182,
+
323 217,175,42,64,21,72,164,85,80,80,5,0,0,128,4,32,10,160,170,10,160,0,28,165,123,205,109,182,219,108,211,74,84,64,5,82,42,145,65,65,
+
324 64,2,0,16,128,64,1,64,20,21,64,0,57,81,239,53,179,91,108,211,94,82,164,0,20,138,170,10,10,0,1,0,132,32,0,0,10,10,0,0,
+
325 0,26,33,74,107,205,52,214,222,247,148,188,21,85,84,20,20,0,2,1,8,112,0,0,0,80,5,0,14,136,143,123,205,121,166,189,229,42,36,0,
+
326 21,65,65,64,0,0,33,8,67,8,0,0,2,128,0,7,68,66,189,239,53,239,123,202,133,192,1,65,84,1,64,32,24,97,132,33,0,128,40,0,
+
327 66,8,136,82,189,239,123,222,82,162,36,0,1,64,20,0,2,1,14,28,33,0,128,0,64,33,209,16,175,121,94,242,189,17,56,2,128,40,0,4,
+
328 2,24,112,240,132,32,0,16,14,136,133,43,202,242,148,165,79,0,0,0,0,0,8,67,15,135,8,64,32,16,250,21,10,87,148,165,42,39,128,0,
+
329 0,0,0,4,48,255,135,8,64,32,31,68,41,74,82,161,74,148,194,0,0,0,16,132,60,63,194,16,128,67,10,81,10,133,41,74,136,137,224,0,
+
330 0,1,0,134,31,255,132,2,16,194,148,68,66,149,10,136,137,194,0,16,0,134,31,254,28,33,8,67,210,133,68,42,21,17,62,1,0,0,132,48,
+
331 254,159,134,16,132,62,137,42,33,81,17,52,12,0,32,16,195,135,79,240,194,16,195,165,17,17,10,136,148,240,8,4,2,24,127,167,248,97,8,125,
+
332 40,136,136,136,148,240,132,33,12,63,255,225,134,28,41,165,17,17,40,159,132,33,134,30,26,127,225,135,15,165,40,137,68,255,12,48,248,127,254,24,
+
333 97,253,41,68,68,167,240,135,15,135,255,248,97,195,166,148,162,83,76,56,124,63,255,195,134,28,62,154,37,18,154,97,195,15,255,255,135,12,63,244,
+
334 162,82,159,195,195,255,255,195,12,56,116,233,74,38,159,14,31,255,255,225,135,15,244,166,148,255,240,255,255,252,48,225,255,74,83,79,248,127,255,255,
+
335 195,15,15,167,77,62,152,116,255,225,255,195,135,15,211,166,159,255,255,255,255,15,15,254,158,159,255,211,255,195,225,225,255,244,250,127,255,255,255,240,
+
336 255,135,211,233,254,9,253,63,248,124,60,63,253,62,159,15,167,255,255,240,255,193,63,211,255,255,211,252,63,15,135,254,159,79,225,211,255,255,248,127,
+
337 255,253,63,255,255,255,252,63,15,253,63,79,255,255,255,240,255,255,254,159,255,167,240,255,135,255,15,250,127,79,255,255,252,63,255,255,255,79,250,127,
+
338 195,252,63,254,31,233,255,211,255,255,248,127,255,255,255,79,233,255,195,248,127,225,255,167,255,79,244,240,255,195,255,255,255,253,62,159,255,15,195,252,
+
339 63,253,63,253,62,159,225,252,63,255,255,255,233,244,255,248,126,31,135,255,233,255,211,233,255,15,248,127,255,255,254,158,159,255,195,240,252,63,255,233,
+
340 253,61,63,225,255,135,255,255,255,233,233,255,240,255,15,240,255,254,159,211,211,252,63,248,127,255,255,254,158,159,255,15,248,127,135,255,244,253,61,63,
+
341 195,255,195,255,255,255,233,233,255,240,255,135,248,127,255,211,211,211,255,15,252,63,255,255,255,78,159,255,135,252,63,15,255,250,125,62,159,248,127,195,
+
342 255,14,159,255,167,167,255,240,254,31,195,255,250,127,79,211,252,63,240,255,255,255,250,125,63,254,31,225,252,63,255,79,233,255,255,255,195,255,255,255,
+
343 211,211,255,240,255,15,240,255,255,167,167,167,254,31,225,255,255,195,233,250,116,250,67,248,126,31,195,255,255,167,167,167,255,135,225,254,31,79,195,167,
+
344 233,211,233,225,248,120,126,31,255,253,62,158,159,255,15,135,240,255,244,255,233,211,255,254,30,31,15,255,253,63,79,167,255,195,225,252,63,250,127,244,
+
345 244,255,255,15,135,225,255,254,159,211,233,255,195,240,255,195,250,127,253,61,63,255,15,135,255,135,254,159,244,250,127,195,240,255,255,255,255,167,233,255,
+
346 225,240,255,193,63,255,254,159,211,252,62,31,225,244,255,255,167,250,127,248,124,63,15,250,127,253,63,167,252,63,15,225,255,167,255,79,244,255,248,126,
+
347 31,135,255,211,253,63,79,255,15,135,225,255,250,127,167,244,255,254,30,31,135,255,244,254,159,211,255,195,195,240,255,250,127,244,254,159,255,135,195,240,
+
348 255,233,255,211,253,63,240,248,127,15,254,159,253,63,211,255,225,240,255,135,250,127,244,255,211,240,255,15,255,255,255,167,255,79,225,255,135,255,255,255,
+
349 211,255,255,248,127,255,255,255,211,255,255,254,31,255,255,255,250,127,255,252,63,255,255,255,244,255,255,255,15,255,255,255,253,63,255,254,31,255,255,255,
+
350 167,255,255,255,195,255,255,255,253,63,255,255,15,255,255,255,211,255,255,252,63,255,232,31,255,250,127,255,240,255,255,244,15,255,244,240,240,255,166,148,
+
351 211,233,135,225,135,15,195,250,7,240,225,250,105,166,158,159,233,255,195,254,30,28,48,195,167,211,233,254,157,63,255,211,225,225,195,255,15,254,159,255,
+
352 211,255,135,79,211,248,127,211,248,112,135,255,233,135,250,125,63,240,79,77,63,135,14,28,56,83,165,63,135,225,167,135,255,253,40,148,77,48,225,225,
+
353 15,255,167,160,124,33,8,64,0,2,1,8,116,68,66,161,81,10,133,68,68,74,127,134,24,4,0,63,194,0,0,0,1,0,128,2,168,0,116,162,
+
354 34,34,34,33,81,10,82,149,229,41,74,84,68,194,0,0,0,16,0,128,40,2,128,40,0,0,4,56,97,132,32,0,16,209,17,16,168,82,149,229,
+
355 53,239,123,202,82,149,48,130,130,128,40,0,0,0,0,2,130,130,130,128,0,0,0,6,148,74,66,24,105,165,17,10,133,41,74,82,188,165,41,74,
+
356 84,68,224,10,10,160,160,0,1,8,0,40,42,130,168,2,128,0,116,162,74,148,167,135,162,33,74,133,43,202,87,149,229,41,81,48,0,80,85,0,
+
357 0,0,132,1,65,85,85,84,20,2,16,254,157,41,68,162,81,16,168,84,41,74,133,41,74,84,42,34,80,32,10,10,10,1,0,128,2,128,42,170,
+
358 170,130,128,4,3,74,34,83,211,209,40,133,66,148,165,41,74,133,41,74,84,42,38,0,0,160,160,170,0,0,0,0,10,10,10,10,10,1,8,126,
+
359 148,233,250,34,34,20,165,41,74,242,188,175,41,74,84,68,192,21,65,85,85,85,64,0,1,64,20,20,0,0,2,31,165,41,8,67,135,162,34,20,
+
360 165,43,222,107,205,52,215,189,229,42,64,21,72,164,33,20,138,170,160,160,160,160,0,0,16,254,148,78,1,0,0,8,6,20,68,41,94,105,166,182,
+
361 216,150,219,52,215,189,16,1,72,65,134,24,98,12,66,42,170,128,40,0,4,0,63,210,136,148,134,0,0,0,10,1,208,165,121,166,182,36,72,145,
+
362 45,137,52,210,151,5,32,196,20,48,194,134,24,132,82,2,168,40,0,0,6,20,162,34,21,17,41,240,8,0,40,40,0,104,87,188,211,68,182,60,
+
363 72,145,45,154,242,224,164,32,195,10,24,97,134,24,132,33,21,65,64,33,253,40,84,68,66,162,83,8,0,0,2,168,40,6,82,148,211,91,18,60,
+
364 72,241,45,154,242,164,20,132,24,130,134,24,97,136,66,41,21,84,1,96,1,133,40,136,133,68,68,68,167,192,0,0,1,64,52,66,189,237,182,216,
+
365 145,34,68,154,105,75,0,82,12,48,194,134,24,98,16,138,170,160,0,0,1,12,58,81,18,136,136,137,78,144,130,130,170,128,81,30,246,219,18,60,
+
366 72,241,45,154,242,193,84,131,12,40,97,134,24,138,64,80,5,0,80,0,8,97,166,136,148,68,248,67,0,128,0,104,82,189,182,219,30,36,120,145,
+
367 38,188,169,82,16,97,133,10,24,80,196,33,21,65,64,32,16,255,255,192,33,255,8,6,136,87,154,216,241,227,207,159,30,37,183,165,72,48,161,77,
+
368 26,52,104,40,80,196,34,128,0,67,135,250,34,34,112,134,0,0,16,0,85,80,12,175,120,145,39,217,11,139,178,100,124,73,165,128,195,52,118,208,
+
369 205,219,182,141,26,12,48,202,170,1,244,68,162,34,81,17,41,211,0,128,0,2,170,145,85,66,82,182,217,246,71,103,103,103,108,143,137,53,1,70,
+
370 104,209,217,153,153,155,183,110,197,10,24,132,80,0,250,34,34,34,34,21,17,19,64,192,2,24,0,0,40,44,16,165,109,177,236,153,11,139,139,159,
+
371 30,217,80,8,48,167,110,221,153,153,187,118,208,80,195,17,72,10,16,210,136,84,66,161,80,168,148,252,41,224,10,10,170,161,41,77,18,60,251,35,
+
372 177,118,71,199,154,244,2,12,209,163,179,51,55,102,109,26,52,24,98,17,64,0,52,162,33,80,165,42,21,18,148,240,134,156,0,1,64,2,136,246,
+
373 196,143,62,46,201,147,33,45,189,1,70,20,41,219,179,55,110,221,138,104,48,195,17,85,64,61,17,10,133,121,74,82,162,39,132,0,61,3,0,0,
+
374 0,161,94,104,145,236,153,11,178,62,37,178,160,40,205,5,59,118,102,237,219,70,130,133,12,69,32,40,7,209,16,168,82,148,165,42,34,34,66,1,
+
375 15,194,10,1,161,94,219,99,199,178,62,124,72,151,150,4,25,160,167,109,29,180,104,208,97,134,85,80,0,195,166,136,136,84,68,45,41,15,165,18,
+
376 144,0,5,13,10,243,91,30,60,248,241,237,154,84,5,32,194,154,52,104,208,80,161,68,33,20,20,48,233,165,18,136,84,68,68,240,0,0,254,16,
+
377 232,133,121,162,68,143,30,60,123,102,149,42,65,134,104,209,163,65,66,133,12,50,170,128,127,210,136,136,136,136,136,148,8,66,20,254,16,229,41,77,
+
378 108,72,145,35,219,53,232,128,164,24,97,77,5,10,20,48,196,34,168,4,62,157,40,136,136,136,136,148,225,195,225,8,116,71,148,214,219,109,182,205,
+
379 121,82,10,65,136,40,97,133,16,98,17,84,22,31,166,148,74,34,34,37,19,8,66,31,195,209,10,87,154,107,102,182,247,189,53,82,16,131,12,49,
+
380 6,34,170,168,0,7,253,41,68,68,68,68,68,240,135,195,135,162,33,74,243,77,121,175,121,104,0,164,33,8,66,16,132,85,0,0,135,233,233,74,
+
381 34,81,17,52,14,31,134,30,136,133,43,205,123,222,82,166,10,170,69,33,20,138,10,0,16,248,126,154,81,40,148,167,15,254,26,81,16,165,43,222,
+
382 87,162,36,0,21,84,138,170,170,0,176,135,254,26,105,74,37,41,255,225,253,17,10,87,148,175,66,240,5,5,82,42,130,128,0,127,255,13,52,210,
+
383 154,127,240,240,165,37,71,148,165,41,83,128,2,170,170,130,128,0,127,79,15,15,167,79,233,233,255,74,33,74,82,149,17,56,2,130,170,130,128,0,
+
384 7,255,195,250,105,77,63,255,250,81,16,168,84,42,39,0,5,5,5,5,0,135,233,211,135,233,233,255,252,63,209,17,16,165,68,68,225,0,80,0,
+
385 80,8,67,211,254,31,211,167,195,255,233,165,17,10,133,68,79,0,0,0,80,0,8,67,255,255,244,211,250,127,255,165,17,17,17,62,1,0,0,0,
+
386 0,195,233,233,135,233,244,255,255,195,211,68,162,34,105,8,66,0,16,135,254,156,62,31,233,255,211,255,165,18,136,148,225,8,4,2,16,195,211,248,
+
387 127,244,253,63,233,254,154,82,159,8,64,33,12,61,58,127,240,254,159,10,127,255,166,148,167,240,194,16,195,233,233,225,225,240,255,211,211,211,211,74,
+
388 83,225,132,33,8,97,233,244,240,255,233,255,250,127,78,157,56,97,132,33,15,233,166,159,255,240,248,127,250,125,52,211,248,97,195,255,211,255,15,135,
+
389 240,250,122,116,211,78,159,135,8,97,135,255,211,255,255,255,211,250,126,156,60,56,97,225,167,166,159,255,255,135,255,255,211,211,240,254,31,250,127,240,
+
390 252,63,254,159,167,167,167,195,225,195,195,254,159,255,255,255,244,253,63,248,120,112,255,233,211,233,135,255,135,255,255,211,255,255,15,255,79,255,225,255,
+
391 15,250,122,116,255,252,56,120,127,211,250,127,255,225,255,244,244,252,62,30,31,250,116,233,255,135,248,124,63,244,244,255,255,240,255,167,255,240,255,248,
+
392 127,79,78,159,255,15,15,15,244,255,254,159,255,195,255,79,255,225,252,62,159,79,167,195,255,240,248,127,211,233,255,255,240,250,127,248,127,255,255,253,
+
393 58,127,195,252,63,15,79,255,254,159,210,31,195,250,127,225,255,255,244,250,124,63,255,195,225,254,159,79,255,255,255,255,248,127,255,255,254,157,63,225,
+
394 254,31,255,255,255,167,255,225,255,211,255,248,127,255,167,255,255,255,135,195,254,158,159,255,255,255,248,127,255,255,255,253,63,255,255,195,255,255,255,167,
+
395 255,248,127,244,255,195,255,255,79,255,255,255,248,124,62,159,250,127,255,255,15,255,254,159,254,31,253,63,255,255,248,127,255,253,63,255,225,255,255,255,
+
396 167,255,255,255,255,255,225,252,63,79,244,255,255,255,240,255,255,211,254,31,250,127,255,255,225,255,255,250,127,255,225,255,255,255,233,255,255,255,130,127,
+
397 255,135,240,255,167,233,253,60,63,252,63,255,244,255,252,63,255,211,255,255,225,255,255,211,255,255,15,255,255,253,63,255,255,195,233,255,255,15,240,254,
+
398 159,211,255,255,255,15,255,167,255,252,63,255,254,159,255,248,127,254,159,255,248,127,255,255,250,127,255,255,135,211,255,225,255,255,255,233,255,255,255,195,
+
399 255,167,255,255,195,255,255,211,255,135,255,211,255,255,225,255,255,255,253,63,255,255,255,255,240,255,255,255,167,255,255,255,15,255,233,255,255,225,255,255,
+
400 255,255,255,244,255,255,255,135,255,195,211,254,159,255,255,255,255,252,63,255,255,255,167,255,255,248,127,244,255,255,195,255,255,255,244,255,255,255,255,255,
+
401 135,255,255,255,244,255,255,252,63,211,255,135,255,255,211,252,63,250,127,240,255,233,255,255,248,127,255,255,255,253,63,255,255,255,135,255,255,255,233,255,
+
402 255,255,4,15,211,248,127,255,167,255,225,255,255,255,255,167,253,56,127,135,255,255,255,255,233,255,255,255,255,135,255,255,255,211,255,255,225,255,79,254,
+
403 31,254,159,255,15,255,253,63,225,255,167,255,255,195,255,255,255,255,244,255,255,255,254,31,255,255,255,255,79,255,252,63,253,60,63,250,127,255,240,255,
+
404 255,255,255,211,250,7,255,4,130,120,39,130,5,3,224,144,79,64,160,39,255,193,56,32,32,36,30,117,48,14,166,40,196,109,210,103,152,2,25,25,
+
405 157,34,49,167,9,224,75,21,217,132,75,13,197,212,114,118,234,59,96,139,185,218,8,3,220,195,8,133,116,132,186,24,216,130,238,131,27,61,134,197,
+
406 96,29,89,135,7,59,139,132,93,156,102,228,123,153,25,163,51,132,186,26,154,226,17,0,112,207,57,56,15,2,51,128,230,196,29,184,79,92,198,110,
+
407 70,220,192,34,43,152,123,144,201,156,33,112,142,217,231,38,97,224,240,204,57,177,7,110,19,214,115,27,144,75,152,130,32,57,141,114,59,115,29,186,
+
408 7,110,115,155,48,240,192,96,157,24,131,129,4,66,206,99,114,9,115,43,144,28,198,136,134,110,99,183,64,237,174,115,16,24,12,38,97,201,206,99,
+
409 112,136,92,173,66,32,151,48,198,10,28,70,152,46,220,199,172,209,99,56,228,32,136,204,38,11,13,136,99,102,142,92,198,66,32,247,49,12,25,196,
+
410 107,145,160,180,46,205,117,103,28,196,19,195,9,192,195,115,152,220,35,151,43,83,144,75,148,80,136,130,209,172,215,108,225,119,67,171,156,230,193,48,
+
411 176,24,167,70,17,212,64,28,181,218,156,39,220,173,28,133,115,35,52,103,48,246,107,83,56,114,225,49,179,216,174,6,1,212,64,57,181,220,89,162,
+
412 238,87,102,11,197,162,136,130,156,199,220,142,46,83,152,130,117,98,29,24,44,243,8,128,112,103,11,29,2,238,102,142,71,139,72,34,10,115,31,102,
+
413 181,51,135,34,8,225,158,195,98,136,198,23,1,201,206,44,112,139,181,204,221,6,185,129,154,51,152,248,130,212,231,61,102,14,25,231,70,24,140,97,
+
414 96,156,24,142,34,9,219,57,219,145,236,235,53,92,167,220,142,46,113,200,130,56,98,56,24,172,35,171,48,224,196,22,8,34,236,230,142,131,92,192,
+
415 34,10,114,143,116,25,53,207,68,1,99,16,232,224,96,29,88,39,54,32,176,64,59,107,153,51,77,114,131,52,142,86,220,38,77,115,177,0,112,207,
+
416 57,48,196,102,3,128,228,231,28,58,14,220,206,220,141,185,128,193,35,148,123,53,219,148,237,154,234,207,57,48,76,44,6,99,21,174,59,102,158,179,
+
417 140,217,162,92,164,102,220,207,114,25,185,69,221,3,182,185,204,64,17,152,12,83,163,0,198,32,142,92,238,46,134,78,86,142,68,22,138,228,104,229,
+
418 100,225,22,49,7,46,3,27,8,232,116,97,14,24,34,23,59,139,160,251,148,83,53,25,197,116,10,107,139,184,69,140,243,131,48,194,120,112,28,152,
+
419 67,177,4,114,196,50,102,159,114,168,136,142,98,152,38,98,208,133,194,56,115,156,216,39,131,195,128,228,196,28,56,68,44,230,55,32,145,104,134,8,
+
420 11,77,136,134,110,83,183,64,225,136,115,112,48,15,14,3,155,156,112,225,59,114,153,51,91,56,149,154,162,211,110,70,55,40,229,194,234,231,58,51,
+
421 24,2,48,128,115,115,186,179,69,217,205,25,162,92,160,113,220,167,196,71,109,113,203,160,118,196,58,48,88,12,6,9,205,206,117,112,158,185,152,217,
+
422 163,197,161,140,21,22,155,17,12,197,161,11,52,112,215,57,8,12,38,19,48,228,215,49,186,15,69,163,38,104,145,105,68,64,56,155,48,76,156,167,
+
423 174,17,195,92,228,204,103,176,156,7,38,112,225,194,122,230,99,48,91,56,144,193,7,49,243,140,205,158,115,114,56,176,24,162,9,212,234,204,97,185,
+
424 199,14,19,211,137,169,200,246,176,142,65,157,38,220,141,71,16,133,154,117,103,48,196,6,123,9,194,114,103,14,4,67,177,104,204,193,109,210,1,110,
+
425 51,164,125,200,212,230,29,56,78,172,67,155,5,128,192,102,28,154,231,86,104,133,210,99,17,30,233,41,130,51,164,60,193,50,115,14,132,65,219,61,
+
426 130,225,48,157,89,174,6,16,176,193,28,179,140,204,17,46,145,12,17,143,55,185,24,221,33,119,65,213,204,114,16,25,236,65,0,232,206,58,185,4,
+
427 39,19,25,130,36,226,83,141,78,33,38,11,183,48,133,200,234,215,57,8,39,134,123,48,232,215,48,186,7,78,103,17,16,251,164,208,227,3,205,238,
+
428 67,39,72,93,154,59,22,142,78,134,3,16,64,102,49,12,102,9,209,206,100,35,196,46,85,48,6,156,79,17,237,26,195,230,8,237,210,29,56,88,
+
429 76,231,3,21,156,120,16,71,78,97,219,144,92,226,118,96,149,210,41,130,208,90,23,114,56,179,142,14,19,171,17,192,193,98,24,92,39,6,112,177,
+
430 200,46,45,52,114,60,90,1,16,97,105,182,107,136,180,33,16,14,173,115,147,129,132,192,16,14,78,113,219,144,114,206,118,35,207,179,158,34,145,202,
+
431 46,113,187,115,14,153,166,54,185,209,130,196,97,48,78,110,99,27,132,236,226,106,17,13,107,20,193,24,226,18,228,50,115,30,179,71,108,230,24,130,
+
432 120,103,184,88,172,225,195,144,114,45,49,152,35,221,37,56,193,172,108,193,50,107,4,34,33,213,204,115,16,88,140,71,3,13,202,120,114,30,156,77,
+
433 71,24,147,136,4,84,90,62,34,133,51,142,7,24,177,158,224,116,24,88,66,11,21,174,117,112,142,93,39,23,35,103,152,161,17,90,199,136,134,71,
+
434 16,187,52,118,229,57,184,79,12,246,99,21,174,99,116,14,156,172,98,33,241,104,135,28,90,52,68,104,45,11,186,5,142,81,208,130,35,49,24,167,
+
435 71,57,132,64,16,185,133,142,19,238,147,177,17,14,34,156,109,28,199,166,11,83,156,232,96,152,207,14,17,4,240,99,114,29,25,206,38,11,38,177,
+
436 161,130,167,156,68,50,60,217,51,71,14,99,128,130,120,115,176,92,14,113,25,154,112,115,56,136,135,206,33,71,26,28,70,152,34,133,163,177,16,88,
+
437 206,57,56,79,12,246,99,21,174,99,116,14,78,38,161,16,214,176,80,136,49,230,246,107,27,88,118,232,49,179,152,98,9,224,240,225,96,179,197,135,
+
438 25,201,206,208,192,11,185,144,71,161,196,36,193,99,56,133,217,166,17,104,230,204,98,49,24,44,55,48,140,228,61,56,156,76,17,39,153,5,185,29,
+
439 38,206,51,33,104,66,34,14,217,204,87,65,225,132,225,112,53,204,110,65,208,180,212,96,143,60,198,56,193,172,120,136,198,214,11,186,14,167,17,205,
+
440 152,196,98,49,88,108,227,11,144,116,229,50,17,226,238,82,152,6,218,236,132,113,25,195,161,110,44,107,157,4,22,3,93,192,116,115,48,4,19,214,
+
441 177,213,154,217,230,208,68,83,204,209,16,200,226,59,114,14,25,199,71,9,225,128,32,48,88,134,49,16,224,229,50,22,227,220,196,22,243,136,209,16,
+
442 204,90,23,102,142,28,167,6,99,61,206,197,57,185,79,2,1,219,164,44,116,54,233,12,113,163,152,72,138,25,206,115,17,230,103,134,97,130,56,58,
+
443 184,89,140,241,195,160,66,45,11,29,15,48,46,221,2,143,59,161,169,210,100,32,142,28,167,6,97,225,132,193,98,177,12,108,211,131,56,200,193,100,
+
444 230,81,110,130,208,147,141,163,148,66,228,117,115,156,153,135,134,19,128,228,206,58,136,7,103,16,177,194,107,88,209,154,51,88,246,107,24,180,122,205,
+
445 117,103,177,93,6,51,27,53,152,35,49,152,39,38,32,163,4,251,149,92,138,113,21,194,212,113,31,102,29,92,163,150,43,1,136,195,57,53,204,98,
+
446 9,235,57,141,154,61,202,67,5,28,173,152,34,153,194,22,107,139,16,232,32,29,79,12,22,27,60,198,225,16,185,154,157,13,139,66,153,170,113,21,
+
447 194,100,230,30,32,14,25,195,151,1,225,132,197,97,179,221,93,7,6,123,67,4,245,158,130,220,214,32,145,16,102,185,216,130,44,107,142,88,167,134,
+
448 121,200,224,231,48,184,15,92,174,34,0,151,48,167,69,202,246,107,70,184,187,161,197,158,115,16,14,162,51,5,134,192,29,136,35,167,57,147,52,123,
+
449 56,142,75,152,174,131,39,51,33,0,118,206,29,49,79,12,35,161,205,206,117,102,30,179,154,153,163,217,202,96,189,174,60,227,35,16,114,96,177,176,
+
450 142,78,19,8,140,224,58,49,14,172,195,215,48,176,65,108,226,104,232,83,136,174,131,39,43,39,11,171,92,230,204,48,158,24,44,54,16,237,194,58,
+
451 115,153,57,15,185,84,68,185,91,114,52,114,157,186,29,92,227,166,97,225,132,197,57,181,206,172,195,183,43,139,133,177,104,103,64,57,158,205,104,206,
+
452 61,102,181,48,142,142,17,193,140,64,98,136,206,174,129,203,156,201,208,37,204,65,4,5,164,112,153,57,143,136,3,183,56,229,130,35,48,24,103,38,
+
453 16,224,64,16,185,216,217,163,218,234,228,181,205,114,59,115,157,136,46,44,243,131,4,234,35,49,78,76,35,27,48,245,174,212,32,182,229,24,65,7,
+
454 41,68,19,54,185,241,0,88,196,29,56,12,102,22,41,208,240,44,112,142,152,78,220,140,152,128,205,71,59,220,45,26,231,217,142,172,65,11,12,194,
+
455 192,58,28,24,70,54,9,219,157,140,64,18,215,35,133,26,239,112,138,115,139,136,45,76,33,211,4,112,35,49,78,71,135,86,8,229,136,100,32,137,
+
456 115,138,112,217,200,32,180,103,31,102,11,24,130,22,25,140,240,115,57,158,7,14,1,11,60,200,65,100,207,86,107,217,237,179,72,207,23,16,88,216,
+
457 67,150,41,140,70,57,28,24,3,134,41,219,17,169,130,37,174,40,64,181,208,64,20,231,62,32,53,48,135,44,81,217,132,232,114,17,157,88,34,22,
+
458 17,155,48,251,16,130,9,92,229,16,69,49,15,179,28,88,71,172,83,25,224,230,112,60,14,24,167,108,246,166,96,151,56,194,10,57,222,225,25,158,
+
459 46,225,50,60,28,25,142,167,86,25,200,194,59,112,30,179,218,153,141,181,198,102,3,93,25,142,216,131,216,46,44,33,11,20,198,97,58,28,196,97,
+
460 219,4,245,128,100,32,15,103,144,65,43,156,209,4,83,60,248,128,212,194,28,177,71,6,19,145,192,240,59,98,158,177,24,217,141,181,198,16,1,174,
+
461 86,99,70,33,246,11,81,224,114,224,29,152,216,167,67,11,83,48,66,120,51,16,71,177,8,32,92,229,102,59,115,143,96,139,25,227,147,161,140,70,
+
462 57,28,15,3,183,1,219,60,201,152,61,136,65,5,28,230,136,2,153,236,153,140,108,1,203,20,118,117,58,28,196,103,87,1,235,60,201,152,219,16,
+
463 102,101,206,86,11,70,32,247,3,83,8,66,116,28,29,78,71,3,11,171,4,66,192,118,32,31,96,43,132,172,39,136,34,153,231,216,45,76,35,214,
+
464 25,140,70,57,142,143,3,182,25,219,61,141,130,37,136,48,129,98,20,64,20,207,100,193,99,60,14,88,110,167,83,145,192,234,234,197,16,176,12,153,
+
465 130,89,228,16,44,242,176,69,51,199,184,26,152,7,167,65,193,212,224,58,17,157,88,98,236,3,38,8,150,17,4,2,176,158,32,145,128,46,193,51,
+
466 17,132,44,55,83,25,192,116,97,117,58,29,176,24,216,173,179,198,112,89,232,193,20,194,18,224,99,60,8,78,131,179,25,204,224,117,22,48,207,79,
+
467 6,108,17,44,2,48,81,128,86,8,204,33,238,3,35,193,217,209,212,234,112,29,29,71,103,67,182,1,147,20,75,8,83,5,25,229,96,140,192,30,
+
468 193,50,48,136,88,110,38,51,145,192,112,44,97,158,158,12,156,2,88,66,152,40,196,71,0,166,16,150,43,27,0,236,232,234,117,29,28,14,174,172,
+
469 51,179,193,155,128,123,0,102,98,48,10,193,25,128,125,192,100,35,30,157,29,76,103,1,209,212,88,116,23,17,140,152,173,176,6,112,88,72,224,20,
+
470 192,30,195,99,17,142,206,142,163,131,129,192,198,226,195,61,48,187,112,15,60,43,129,24,5,112,10,60,9,97,177,136,194,231,39,83,168,232,114,117,
+
471 22,28,133,196,99,54,24,150,1,28,8,192,43,128,99,192,246,41,145,132,244,228,44,28,28,7,35,129,97,208,92,194,102,195,18,120,35,21,24,5,
+
472 97,140,120,18,195,99,48,139,156,197,134,49,208,132,112,44,57,11,152,93,176,196,152,85,192,130,51,220,3,24,71,176,204,142,167,103,55,81,216,228,
+
473 66,99,22,28,197,196,99,51,163,103,130,48,231,130,176,197,24,68,176,204,142,167,103,49,96,236,116,57,28,53,28,153,29,93,176,219,17,149,139,17,
+
474 138,197,24,70,18,116,50,58,139,156,221,71,99,145,9,141,196,230,200,194,236,232,104,140,70,26,8,197,97,144,194,61,134,102,99,61,57,184,186,142,
+
475 132,35,134,163,152,185,132,204,232,217,224,140,57,225,24,99,30,4,157,12,142,162,231,49,96,236,114,33,29,184,156,133,204,46,216,109,152,72,195,67,
+
476 9,88,99,24,68,157,12,206,167,103,7,17,216,228,66,56,106,56,50,58,153,157,13,48,144,232,2,49,78,130,140,35,206,70,70,51,179,155,139,168,
+
477 232,114,59,99,57,139,152,221,157,4,136,202,116,136,197,58,10,48,137,57,49,152,197,199,78,35,177,201,232,225,168,230,200,234,236,232,105,133,88,115,
+
478 9,88,99,24,71,156,140,204,103,103,7,17,216,232,244,118,212,115,100,117,118,114,108,194,67,164,194,135,65,70,17,39,35,35,24,184,233,196,118,57,
+
479 16,142,218,142,98,230,54,135,70,206,170,195,67,11,206,131,24,68,156,140,140,98,227,167,17,216,228,244,112,212,112,100,117,118,114,52,194,67,164,194,
+
480 83,160,199,81,39,35,49,192,185,193,197,212,114,122,234,212,112,100,56,118,114,108,194,167,36,48,161,208,99,171,103,35,51,27,35,131,136,236,66,33,
+
481 29,184,156,25,24,221,156,196,152,84,232,135,82,157,8,117,30,114,51,28,11,156,26,157,68,39,163,182,163,129,243,27,179,155,102,17,142,147,10,28,
+
482 136,117,108,230,236,198,46,58,106,117,16,136,93,90,142,2,230,55,103,38,206,164,57,33,213,14,131,29,68,156,204,199,12,142,14,46,162,19,215,86,
+
483 161,211,35,27,179,153,167,82,28,144,194,83,144,198,49,39,55,99,182,71,6,49,96,132,66,234,198,58,100,56,118,115,108,234,49,201,12,40,114,24,
+
484 234,217,204,204,112,200,114,212,44,61,61,117,99,29,31,29,187,57,182,99,33,201,14,165,57,144,198,36,224,236,118,200,116,212,44,61,61,117,99,28,
+
485 178,28,59,56,54,117,33,205,12,115,144,198,54,206,14,199,108,135,44,98,195,211,215,22,49,211,33,219,179,155,99,130,28,208,198,135,2,14,13,56,
+
486 59,28,31,28,177,186,158,157,139,24,199,39,199,110,206,13,152,200,115,65,194,28,200,56,108,224,208,118,124,114,100,44,59,61,113,106,28,178,29,187,
+
487 56,54,99,33,192,166,57,204,134,51,78,13,7,99,199,76,98,195,179,183,22,161,203,33,219,179,128,145,193,14,101,28,78,106,56,108,116,208,118,124,
+
488 114,198,44,59,59,113,106,16,178,29,187,29,54,56,24,224,83,26,28,8,56,108,116,209,212,120,233,141,196,236,237,197,140,114,125,213,216,232,72,224,
+
489 135,4,28,33,193,71,6,142,154,58,143,28,177,184,139,157,184,177,136,89,14,221,142,155,29,140,112,40,226,112,81,217,167,6,142,167,199,38,66,195,
+
490 179,183,22,49,11,33,219,177,211,99,130,14,138,99,65,210,142,13,29,52,117,30,57,50,22,29,157,184,153,8,79,186,180,29,54,59,32,232,163,132,
+
491 56,16,118,104,232,83,168,241,9,147,136,185,219,83,25,233,241,99,177,203,99,177,135,69,28,78,4,29,154,57,20,234,60,66,102,226,46,122,212,198,
+
492 33,100,234,208,114,216,236,135,4,28,32,233,71,6,142,154,58,143,16,153,56,139,139,181,49,136,79,186,180,28,182,59,32,232,163,185,193,71,102,142,
+
493 69,58,143,16,153,184,139,157,184,153,30,178,117,104,57,53,212,97,209,71,17,210,142,205,28,180,117,30,33,51,113,100,118,212,100,122,124,88,208,114,
+
494 36,118,67,129,71,113,210,142,205,28,138,117,30,122,102,226,200,237,196,200,244,248,177,216,229,177,217,7,69,28,32,233,71,102,142,154,11,7,136,76,
+
495 154,133,197,218,140,143,79,139,26,14,77,117,32,233,7,113,210,142,205,28,180,22,9,16,153,53,50,59,106,99,61,62,44,104,33,109,212,131,164,117,
+
496 142,149,212,209,200,161,96,241,9,147,83,35,182,166,51,211,226,199,99,147,93,72,57,40,238,58,81,217,163,145,66,193,231,166,110,34,226,236,102,71,
+
497 163,220,90,8,91,117,32,229,29,99,162,58,154,57,104,44,30,122,102,226,46,46,212,100,122,124,88,208,66,219,169,7,40,235,28,171,169,163,150,142,
+
498 35,207,76,218,133,197,216,204,143,71,184,180,16,154,234,162,20,117,65,10,186,154,33,20,44,30,118,102,212,46,201,140,200,244,123,139,65,11,110,164,
+
499 28,149,214,57,87,83,68,34,156,68,158,153,181,11,178,99,50,61,30,226,208,66,107,170,136,81,213,4,42,44,120,132,83,136,147,211,54,161,118,76,
+
500 102,103,163,220,90,8,91,117,81,202,58,160,133,93,77,16,180,113,30,118,102,212,200,93,168,204,236,123,139,65,9,162,194,14,81,213,4,42,44,52,
+
501 66,41,196,73,233,155,27,38,76,102,103,99,220,69,30,154,44,32,230,44,65,9,5,134,136,90,56,143,59,51,99,100,201,140,204,236,123,136,163,211,
+
502 69,138,33,65,98,8,85,197,226,17,78,34,78,204,216,217,50,106,51,59,30,226,40,244,209,98,158,160,177,4,42,44,52,244,83,80,147,183,108,108,
+
503 153,49,153,157,143,113,20,122,104,177,68,40,44,136,84,88,105,232,167,17,39,102,102,71,217,49,153,157,143,113,20,122,104,177,68,40,44,65,9,28,
+
504 77,61,20,212,36,236,205,141,147,38,51,51,177,45,77,15,77,22,41,234,11,16,66,162,195,79,69,53,9,59,51,50,62,201,141,216,184,246,161,71,
+
505 102,184,169,234,11,16,66,162,195,79,69,53,9,23,118,198,200,249,145,153,216,150,161,71,175,113,83,212,22,33,234,184,154,118,41,168,73,217,153,145,
+
506 246,76,110,197,199,181,10,59,53,196,130,27,140,66,70,167,158,138,106,18,46,236,200,251,35,35,49,113,237,66,142,205,113,83,212,113,136,85,197,231,
+
507 162,154,132,139,187,50,62,124,201,216,184,150,161,71,175,113,83,212,113,158,171,139,207,69,53,9,23,118,198,200,249,145,152,184,246,161,71,175,106,83,
+
508 212,113,158,171,83,206,198,106,18,46,236,200,249,243,39,108,132,177,138,59,53,197,79,109,83,213,113,52,236,83,27,98,238,204,143,178,50,118,200,75,
+
509 24,163,179,90,136,122,142,40,118,173,79,59,25,168,75,38,140,103,207,153,59,23,18,212,40,236,214,162,30,163,138,29,131,83,206,198,106,18,46,236,
+
510 200,249,243,39,108,132,177,138,59,123,82,157,163,84,236,26,158,46,51,27,98,237,12,135,159,51,118,46,217,144,161,115,90,148,237,26,167,106,212,243,
+
511 177,154,132,178,104,100,60,249,147,177,118,216,198,23,123,25,14,209,169,14,213,169,231,99,49,182,46,208,200,249,243,38,140,132,177,138,23,53,169,78,
+
512 209,197,14,213,169,226,227,49,182,46,236,204,121,243,55,108,132,177,138,23,53,169,78,209,170,118,13,79,23,35,80,150,77,12,135,159,51,118,200,75,
+
513 24,163,183,177,144,237,26,167,96,212,241,113,152,196,178,104,100,60,249,155,182,66,76,133,11,154,212,162,232,199,23,6,167,139,140,198,219,38,134,99,
+
514 199,153,180,62,36,200,80,187,216,212,92,173,83,176,106,120,185,24,219,100,208,204,120,247,110,207,137,50,20,46,246,53,23,70,56,184,53,60,92,102,
+
515 54,217,52,51,30,61,219,182,77,153,12,200,214,53,23,70,56,184,49,189,145,24,219,100,208,204,73,243,55,108,155,50,25,147,216,212,93,24,231,106,
+
516 198,246,68,99,109,147,67,49,227,221,180,62,217,152,161,119,177,168,186,49,197,193,141,236,134,50,108,248,163,49,35,221,180,62,217,144,204,158,100,172,
+
517 144,202,46,12,101,23,24,201,182,77,12,199,137,118,208,251,102,67,50,123,26,139,163,28,92,24,222,200,99,51,89,52,51,30,61,219,67,237,153,12,
+
518 46,246,48,100,134,81,117,50,43,34,25,54,125,163,177,35,204,218,31,108,200,102,79,50,86,72,198,140,129,141,236,136,100,217,246,142,196,143,118,208,
+
519 251,102,99,31,121,146,139,204,172,128,200,172,136,100,105,241,78,196,137,104,208,123,102,99,50,121,146,178,67,40,186,153,149,145,12,155,62,209,216,145,
+
520 238,218,15,108,204,102,69,50,86,72,101,100,6,69,100,49,153,167,197,59,18,37,216,161,237,153,140,201,230,74,47,50,67,224,100,243,228,50,108,120,
+
521 167,98,68,180,104,61,179,49,153,60,201,89,33,149,144,25,60,249,12,205,62,41,216,145,45,26,31,52,204,135,222,100,172,144,202,201,76,138,200,99,
+
522 51,79,180,118,36,75,70,135,205,118,49,247,153,171,36,50,178,3,39,159,33,153,167,197,59,18,37,216,161,237,153,140,125,230,106,125,12,144,248,25,
+
523 60,249,12,205,30,41,216,145,45,5,15,53,216,199,222,102,172,166,118,74,102,83,228,51,52,120,167,98,68,180,104,61,179,50,31,41,154,178,67,43,
+
524 32,50,121,242,25,154,60,83,70,196,180,20,60,215,99,31,121,154,159,67,36,62,6,69,62,71,102,143,20,236,72,150,130,135,154,236,99,239,51,86,
+
525 83,59,32,50,120,242,59,52,120,167,98,91,104,40,121,166,100,30,243,53,62,134,115,224,102,83,228,118,104,241,77,27,18,208,80,243,93,144,249,76,
+
526 192,252,206,124,12,202,124,134,102,143,20,209,177,45,5,9,53,217,7,188,205,79,161,156,248,59,40,245,51,52,120,206,196,182,40,80,147,93,144,123,
+
527 204,212,250,25,207,171,180,62,71,102,137,25,163,98,90,10,30,107,178,15,121,154,159,67,57,240,51,41,242,59,120,241,77,27,18,208,80,147,93,144,
+
528 123,204,212,250,25,207,131,180,62,71,102,143,25,163,109,138,20,37,183,100,30,87,106,61,12,231,192,204,163,200,236,209,35,52,109,182,131,9,53,217,
+
529 7,188,204,7,163,185,240,51,41,242,59,52,72,205,27,108,80,161,38,187,32,242,187,81,232,103,62,6,101,30,174,205,18,51,70,219,20,40,121,174,
+
530 200,60,174,192,122,25,160,240,118,81,42,236,209,35,52,109,182,131,9,123,66,9,123,181,30,142,227,193,217,71,145,163,196,140,40,209,45,6,18,246,
+
531 132,30,87,106,61,29,199,131,180,30,174,205,18,51,70,219,20,40,73,173,8,60,174,192,122,59,143,7,101,30,70,143,18,48,163,91,20,40,73,174,
+
532 200,60,174,212,122,59,143,7,104,61,93,154,36,102,141,182,40,80,147,90,16,75,221,128,251,184,240,104,131,200,209,226,70,20,107,98,134,108,214,132,
+
533 18,86,138,61,29,199,131,178,143,35,67,68,140,209,182,197,12,217,173,8,36,173,20,125,218,9,6,136,60,141,30,36,97,70,182,40,102,205,104,65,
+
534 37,104,163,209,220,120,59,40,242,52,120,145,133,26,216,161,155,53,161,4,149,162,143,180,143,7,101,30,70,134,182,65,70,182,40,102,205,104,65,37,
+
535 104,163,237,34,65,161,68,145,163,196,140,40,211,69,12,37,237,20,73,90,40,251,72,240,118,81,42,209,226,70,20,217,162,134,18,246,138,36,174,192,
+
536 74,59,65,32,209,4,171,71,137,24,81,173,138,25,179,90,40,146,187,1,246,145,32,208,162,72,41,237,140,40,214,197,12,217,173,8,36,173,0,74,
+
537 59,143,6,136,37,90,60,72,194,141,108,80,205,188,81,4,149,160,9,71,104,36,26,32,149,104,241,35,10,53,177,67,54,241,68,18,86,128,37,26,
+
538 68,131,66,137,86,143,108,130,141,52,97,155,120,162,54,86,128,38,210,38,209,4,171,71,182,65,70,154,48,205,188,81,4,149,160,9,138,137,6,133,
+
539 18,173,30,217,5,26,104,162,26,107,69,108,173,0,77,164,77,162,9,81,69,108,130,141,108,81,13,53,162,182,81,74,37,26,68,131,66,182,162,138,
+
540 217,5,26,104,195,54,241,74,217,90,0,148,105,18,13,10,218,138,121,164,25,230,140,67,94,41,91,43,64,19,105,18,2,144,74,138,43,100,25,237,
+
541 138,35,111,20,65,37,104,2,109,17,176,20,141,168,167,154,65,70,154,48,205,188,81,4,160,160,19,21,110,208,173,168,162,182,65,158,104,196,53,227,
+
542 17,178,138,6,226,173,218,21,181,20,86,200,40,211,70,33,175,20,173,148,80,54,141,34,64,82,54,162,158,105,6,121,163,16,215,138,86,202,41,68,
+
543 197,68,128,164,109,69,60,210,12,243,70,33,175,20,173,160,160,109,5,91,1,72,216,10,43,100,20,105,163,12,219,197,43,101,20,13,163,68,108,5,
+
544 35,96,40,173,144,81,166,140,51,101,24,141,148,80,55,21,108,5,20,208,20,86,200,51,205,24,134,188,82,182,130,129,180,21,108,5,21,181,20,243,
+
545 72,51,205,24,134,188,82,182,81,64,220,85,176,20,86,212,83,205,32,207,52,98,26,241,148,210,138,6,226,173,197,35,106,40,173,144,103,154,49,13,
+
546 120,165,108,162,129,184,171,96,50,26,2,138,217,6,121,163,16,215,138,86,202,40,27,138,182,2,138,104,10,43,100,25,230,140,67,94,50,154,81,64,
+
547 220,105,177,72,218,138,121,164,25,239,33,13,40,202,105,69,3,104,42,216,12,134,128,162,182,65,158,104,196,53,227,41,165,20,13,198,155,20,141,168,
+
548 197,52,131,60,209,136,105,70,86,208,96,53,5,91,1,144,208,24,166,144,103,154,49,13,120,165,109,6,3,80,85,176,25,13,1,138,105,6,121,163,
+
549 16,215,140,166,160,192,106,10,182,3,33,160,41,230,144,103,154,49,13,41,8,218,12,6,160,171,96,50,26,3,20,210,17,239,33,30,241,148,212,24,
+
550 13,65,86,192,100,53,70,41,170,51,222,66,26,82,41,168,48,26,130,173,128,200,104,12,83,72,71,188,132,123,198,83,80,96,53,5,77,140,134,168,
+
551 197,53,70,123,200,67,74,69,53,6,6,227,77,1,144,208,24,166,144,143,121,8,247,140,166,160,192,106,10,67,64,100,52,6,43,212,103,188,132,52,
+
552 163,41,165,24,13,141,54,50,26,164,67,84,133,121,21,239,25,77,66,1,177,166,197,33,160,49,77,33,30,82,43,202,69,121,70,3,99,77,140,134,
+
553 169,10,245,33,94,69,121,72,166,160,192,106,13,52,6,67,64,98,189,72,87,145,94,82,41,168,48,26,131,77,1,144,208,24,175,82,60,170,71,148,
+
554 138,106,12,6,160,211,64,100,53,72,87,169,10,242,43,202,69,121,70,3,99,77,140,134,169,10,245,33,94,69,121,72,166,160,192,106,13,52,8,143,
+
555 2,33,170,51,222,66,60,164,83,80,96,53,6,190,50,60,6,43,212,143,42,145,229,32,61,8,6,201,124,100,52,6,43,212,143,121,8,242,145,77,
+
556 65,175,65,166,128,200,104,12,87,169,10,242,43,202,69,121,70,3,100,190,50,26,164,43,212,133,121,21,229,34,188,163,1,178,95,25,13,1,138,245,
+
557 35,202,164,121,72,175,40,192,108,151,201,52,6,43,212,133,121,21,229,34,154,132,7,160,211,64,147,84,133,122,144,175,34,148,164,7,161,1,232,52,
+
558 216,200,240,33,94,164,121,84,143,41,1,232,64,122,13,52,8,143,1,138,245,33,94,69,121,72,175,40,192,108,151,198,71,129,10,245,33,94,69,121,
+
559 72,175,40,192,108,151,201,52,6,43,212,133,121,21,229,34,154,132,7,160,215,201,53,72,87,169,10,242,43,202,69,121,70,3,100,190,50,26,164,43,
+
560 212,133,122,145,229,34,188,163,95,37,242,77,82,21,234,66,188,138,244,85,122,18,249,47,145,30,4,71,170,148,170,71,148,138,244,32,27,37,241,145,
+
561 224,66,148,8,82,170,188,164,87,148,128,249,47,145,30,4,71,169,10,245,35,202,64,41,70,190,75,228,188,8,87,169,10,245,35,202,69,122,16,30,
+
562 132,188,8,143,2,35,192,133,121,21,229,32,61,8,15,66,94,4,71,129,17,234,66,188,138,242,145,94,132,7,161,47,2,35,192,136,240,33,94,69,
+
563 121,72,5,41,1,242,95,37,224,66,148,8,82,170,188,164,2,148,128,249,47,145,30,4,71,170,148,170,165,41,0,168,160,249,47,146,240,33,74,4,
+
564 41,85,94,138,175,66,95,37,242,94,4,41,64,133,42,171,209,64,165,32,62,160,249,17,224,68,120,16,165,85,41,72,15,66,3,228,188,8,143,2,
+
565 35,213,74,85,82,148,128,244,32,61,9,124,136,80,84,122,169,74,170,82,144,30,132,7,201,124,136,89,17,234,165,42,169,74,64,42,18,249,47,5,
+
566 188,8,82,129,10,85,87,162,171,208,151,201,124,151,130,161,65,74,85,82,148,128,84,37,242,95,37,224,168,245,82,149,84,165,32,61,8,15,168,62,
+
567 68,40,42,20,8,82,170,148,164,7,161,1,245,150,68,120,16,165,5,41,85,74,82,3,208,128,250,203,34,20,21,30,170,133,80,42,40,21,9,124,
+
568 151,200,133,5,66,130,161,85,74,85,87,161,37,66,94,10,133,5,71,170,148,170,165,41,0,168,160,249,47,145,10,10,133,2,20,170,165,42,171,208,
+
569 146,161,47,145,11,34,61,84,165,85,41,72,5,69,2,161,37,173,224,66,148,21,10,160,84,80,42,40,62,68,44,136,80,84,40,41,81,64,168,160,
+
570 84,36,168,75,193,80,160,168,80,84,42,129,81,64,168,160,249,47,5,66,130,161,65,80,170,5,69,2,162,131,235,44,136,80,84,40,42,21,64,168,
+
571 160,84,36,181,150,183,130,161,65,80,170,5,69,7,214,90,203,89,100,66,130,161,84,10,138,5,66,75,89,107,120,42,20,21,10,160,84,80,42,40,
+
572 62,178,200,133,5,66,130,161,84,10,138,5,69,7,214,90,202,10,133,5,42,40,21,20,10,138,5,173,224,168,80,84,40,42,21,64,168,160,84,80,
+
573 125,101,5,66,130,161,84,16,170,8,85,2,161,37,69,150,178,213,10,160,133,80,68,89,107,44,151,130,203,84,64,82,160,2,21,64,168,160,84,89,
+
574 100,66,130,161,65,74,138,5,69,2,162,129,80,151,130,161,65,80,160,168,85,2,162,129,107,45,101,173,224,168,80,82,160,41,81,65,245,150,183,130,
+
575 161,65,81,1,74,128,165,69,2,162,203,89,106,137,89,65,81,1,81,20,11,89,107,45,101,169,74,10,82,168,21,0,10,139,45,111,0,148,1,16,
+
576 20,168,160,84,80,68,80,45,101,172,160,8,85,4,42,130,34,130,33,41,80,44,136,149,68,0,42,0,21,0,10,129,44,37,170,22,165,72,33,84,
+
577 10,138,8,138,5,5,148,22,80,84,64,4,64,4,64,2,162,203,89,107,40,42,32,42,21,65,17,65,17,64,181,148,2,88,33,66,133,0,42,0,
+
578 21,0,10,139,40,4,160,168,128,168,128,168,138,5,69,2,194,80,9,106,133,0,66,168,21,20,17,20,18,74,73,40,44,160,165,64,4,42,202,139,
+
579 42,42,22,23,128,33,64,16,170,5,128,34,45,43,40,4,160,8,128,5,64,2,162,129,81,64,176,2,214,128,168,138,168,138,169,80,74,129,107,44,
+
580 16,160,5,72,20,160,5,40,3,225,42,4,181,66,130,162,0,80,21,17,64,176,162,44,176,148,21,16,21,16,1,32,169,80,74,130,86,80,84,64,
+
581 4,64,2,160,81,2,88,95,4,124,10,88,21,0,17,20,18,160,80,0,40,4,160,8,128,5,64,2,160,1,107,64,90,1,40,11,69,13,85,32,
+
582 8,129,44,37,170,20,1,10,20,46,242,209,229,4,124,41,92,23,5,160,2,64,11,9,97,74,208,22,138,180,80,68,90,66,136,180,168,34,168,85,
+
583 82,0,136,18,166,106,35,205,41,94,105,80,175,130,34,172,8,176,32,65,65,1,65,0,40,0,136,0,136,20,64,165,105,90,87,5,72,42,84,53,
+
584 84,5,164,16,169,43,202,134,154,82,154,244,71,148,37,5,10,144,36,80,5,93,85,42,9,0,44,37,132,186,22,5,64,4,168,107,74,208,23,85,
+
585 10,174,160,136,18,150,83,94,87,154,242,189,229,148,160,26,146,4,80,2,4,9,130,210,168,128,8,129,66,133,16,41,9,97,64,4,128,37,66,10,
+
586 176,85,130,130,65,11,66,188,165,52,210,148,215,162,61,2,128,161,82,0,1,2,171,168,96,9,10,114,232,154,32,83,4,69,224,8,11,170,173,72,
+
587 21,92,37,74,61,232,83,94,87,154,84,43,210,136,1,5,36,8,176,85,64,80,214,128,8,128,5,64,149,1,10,128,136,129,74,224,180,85,130,172,
+
588 8,176,32,107,46,87,162,60,210,188,211,74,87,189,37,64,8,17,65,72,0,170,21,13,65,33,72,81,2,93,11,161,66,136,0,136,180,0,10,170,
+
589 130,145,65,72,21,10,111,42,20,215,189,237,154,87,154,84,41,97,169,1,72,170,4,88,42,234,26,210,18,132,168,146,150,133,46,88,80,0,32,176,
+
590 85,0,82,2,145,65,72,16,4,42,35,222,247,182,217,175,108,215,189,229,74,85,64,132,32,16,101,5,32,2,168,84,18,0,93,10,146,149,17,30,
+
591 148,46,136,0,149,8,42,212,101,2,12,170,66,40,40,82,134,188,166,137,108,214,196,137,123,102,189,10,80,0,82,12,164,20,50,144,98,42,145,64,
+
592 20,16,1,11,66,149,16,175,163,209,16,165,161,82,136,11,5,85,2,12,170,49,20,132,34,170,175,71,148,173,182,107,98,68,182,219,109,188,175,40,
+
593 4,8,69,32,162,16,97,149,70,34,130,168,64,17,40,82,202,242,161,94,136,87,162,21,16,17,1,96,69,0,34,130,140,160,49,8,164,25,65,65,
+
594 17,10,105,175,52,123,109,182,61,183,154,107,209,16,20,20,98,16,130,134,33,6,34,169,20,0,1,52,68,66,189,10,87,161,74,84,71,162,33,122,
+
595 1,1,72,50,128,196,85,24,132,81,149,85,67,68,53,239,109,182,219,30,37,179,91,108,165,42,0,84,132,33,5,12,65,134,34,144,128,170,184,80,
+
596 180,121,80,175,122,21,229,66,149,37,46,144,8,17,84,131,12,163,12,66,16,101,82,40,66,82,149,237,182,107,99,196,182,36,73,175,53,233,212,138,
+
597 163,12,66,10,25,72,66,42,145,96,0,137,66,149,10,242,148,175,42,61,17,10,148,72,106,69,82,17,84,98,41,8,69,82,40,0,2,36,166,189,
+
598 237,137,109,177,226,91,53,179,74,133,69,0,32,196,32,195,12,163,12,69,33,20,21,125,11,41,74,82,188,168,242,149,10,84,68,44,18,160,160,50,
+
599 170,140,164,32,196,81,136,64,34,251,222,83,68,137,108,72,241,45,137,108,215,148,168,0,4,33,8,48,162,16,80,202,65,136,170,171,0,162,74,82,
+
600 163,202,82,188,165,41,74,136,82,229,128,85,85,70,25,72,48,196,81,136,170,69,0,9,74,87,182,219,98,71,137,18,60,121,166,154,244,192,138,65,
+
601 133,12,65,66,134,32,195,42,144,128,10,9,162,21,10,242,148,166,148,175,121,80,175,162,36,53,80,81,136,164,24,132,32,162,40,196,32,17,116,67,
+
602 77,52,72,241,226,79,159,30,37,182,205,66,160,17,84,97,67,12,41,160,196,20,49,8,49,20,8,24,33,81,30,242,149,239,41,94,244,43,222,82,
+
603 188,186,2,168,16,132,32,194,136,48,194,136,48,195,41,21,122,26,243,68,143,18,60,251,33,227,199,137,53,239,74,130,138,24,97,154,10,20,40,80,
+
604 195,12,49,20,138,0,0,136,136,242,149,239,121,94,105,74,247,148,165,42,34,36,0,8,66,16,97,136,48,195,16,97,134,82,12,160,0,133,123,219,
+
605 18,36,75,35,227,207,159,30,107,102,151,144,131,16,83,65,66,133,52,24,97,67,16,131,40,40,105,41,74,87,154,87,188,210,189,239,41,94,84,68,
+
606 192,20,132,82,16,138,48,195,16,97,136,66,17,84,128,136,143,108,214,199,143,30,60,251,33,45,137,53,229,74,170,140,40,80,194,154,10,24,80,195,
+
607 16,97,149,84,3,161,80,175,121,94,107,202,247,188,165,52,168,82,250,170,168,196,33,6,33,8,48,202,48,196,82,17,64,47,123,219,18,60,73,243,
+
608 231,207,137,30,36,215,149,0,0,97,134,24,80,161,66,133,10,24,97,134,82,16,0,2,137,41,74,87,154,87,188,210,189,239,41,74,84,164,0,20,
+
609 132,81,134,33,6,24,131,12,49,8,49,21,86,143,43,109,137,30,61,145,243,231,207,137,53,183,151,82,16,97,133,10,20,40,80,161,134,20,66,16,
+
610 96,80,90,101,41,74,247,149,230,188,165,121,81,229,68,42,39,5,82,12,49,8,48,196,32,196,82,16,128,164,209,30,107,102,143,30,36,121,241,34,
+
611 91,109,229,68,5,85,24,97,136,48,162,12,48,202,65,136,10,171,133,17,10,242,163,222,82,188,165,41,74,84,41,116,0,80,85,85,33,8,66,12,
+
612 164,33,21,72,161,4,43,222,107,98,91,18,60,75,109,182,105,74,144,5,33,20,97,134,33,6,33,20,101,85,80,0,4,208,165,66,149,232,87,149,
+
613 10,82,161,94,146,160,64,21,85,72,170,66,17,72,69,85,32,2,130,34,20,211,77,52,75,109,137,109,183,189,233,192,138,164,24,138,49,8,164,34,
+
614 170,168,2,130,65,16,168,143,42,60,165,71,149,16,168,136,158,10,0,10,160,164,85,34,170,169,1,65,122,60,175,52,214,205,109,182,222,107,209,18,
+
615 10,10,66,41,8,69,82,42,170,128,2,240,68,73,74,136,242,162,20,178,149,17,19,72,0,0,40,42,170,170,170,170,168,40,4,40,82,148,215,154,
+
616 246,205,53,239,122,33,96,21,85,82,17,85,72,160,170,0,161,134,148,42,34,20,168,133,68,42,34,33,116,194,10,160,170,160,170,160,170,0,11,133,
+
617 17,17,229,123,205,123,222,247,161,81,3,80,80,82,2,170,168,42,128,44,33,77,17,37,44,168,90,21,40,154,36,40,0,21,0,85,0,80,80,0,
+
618 0,0,242,149,10,242,189,239,121,74,84,74,0,5,84,20,21,65,84,0,0,32,30,137,68,73,81,17,17,40,137,78,144,192,0,1,64,21,64,0,
+
619 2,1,130,34,74,82,148,175,41,74,82,162,97,0,80,5,0,5,0,0,0,128,126,148,74,34,34,37,17,52,211,240,10,128,0,0,0,0,64,48,
+
620 166,136,133,66,148,165,42,21,19,192,0,0,1,64,0,2,1,12,18,9,77,18,136,148,77,19,78,144,132,2,0,0,0,16,0,135,10,37,10,136,
+
621 82,149,10,90,80,48,0,0,0,0,0,128,97,195,78,148,165,17,52,77,52,248,6,161,0,0,0,192,56,38,136,136,136,84,66,162,34,120,66,0,
+
622 0,1,0,132,56,125,52,165,41,68,211,167,195,0,128,6,1,128,112,160,81,40,136,136,84,68,77,33,128,4,2,16,8,67,240,78,148,166,137,211,
+
623 79,72,112,8,6,1,0,225,250,81,40,84,68,68,211,192,33,0,128,66,24,127,211,74,105,74,116,255,14,1,128,66,24,97,166,148,68,74,34,37,
+
624 60,33,0,192,48,195,255,233,77,52,233,208,63,132,33,132,48,225,72,37,41,74,34,81,62,24,96,24,7,15,254,157,58,83,211,255,12,33,134,28,
+
625 63,210,148,74,82,159,195,0,195,135,240,79,233,211,167,255,248,112,225,195,255,77,41,74,122,67,132,48,195,255,253,58,126,159,255,15,195,135,135,244,
+
626 210,154,83,252,48,225,195,255,233,250,127,79,255,15,15,135,255,211,74,116,240,225,195,130,67,244,10,127,79,233,4,252,18,31,135,135,255,167,77,63,
+
627 240,225,255,130,96,159,253,63,167,252,18,28,60,63,255,77,52,255,225,195,255,255,254,159,255,208,63,195,240,255,160,39,78,159,240,225,255,255,255,79,
+
628 255,255,254,31,135,254,157,58,127,135,135,255,255,255,79,254,129,76,18,31,135,135,254,158,158,159,15,135,255,255,253,63,255,255,252,63,135,233,244,244,
+
629 240,252,63,255,255,254,159,255,208,63,240,240,255,167,211,255,254,31,255,255,254,159,255,255,240,254,9,10,127,79,255,240,255,255,255,244,255,254,129,255,
+
630 135,240,253,62,159,255,240,255,255,255,244,254,159,240,252,63,135,232,9,233,255,254,20,15,255,255,250,127,244,13,3,248,127,4,134,159,211,255,252,63,
+
631 255,255,253,1,63,253,33,252,63,240,164,41,250,127,255,194,129,255,255,250,2,127,255,255,195,255,255,211,255,252,63,255,255,253,63,255,255,225,255,255,
+
632 253,63,255,225,64,255,255,250,127,244,10,67,252,16,63,252,19,253,63,255,193,33,255,255,244,255,255,255,135,255,255,244,255,255,225,255,255,255,79,253,
+
633 48,72,127,15,254,9,255,211,255,255,225,255,255,233,255,164,40,31,225,255,255,253,63,255,240,64,255,255,253,63,244,248,127,15,252,19,255,211,255,255,
+
634 248,127,255,250,127,164,18,31,248,127,130,66,159,244,255,255,252,63,255,253,63,250,7,252,63,255,255,167,255,255,240,255,255,255,79,255,255,135,255,255,
+
635 250,127,255,252,63,255,255,167,255,255,135,255,255,211,255,255,224,129,255,255,250,2,127,255,252,63,255,255,211,255,254,9,13,3,255,255,211,255,255,225,
+
636 255,255,254,144,79,255,248,82,20,15,255,250,127,255,255,15,255,255,167,255,255,194,129,255,255,254,159,255,255,15,255,255,160,39,255,255,194,129,255,255,
+
637 250,2,127,255,224,129,255,255,244,255,255,130,67,255,255,253,63,255,255,4,15,255,255,167,255,255,135,255,255,211,255,255,254,31,255,254,159,255,195,255,
+
638 255,253,63,255,255,252,63,255,255,211,255,254,31,255,254,159,255,255,254,31,255,255,211,255,240,255,255,79,255,255,254,31,255,255,255,64,167,255,195,255,
+
639 254,128,159,255,255,240,164,48
+
640 };
+
641 #endif /* UMPAH_H_ */
- - - - - - - diff --git a/extras/doxygen-style/html/nav_f.png b/extras/doxygen-style/html/nav_f.png deleted file mode 100644 index 72a58a529..000000000 Binary files a/extras/doxygen-style/html/nav_f.png and /dev/null differ diff --git a/extras/doxygen-style/html/nav_g.png b/extras/doxygen-style/html/nav_g.png deleted file mode 100644 index 2093a237a..000000000 Binary files a/extras/doxygen-style/html/nav_g.png and /dev/null differ diff --git a/extras/doxygen-style/html/nav_h.png b/extras/doxygen-style/html/nav_h.png deleted file mode 100644 index 33389b101..000000000 Binary files a/extras/doxygen-style/html/nav_h.png and /dev/null differ diff --git a/extras/doxygen-style/html/open.png b/extras/doxygen-style/html/open.png deleted file mode 100644 index 30f75c7ef..000000000 Binary files a/extras/doxygen-style/html/open.png and /dev/null differ diff --git a/extras/doxygen-style/html/search/all_0.js b/extras/doxygen-style/html/search/all_0.js deleted file mode 100644 index 709a938a0..000000000 --- a/extras/doxygen-style/html/search/all_0.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['analog',['Analog',['../group__analog.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/all_1.js b/extras/doxygen-style/html/search/all_1.js deleted file mode 100644 index 641232743..000000000 --- a/extras/doxygen-style/html/search/all_1.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['core',['Core',['../group__core.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/all_2.js b/extras/doxygen-style/html/search/all_2.js deleted file mode 100644 index c06e4df88..000000000 --- a/extras/doxygen-style/html/search/all_2.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['fixmath',['Fixmath',['../group__fixmath.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/all_3.js b/extras/doxygen-style/html/search/all_3.js deleted file mode 100644 index 5edb8fa4b..000000000 --- a/extras/doxygen-style/html/search/all_3.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['midi',['Midi',['../group__midi.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/all_4.html b/extras/doxygen-style/html/search/all_4.html deleted file mode 100644 index 6452295dc..000000000 --- a/extras/doxygen-style/html/search/all_4.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/all_4.js b/extras/doxygen-style/html/search/all_4.js deleted file mode 100644 index 28844cf87..000000000 --- a/extras/doxygen-style/html/search/all_4.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['random',['Random',['../group__random.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/all_5.html b/extras/doxygen-style/html/search/all_5.html deleted file mode 100644 index e59e1d536..000000000 --- a/extras/doxygen-style/html/search/all_5.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/all_5.js b/extras/doxygen-style/html/search/all_5.js deleted file mode 100644 index 2e92eb0ce..000000000 --- a/extras/doxygen-style/html/search/all_5.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['soundtables',['Soundtables',['../group__soundtables.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/all_6.html b/extras/doxygen-style/html/search/all_6.html deleted file mode 100644 index f75a754e9..000000000 --- a/extras/doxygen-style/html/search/all_6.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/all_6.js b/extras/doxygen-style/html/search/all_6.js deleted file mode 100644 index 6a7ff87f9..000000000 --- a/extras/doxygen-style/html/search/all_6.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['util',['Util',['../group__util.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/close.png b/extras/doxygen-style/html/search/close.png deleted file mode 100644 index 9342d3dfe..000000000 Binary files a/extras/doxygen-style/html/search/close.png and /dev/null differ diff --git a/extras/doxygen-style/html/search/groups_0.html b/extras/doxygen-style/html/search/groups_0.html deleted file mode 100644 index f4895cb40..000000000 --- a/extras/doxygen-style/html/search/groups_0.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/groups_0.js b/extras/doxygen-style/html/search/groups_0.js deleted file mode 100644 index 709a938a0..000000000 --- a/extras/doxygen-style/html/search/groups_0.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['analog',['Analog',['../group__analog.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/groups_1.html b/extras/doxygen-style/html/search/groups_1.html deleted file mode 100644 index 31952659a..000000000 --- a/extras/doxygen-style/html/search/groups_1.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/groups_1.js b/extras/doxygen-style/html/search/groups_1.js deleted file mode 100644 index 641232743..000000000 --- a/extras/doxygen-style/html/search/groups_1.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['core',['Core',['../group__core.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/groups_2.html b/extras/doxygen-style/html/search/groups_2.html deleted file mode 100644 index 58824467c..000000000 --- a/extras/doxygen-style/html/search/groups_2.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/groups_2.js b/extras/doxygen-style/html/search/groups_2.js deleted file mode 100644 index c06e4df88..000000000 --- a/extras/doxygen-style/html/search/groups_2.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['fixmath',['Fixmath',['../group__fixmath.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/groups_3.html b/extras/doxygen-style/html/search/groups_3.html deleted file mode 100644 index bd23aa6e1..000000000 --- a/extras/doxygen-style/html/search/groups_3.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/groups_3.js b/extras/doxygen-style/html/search/groups_3.js deleted file mode 100644 index 5edb8fa4b..000000000 --- a/extras/doxygen-style/html/search/groups_3.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['midi',['Midi',['../group__midi.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/groups_4.html b/extras/doxygen-style/html/search/groups_4.html deleted file mode 100644 index 34edffce9..000000000 --- a/extras/doxygen-style/html/search/groups_4.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/groups_4.js b/extras/doxygen-style/html/search/groups_4.js deleted file mode 100644 index 28844cf87..000000000 --- a/extras/doxygen-style/html/search/groups_4.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['random',['Random',['../group__random.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/groups_5.html b/extras/doxygen-style/html/search/groups_5.html deleted file mode 100644 index 6d9adbf88..000000000 --- a/extras/doxygen-style/html/search/groups_5.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/groups_5.js b/extras/doxygen-style/html/search/groups_5.js deleted file mode 100644 index 2e92eb0ce..000000000 --- a/extras/doxygen-style/html/search/groups_5.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['soundtables',['Soundtables',['../group__soundtables.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/groups_6.html b/extras/doxygen-style/html/search/groups_6.html deleted file mode 100644 index f8f808513..000000000 --- a/extras/doxygen-style/html/search/groups_6.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -
-
Loading...
-
- -
Searching...
-
No Matches
- -
- - diff --git a/extras/doxygen-style/html/search/groups_6.js b/extras/doxygen-style/html/search/groups_6.js deleted file mode 100644 index 6a7ff87f9..000000000 --- a/extras/doxygen-style/html/search/groups_6.js +++ /dev/null @@ -1,4 +0,0 @@ -var searchData= -[ - ['util',['Util',['../group__util.html',1,'']]] -]; diff --git a/extras/doxygen-style/html/search/mag_sel.png b/extras/doxygen-style/html/search/mag_sel.png deleted file mode 100644 index 81f6040a2..000000000 Binary files a/extras/doxygen-style/html/search/mag_sel.png and /dev/null differ diff --git a/extras/doxygen-style/html/search/nomatches.html b/extras/doxygen-style/html/search/nomatches.html deleted file mode 100644 index b1ded27e9..000000000 --- a/extras/doxygen-style/html/search/nomatches.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - -
-
No Matches
-
- - diff --git a/extras/doxygen-style/html/search/search.css b/extras/doxygen-style/html/search/search.css deleted file mode 100644 index 3cf9df94a..000000000 --- a/extras/doxygen-style/html/search/search.css +++ /dev/null @@ -1,271 +0,0 @@ -/*---------------- Search Box */ - -#FSearchBox { - float: left; -} - -#MSearchBox { - white-space : nowrap; - float: none; - margin-top: 8px; - right: 0px; - width: 170px; - height: 24px; - z-index: 102; -} - -#MSearchBox .left -{ - display:block; - position:absolute; - left:10px; - width:20px; - height:19px; - background:url('search_l.png') no-repeat; - background-position:right; -} - -#MSearchSelect { - display:block; - position:absolute; - width:20px; - height:19px; -} - -.left #MSearchSelect { - left:4px; -} - -.right #MSearchSelect { - right:5px; -} - -#MSearchField { - display:block; - position:absolute; - height:19px; - background:url('search_m.png') repeat-x; - border:none; - width:115px; - margin-left:20px; - padding-left:4px; - color: #909090; - outline: none; - font: 9pt Arial, Verdana, sans-serif; - -webkit-border-radius: 0px; -} - -#FSearchBox #MSearchField { - margin-left:15px; -} - -#MSearchBox .right { - display:block; - position:absolute; - right:10px; - top:8px; - width:20px; - height:19px; - background:url('search_r.png') no-repeat; - background-position:left; -} - -#MSearchClose { - display: none; - position: absolute; - top: 4px; - background : none; - border: none; - margin: 0px 4px 0px 0px; - padding: 0px 0px; - outline: none; -} - -.left #MSearchClose { - left: 6px; -} - -.right #MSearchClose { - right: 2px; -} - -.MSearchBoxActive #MSearchField { - color: #000000; -} - -/*---------------- Search filter selection */ - -#MSearchSelectWindow { - display: none; - position: absolute; - left: 0; top: 0; - border: 1px solid #90A5CE; - background-color: #F9FAFC; - z-index: 10001; - padding-top: 4px; - padding-bottom: 4px; - -moz-border-radius: 4px; - -webkit-border-top-left-radius: 4px; - -webkit-border-top-right-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -} - -.SelectItem { - font: 8pt Arial, Verdana, sans-serif; - padding-left: 2px; - padding-right: 12px; - border: 0px; -} - -span.SelectionMark { - margin-right: 4px; - font-family: monospace; - outline-style: none; - text-decoration: none; -} - -a.SelectItem { - display: block; - outline-style: none; - color: #000000; - text-decoration: none; - padding-left: 6px; - padding-right: 12px; -} - -a.SelectItem:focus, -a.SelectItem:active { - color: #000000; - outline-style: none; - text-decoration: none; -} - -a.SelectItem:hover { - color: #FFFFFF; - background-color: #3D578C; - outline-style: none; - text-decoration: none; - cursor: pointer; - display: block; -} - -/*---------------- Search results window */ - -iframe#MSearchResults { - width: 60ex; - height: 15em; -} - -#MSearchResultsWindow { - display: none; - position: absolute; - left: 0; top: 0; - border: 1px solid #000; - background-color: #EEF1F7; - z-index:10000; -} - -/* ----------------------------------- */ - - -#SRIndex { - clear:both; - padding-bottom: 15px; -} - -.SREntry { - font-size: 10pt; - padding-left: 1ex; -} - -.SRPage .SREntry { - font-size: 8pt; - padding: 1px 5px; -} - -body.SRPage { - margin: 5px 2px; -} - -.SRChildren { - padding-left: 3ex; padding-bottom: .5em -} - -.SRPage .SRChildren { - display: none; -} - -.SRSymbol { - font-weight: bold; - color: #425E97; - font-family: Arial, Verdana, sans-serif; - text-decoration: none; - outline: none; -} - -a.SRScope { - display: block; - color: #425E97; - font-family: Arial, Verdana, sans-serif; - text-decoration: none; - outline: none; -} - -a.SRSymbol:focus, a.SRSymbol:active, -a.SRScope:focus, a.SRScope:active { - text-decoration: underline; -} - -span.SRScope { - padding-left: 4px; -} - -.SRPage .SRStatus { - padding: 2px 5px; - font-size: 8pt; - font-style: italic; -} - -.SRResult { - display: none; -} - -DIV.searchresults { - margin-left: 10px; - margin-right: 10px; -} - -/*---------------- External search page results */ - -.searchresult { - background-color: #F0F3F8; -} - -.pages b { - color: white; - padding: 5px 5px 3px 5px; - background-image: url("../tab_a.png"); - background-repeat: repeat-x; - text-shadow: 0 1px 1px #000000; -} - -.pages { - line-height: 17px; - margin-left: 4px; - text-decoration: none; -} - -.hl { - font-weight: bold; -} - -#searchresults { - margin-bottom: 20px; -} - -.searchpages { - margin-top: 10px; -} - diff --git a/extras/doxygen-style/html/search/search.js b/extras/doxygen-style/html/search/search.js deleted file mode 100644 index a554ab9cb..000000000 --- a/extras/doxygen-style/html/search/search.js +++ /dev/null @@ -1,814 +0,0 @@ -/* - @licstart The following is the entire license notice for the - JavaScript code in this file. - - Copyright (C) 1997-2017 by Dimitri van Heesch - - 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. - - 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. - - 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. - - @licend The above is the entire license notice - for the JavaScript code in this file - */ -function convertToId(search) -{ - var result = ''; - for (i=0;i do a search - { - this.Search(); - } - } - - this.OnSearchSelectKey = function(evt) - { - var e = (evt) ? evt : window.event; // for IE - if (e.keyCode==40 && this.searchIndex0) // Up - { - this.searchIndex--; - this.OnSelectItem(this.searchIndex); - } - else if (e.keyCode==13 || e.keyCode==27) - { - this.OnSelectItem(this.searchIndex); - this.CloseSelectionWindow(); - this.DOMSearchField().focus(); - } - return false; - } - - // --------- Actions - - // Closes the results window. - this.CloseResultsWindow = function() - { - this.DOMPopupSearchResultsWindow().style.display = 'none'; - this.DOMSearchClose().style.display = 'none'; - this.Activate(false); - } - - this.CloseSelectionWindow = function() - { - this.DOMSearchSelectWindow().style.display = 'none'; - } - - // Performs a search. - this.Search = function() - { - this.keyTimeout = 0; - - // strip leading whitespace - var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); - - var code = searchValue.toLowerCase().charCodeAt(0); - var idxChar = searchValue.substr(0, 1).toLowerCase(); - if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair - { - idxChar = searchValue.substr(0, 2); - } - - var resultsPage; - var resultsPageWithSearch; - var hasResultsPage; - - var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); - if (idx!=-1) - { - var hexCode=idx.toString(16); - resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; - resultsPageWithSearch = resultsPage+'?'+escape(searchValue); - hasResultsPage = true; - } - else // nothing available for this search term - { - resultsPage = this.resultsPath + '/nomatches.html'; - resultsPageWithSearch = resultsPage; - hasResultsPage = false; - } - - window.frames.MSearchResults.location = resultsPageWithSearch; - var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); - - if (domPopupSearchResultsWindow.style.display!='block') - { - var domSearchBox = this.DOMSearchBox(); - this.DOMSearchClose().style.display = 'inline'; - if (this.insideFrame) - { - var domPopupSearchResults = this.DOMPopupSearchResults(); - domPopupSearchResultsWindow.style.position = 'relative'; - domPopupSearchResultsWindow.style.display = 'block'; - var width = document.body.clientWidth - 8; // the -8 is for IE :-( - domPopupSearchResultsWindow.style.width = width + 'px'; - domPopupSearchResults.style.width = width + 'px'; - } - else - { - var domPopupSearchResults = this.DOMPopupSearchResults(); - var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; - var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; - domPopupSearchResultsWindow.style.display = 'block'; - left -= domPopupSearchResults.offsetWidth; - domPopupSearchResultsWindow.style.top = top + 'px'; - domPopupSearchResultsWindow.style.left = left + 'px'; - } - } - - this.lastSearchValue = searchValue; - this.lastResultsPage = resultsPage; - } - - // -------- Activation Functions - - // Activates or deactivates the search panel, resetting things to - // their default values if necessary. - this.Activate = function(isActive) - { - if (isActive || // open it - this.DOMPopupSearchResultsWindow().style.display == 'block' - ) - { - this.DOMSearchBox().className = 'MSearchBoxActive'; - - var searchField = this.DOMSearchField(); - - if (searchField.value == this.searchLabel) // clear "Search" term upon entry - { - searchField.value = ''; - this.searchActive = true; - } - } - else if (!isActive) // directly remove the panel - { - this.DOMSearchBox().className = 'MSearchBoxInactive'; - this.DOMSearchField().value = this.searchLabel; - this.searchActive = false; - this.lastSearchValue = '' - this.lastResultsPage = ''; - } - } -} - -// ----------------------------------------------------------------------- - -// The class that handles everything on the search results page. -function SearchResults(name) -{ - // The number of matches from the last run of . - this.lastMatchCount = 0; - this.lastKey = 0; - this.repeatOn = false; - - // Toggles the visibility of the passed element ID. - this.FindChildElement = function(id) - { - var parentElement = document.getElementById(id); - var element = parentElement.firstChild; - - while (element && element!=parentElement) - { - if (element.nodeName == 'DIV' && element.className == 'SRChildren') - { - return element; - } - - if (element.nodeName == 'DIV' && element.hasChildNodes()) - { - element = element.firstChild; - } - else if (element.nextSibling) - { - element = element.nextSibling; - } - else - { - do - { - element = element.parentNode; - } - while (element && element!=parentElement && !element.nextSibling); - - if (element && element!=parentElement) - { - element = element.nextSibling; - } - } - } - } - - this.Toggle = function(id) - { - var element = this.FindChildElement(id); - if (element) - { - if (element.style.display == 'block') - { - element.style.display = 'none'; - } - else - { - element.style.display = 'block'; - } - } - } - - // Searches for the passed string. If there is no parameter, - // it takes it from the URL query. - // - // Always returns true, since other documents may try to call it - // and that may or may not be possible. - this.Search = function(search) - { - if (!search) // get search word from URL - { - search = window.location.search; - search = search.substring(1); // Remove the leading '?' - search = unescape(search); - } - - search = search.replace(/^ +/, ""); // strip leading spaces - search = search.replace(/ +$/, ""); // strip trailing spaces - search = search.toLowerCase(); - search = convertToId(search); - - var resultRows = document.getElementsByTagName("div"); - var matches = 0; - - var i = 0; - while (i < resultRows.length) - { - var row = resultRows.item(i); - if (row.className == "SRResult") - { - var rowMatchName = row.id.toLowerCase(); - rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' - - if (search.length<=rowMatchName.length && - rowMatchName.substr(0, search.length)==search) - { - row.style.display = 'block'; - matches++; - } - else - { - row.style.display = 'none'; - } - } - i++; - } - document.getElementById("Searching").style.display='none'; - if (matches == 0) // no results - { - document.getElementById("NoMatches").style.display='block'; - } - else // at least one result - { - document.getElementById("NoMatches").style.display='none'; - } - this.lastMatchCount = matches; - return true; - } - - // return the first item with index index or higher that is visible - this.NavNext = function(index) - { - var focusItem; - while (1) - { - var focusName = 'Item'+index; - focusItem = document.getElementById(focusName); - if (focusItem && focusItem.parentNode.parentNode.style.display=='block') - { - break; - } - else if (!focusItem) // last element - { - break; - } - focusItem=null; - index++; - } - return focusItem; - } - - this.NavPrev = function(index) - { - var focusItem; - while (1) - { - var focusName = 'Item'+index; - focusItem = document.getElementById(focusName); - if (focusItem && focusItem.parentNode.parentNode.style.display=='block') - { - break; - } - else if (!focusItem) // last element - { - break; - } - focusItem=null; - index--; - } - return focusItem; - } - - this.ProcessKeys = function(e) - { - if (e.type == "keydown") - { - this.repeatOn = false; - this.lastKey = e.keyCode; - } - else if (e.type == "keypress") - { - if (!this.repeatOn) - { - if (this.lastKey) this.repeatOn = true; - return false; // ignore first keypress after keydown - } - } - else if (e.type == "keyup") - { - this.lastKey = 0; - this.repeatOn = false; - } - return this.lastKey!=0; - } - - this.Nav = function(evt,itemIndex) - { - var e = (evt) ? evt : window.event; // for IE - if (e.keyCode==13) return true; - if (!this.ProcessKeys(e)) return false; - - if (this.lastKey==38) // Up - { - var newIndex = itemIndex-1; - var focusItem = this.NavPrev(newIndex); - if (focusItem) - { - var child = this.FindChildElement(focusItem.parentNode.parentNode.id); - if (child && child.style.display == 'block') // children visible - { - var n=0; - var tmpElem; - while (1) // search for last child - { - tmpElem = document.getElementById('Item'+newIndex+'_c'+n); - if (tmpElem) - { - focusItem = tmpElem; - } - else // found it! - { - break; - } - n++; - } - } - } - if (focusItem) - { - focusItem.focus(); - } - else // return focus to search field - { - parent.document.getElementById("MSearchField").focus(); - } - } - else if (this.lastKey==40) // Down - { - var newIndex = itemIndex+1; - var focusItem; - var item = document.getElementById('Item'+itemIndex); - var elem = this.FindChildElement(item.parentNode.parentNode.id); - if (elem && elem.style.display == 'block') // children visible - { - focusItem = document.getElementById('Item'+itemIndex+'_c0'); - } - if (!focusItem) focusItem = this.NavNext(newIndex); - if (focusItem) focusItem.focus(); - } - else if (this.lastKey==39) // Right - { - var item = document.getElementById('Item'+itemIndex); - var elem = this.FindChildElement(item.parentNode.parentNode.id); - if (elem) elem.style.display = 'block'; - } - else if (this.lastKey==37) // Left - { - var item = document.getElementById('Item'+itemIndex); - var elem = this.FindChildElement(item.parentNode.parentNode.id); - if (elem) elem.style.display = 'none'; - } - else if (this.lastKey==27) // Escape - { - parent.searchBox.CloseResultsWindow(); - parent.document.getElementById("MSearchField").focus(); - } - else if (this.lastKey==13) // Enter - { - return true; - } - return false; - } - - this.NavChild = function(evt,itemIndex,childIndex) - { - var e = (evt) ? evt : window.event; // for IE - if (e.keyCode==13) return true; - if (!this.ProcessKeys(e)) return false; - - if (this.lastKey==38) // Up - { - if (childIndex>0) - { - var newIndex = childIndex-1; - document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); - } - else // already at first child, jump to parent - { - document.getElementById('Item'+itemIndex).focus(); - } - } - else if (this.lastKey==40) // Down - { - var newIndex = childIndex+1; - var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); - if (!elem) // last child, jump to parent next parent - { - elem = this.NavNext(itemIndex+1); - } - if (elem) - { - elem.focus(); - } - } - else if (this.lastKey==27) // Escape - { - parent.searchBox.CloseResultsWindow(); - parent.document.getElementById("MSearchField").focus(); - } - else if (this.lastKey==13) // Enter - { - return true; - } - return false; - } -} - -function setKeyActions(elem,action) -{ - elem.setAttribute('onkeydown',action); - elem.setAttribute('onkeypress',action); - elem.setAttribute('onkeyup',action); -} - -function setClassAttr(elem,attr) -{ - elem.setAttribute('class',attr); - elem.setAttribute('className',attr); -} - -function createResults() -{ - var results = document.getElementById("SRResults"); - for (var e=0; eli>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#doc-content{overflow:auto;display:block;padding:0;margin:0;-webkit-overflow-scrolling:touch}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace!important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0!important;-webkit-border-radius:0;border-radius:0!important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px!important;-webkit-border-radius:5px;border-radius:5px!important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0!important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px!important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file diff --git a/extras/python/audio2huff.py b/extras/python/audio2huff.py index 40a865d67..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 @@ -124,10 +127,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 c85ecd7ef..d3a3ba838 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", @@ -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/hardware_defines.h b/hardware_defines.h index e663939c1..7d61adf46 100644 --- a/hardware_defines.h +++ b/hardware_defines.h @@ -1,11 +1,19 @@ +/* + * 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_ -#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 @@ -50,9 +58,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 +84,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,32 +102,25 @@ #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 #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() +#if IS_ESP8266() || IS_ESP32() #define CACHED_FUNCTION_ATTR IRAM_ATTR #else #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/MozziGuts.cpp b/internal/MozziGuts.hpp similarity index 55% rename from MozziGuts.cpp rename to internal/MozziGuts.hpp index b6aad9dda..4381b5e6c 100644 --- a/MozziGuts.cpp +++ b/internal/MozziGuts.hpp @@ -1,39 +1,49 @@ /* - * 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" -#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 "internal/mozzi_rand_p.h" #include "AudioOutput.h" -#define AUDIO_INPUT_NONE 0 -#define AUDIO_INPUT_LEGACY 1 -#define AUDIO_INPUT_CUSTOM 2 +/** @brief Internal. Do not use function in this namespace in your sketch! + +This namespace contains various functions that are used by Mozzi, internally, but are not meant to be used in a sketch. +The details of these may change without warning. I repeat: Do not use these in your sketch! +*/ +namespace MozziPrivate { // Forward declarations of functions to be provided by platform specific implementations #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 + +// 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 #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" @@ -58,35 +68,31 @@ 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 - -static uint8_t adc_count = 0; - +namespace MozziPrivate { ////// BEGIN Output buffering ///// #if BYPASS_MOZZI_OUTPUT_BUFFER == true uint64_t samples_written_to_buffer = 0; -inline void bufferAudioOutput(const AudioOutput_t f) { +inline void bufferAudioOutput(const AudioOutput f) { audioOutput(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 +CircularBuffer output_buffer; // fixed size 256 # define canBufferAudioOutput() (!output_buffer.isFull()) # 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 + MOZZI_ASSERT_NOTEQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE); adc_count = 0; startSecondADCReadOnCurrentChannel(); // the current channel is the AUDIO_INPUT pin # endif @@ -102,8 +108,10 @@ 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 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 @@ -120,8 +128,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; @@ -129,28 +137,23 @@ __attribute__((noinline)) void adcStartReadCycle() { } } -int mozziAnalogRead(uint8_t pin) { -#if defined(MOZZI_FAST_ANALOG_IMPLEMENTED) +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)]; -#else -# warning Asynchronouos analog reads not implemented for this platform - return analogRead(pin); -#endif } -#if (USE_AUDIO_INPUT == true) -static AudioOutputStorage_t audio_input; // holds the latest audio from input_buffer -AudioOutputStorage_t getAudioInput() { return audio_input; } +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) +static uint16_t audio_input; // holds the latest audio from input_buffer +uint16_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 +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: @@ -175,7 +178,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, @@ -195,6 +198,15 @@ inline void advanceADCStep() { } #endif +#else +MOZZI_ASSERT_EQUAL(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) + +uint16_t mozziAnalogRead(uint8_t pin) { + return analogRead(pin); +} + +#endif // MOZZI_ANALOG_READ + ////// END analog input code //////// @@ -206,7 +218,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; } @@ -217,18 +231,13 @@ 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 #endif -#if (USE_AUDIO_INPUT == true) +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) if (audioInputAvailable()) audio_input = readAudioInput(); #endif } @@ -260,12 +269,54 @@ unsigned long mozziMicros() { return audioTicks() * MICROS_PER_AUDIO_TICK; } ////// BEGIN initialization /////// void startMozzi(int control_rate_hz) { - setupMozziADC(); // you can use setupFastAnalogRead() with FASTER_ADC or FASTEST_ADC +#if !MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE) + MozziPrivate::setupMozziADC(FAST_ADC); // 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 = AUDIO_RATE / control_rate_hz; + update_control_timeout = MOZZI_AUDIO_RATE / control_rate_hz - 1; startAudio(); } +uint32_t MozziRandPrivate::x=132456789; +uint32_t MozziRandPrivate::y=362436069; +uint32_t MozziRandPrivate::z=521288629; + ////// 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 + +// "export" publicly accessible functions defined in this file +// 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 audioTicks() { return MozziPrivate::audioTicks(); }; +void startMozzi(int control_rate_hz) { MozziPrivate::startMozzi(control_rate_hz); }; +void stopMozzi() { MozziPrivate::stopMozzi(); }; +template uint16_t mozziAnalogRead(uint8_t pin) { return MozziPrivate::smartShift(MozziPrivate::mozziAnalogRead(pin));}; +#if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) +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); }; +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) +// 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 diff --git a/MozziGuts_impl_AVR.hpp b/internal/MozziGuts_impl_AVR.hpp similarity index 66% rename from MozziGuts_impl_AVR.hpp rename to internal/MozziGuts_impl_AVR.hpp index dd0f474dc..10c82109c 100644 --- a/MozziGuts_impl_AVR.hpp +++ b/internal/MozziGuts_impl_AVR.hpp @@ -1,17 +1,16 @@ /* - * 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 "FrequencyTimer2.h" -#include "TimerOne.h" +#include "utility/FrequencyTimer2.h" +#include "utility/TimerOne.h" #if (F_CPU != 16000000) #warning \ @@ -19,9 +18,15 @@ #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; +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 +34,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,9 +87,10 @@ void adcEnableInterrupt(){ } */ -ISR(ADC_vect, ISR_BLOCK) -{ - advanceADCStep(); +void setupMozziADC(int8_t speed) { + ADCSRA |= (1 << ADIE); // adc Enable Interrupt + adcDisconnectAllDigitalIns(); + setupFastAnalogRead(speed); } void setupFastAnalogRead(int8_t speed) { @@ -94,16 +108,14 @@ void setupFastAnalogRead(int8_t speed) { ADCSRA &= ~(1 << ADPS0); } } - -void setupMozziADC(int8_t speed) { - ADCSRA |= (1 << ADIE); // adc Enable Interrupt - adcDisconnectAllDigitalIns(); } -////// END analog input code //////// +#endif +////// END analog input code //////// +namespace MozziPrivate { //// BEGIN AUDIO OUTPUT code /////// /* ATmega328 technical manual, Section 12.7.4: @@ -133,7 +145,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 +165,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,11 +176,11 @@ 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) 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 @@ -178,67 +190,69 @@ static void startAudio() { // Timer1.attachInterrupt()) } +} // namespace MozziPrivate + ISR(TIMER1_OVF_vect, ISR_BLOCK) { - defaultAudioOutput(); + MozziPrivate::defaultAudioOutput(); } -#elif (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS) -# if (AUDIO_MODE == STANDARD_PLUS) -# include "AudioConfigStandardPlus.h" -# else -# include "AudioConfigStandard9bitPwm.h" -# endif + +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) { - 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()) } -/* Interrupt service routine moves sound data from the output buffer to the -Arduino output register, running at AUDIO_RATE. */ +} // namespace MozziPrivate +/* Interrupt service routine moves sound data from the output buffer to the +Arduino output register, running at MOZZI_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; # endif - defaultAudioOutput(); + MozziPrivate::defaultAudioOutput(); } -#elif (AUDIO_MODE == HIFI) -# if (EXTERNAL_AUDIO_OUTPUT != true) -# include "AudioConfigHiSpeed14bitPwm.h" +namespace MozziPrivate { +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM) inline void audioOutput(const AudioOutput f) { // read about dual pwm at // http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ @@ -247,13 +261,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, @@ -263,26 +277,21 @@ 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_CHANNEL; + MOZZI_AUDIO_PIN_1_LOW_REGISTER = (f.l()+MOZZI_AUDIO_BIAS) & ((1 << MOZZI_AUDIO_BITS_PER_CHANNEL) - 1); } -# endif static void setupTimer2(); static void startAudio() { backupPreMozziTimer1(); // pwm on timer 1 - pinMode(AUDIO_CHANNEL_1_highByte_PIN, - OUTPUT); // set pin to output for audio, use 3.9k resistor - pinMode(AUDIO_CHANNEL_1_lowByte_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(AUDIO_CHANNEL_1_highByte_PIN, - 0); // pwm pin, 0% duty cycle, ie. 0 signal - Timer1.pwm(AUDIO_CHANNEL_1_lowByte_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(); } @@ -316,12 +325,14 @@ 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(); } +} // namespace MozziPrivate + #if defined(TIMER2_COMPA_vect) ISR(TIMER2_COMPA_vect) #elif defined(TIMER2_COMP_vect) @@ -334,11 +345,13 @@ ISR(TIMER4_COMPA_vect) void dummy_function(void) #endif { - defaultAudioOutput(); + MozziPrivate::defaultAudioOutput(); } // end of HIFI +namespace MozziPrivate { + #endif //----------------------------------------------------------------------------------------------------------------- @@ -354,7 +367,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; @@ -385,3 +398,50 @@ 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 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(); + //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/internal/MozziGuts_impl_ESP32.hpp similarity index 63% rename from MozziGuts_impl_ESP32.hpp rename to internal/MozziGuts_impl_ESP32.hpp index 7657eb62c..4a4d35378 100644 --- a/MozziGuts_impl_ESP32.hpp +++ b/internal/MozziGuts_impl_ESP32.hpp @@ -1,60 +1,59 @@ /* - * 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" #endif +namespace MozziPrivate { ////// 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) { -#warning Fast analog read not implemented on this platform } -////// END analog input code //////// - +void setupFastAnalogRead(int8_t speed) { +} +#endif +////// END analog input code //////// //// 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) +} // namespace MozziPrivate +# include // for I2S-based output modes, including - technically - internal DAC +namespace MozziPrivate { +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 +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; @@ -102,7 +106,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 +120,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 +#elif !MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM) 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 +143,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 +164,15 @@ void stopMozzi() { // TODO: implement me } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +void MozziRandPrivate::autoSeed() { + x = esp_random(); + y = esp_random(); + z = esp_random(); +} +//// END Random seeding //////// + +#undef ESP_SAMPLE_SIZE // only used inside this file + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_ESP8266.hpp b/internal/MozziGuts_impl_ESP8266.hpp similarity index 52% rename from MozziGuts_impl_ESP8266.hpp rename to internal/MozziGuts_impl_ESP8266.hpp index c9f925b9f..f4623c96d 100644 --- a/MozziGuts_impl_ESP8266.hpp +++ b/internal/MozziGuts_impl_ESP8266.hpp @@ -1,98 +1,102 @@ /* - * 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" #endif +namespace MozziPrivate { + ////// 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) { -#warning Fast analog read not implemented on this platform } +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 (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) +} // namespace MozziPrivate # include +namespace MozziPrivate { 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) +} // namespace MozziPrivate # include +namespace MozziPrivate { 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) -// 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) +# 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 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() - 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.l()+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 +109,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,18 +126,32 @@ 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 //// 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 + // 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 //////// +} // namespace MozziPrivate diff --git a/MozziGuts_impl_MBED.hpp b/internal/MozziGuts_impl_MBED.hpp similarity index 70% rename from MozziGuts_impl_MBED.hpp rename to internal/MozziGuts_impl_MBED.hpp index e3a642218..c4611bce4 100644 --- a/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" @@ -16,14 +15,18 @@ #define CHUNKSIZE 64 +namespace MozziPrivate { + ////// 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 +} // namespace MozziPrivate #include +namespace MozziPrivate { -AdvancedADC adc(AUDIO_INPUT_PIN); +AdvancedADC adc(MOZZI_AUDIO_INPUT_PIN); Sample inbuf[CHUNKSIZE]; int inbufpos=0; @@ -44,18 +47,20 @@ 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) +#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, 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,53 +79,40 @@ 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. * 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 - #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) +} // namespace MozziPrivate #include +namespace MozziPrivate { mbed::Ticker audio_output_timer; volatile bool audio_output_requested = false; @@ -132,20 +124,23 @@ 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) +} // namespace MozziPrivate #include +namespace MozziPrivate { -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; @@ -157,25 +152,24 @@ 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); -#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 +177,48 @@ 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) +} // namespace MozziPrivate #include +namespace MozziPrivate { -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 +229,14 @@ void stopMozzi() { #endif ////// END audio output code ////// + +//// BEGIN Random seeding //////// +void MozziRandPrivate::autoSeed() { +#warning Automatic random seeding is not implemented on this platform +} +//// END Random seeding //////// + +} // namespace MozziPrivate + +#undef CHUNKSIZE +#undef US_PER_AUDIO_TICK diff --git a/MozziGuts_impl_RENESAS.hpp b/internal/MozziGuts_impl_RENESAS.hpp similarity index 65% rename from MozziGuts_impl_RENESAS.hpp rename to internal/MozziGuts_impl_RENESAS.hpp index f5c0e4c34..7ba7afda4 100644 --- a/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" @@ -16,9 +15,11 @@ #include +namespace MozziPrivate { ////// 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 @@ -30,9 +31,11 @@ void adc_callback(adc_callback_args_t *p_args) { advanceADCStep(); } +} // namespace MozziPrivate + #include "MozziGuts_impl_RENESAS_ADC.hpp" -#define MOZZI_FAST_ANALOG_IMPLEMENTED +namespace MozziPrivate { #define getADCReading() readADC(r4_pin) @@ -56,7 +59,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,23 +81,28 @@ 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; +} // namespace MozziPrivate #include "MozziGuts_impl_RENESAS_analog.hpp" +namespace MozziPrivate { #endif //////////////// 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 +112,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 +128,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 +163,22 @@ 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 /////// + +//// BEGIN Random seeding //////// +void MozziRandPrivate::autoSeed() { +#warning Automatic random seeding is not implemented on this platform +} +//// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_RENESAS_ADC.hpp b/internal/MozziGuts_impl_RENESAS_ADC.hpp similarity index 93% rename from MozziGuts_impl_RENESAS_ADC.hpp rename to internal/MozziGuts_impl_RENESAS_ADC.hpp index 079486e67..4f12b9596 100644 --- a/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(). @@ -8,6 +15,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 +127,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/internal/MozziGuts_impl_RENESAS_analog.hpp similarity index 90% rename from MozziGuts_impl_RENESAS_analog.hpp rename to internal/MozziGuts_impl_RENESAS_analog.hpp index 2496cbfe8..0d1f58139 100644 --- a/MozziGuts_impl_RENESAS_analog.hpp +++ b/internal/MozziGuts_impl_RENESAS_analog.hpp @@ -1,14 +1,25 @@ /* + * 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). */ -FspTimer timer_dac; #include #include #include +namespace MozziPrivate { + +FspTimer timer_dac; volatile uint32_t pin; uint8_t dac_bits; @@ -86,3 +97,4 @@ void dac_init() { } } +} diff --git a/MozziGuts_impl_RP2040.hpp b/internal/MozziGuts_impl_RP2040.hpp similarity index 56% rename from MozziGuts_impl_RP2040.hpp rename to internal/MozziGuts_impl_RP2040.hpp index 096a292ca..552b4548d 100644 --- a/MozziGuts_impl_RP2040.hpp +++ b/internal/MozziGuts_impl_RP2040.hpp @@ -1,24 +1,26 @@ /* - * 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()) # error "Wrong implementation included for this platform" #endif +#include + +namespace MozziPrivate { ////// 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. @@ -27,8 +29,11 @@ * We'll abuse that to connect a callback to the DMA channel, instead. */ +} // namespace MozziPrivate + #include -#include + +namespace MozziPrivate { #define getADCReading() rp2040_adc_result #define channelNumToIndex(channel) channel @@ -69,7 +74,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 +121,9 @@ 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,108 +131,125 @@ 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_EXTERNAL_TIMED) #include -#if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user -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 -} -#endif // #if (EXTERNAL_AUDIO_OUTPUT != true) + +} // 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 - * - 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 - * - Using DMA transfers, instead of a manual timer, would be much more elegant, but I'll leave that as an exercise to the reader ;-) - * - Not to mention PWM output, etc. + * - For once, two different approaches are used between EXTERNAL_TIMED and PWM: + * - EXTERNAL_TIMED (here), uses a repeating alarm to induce the user's callback + * - because the alarm only has a resolution of 1us, we need to trick a bit to get the correct frequency: we compute the desired time target at a higher resolution (next_audio_update_shifted) so that the error is compensated by the higher precision sum. */ absolute_time_t next_audio_update; -uint64_t micros_per_update; +uint64_t micros_per_update, next_audio_update_shifted; +const uint64_t micros_per_update_shifted = (1000000l << 8) / MOZZI_AUDIO_RATE; uint audio_update_alarm_num; void audioOutputCallback(uint) { do { defaultAudioOutput(); - next_audio_update = delayed_by_us(next_audio_update, micros_per_update); + next_audio_update_shifted += micros_per_update_shifted; + next_audio_update = delayed_by_us(nil_time, next_audio_update_shifted>>8); // NOTE: hardware_alarm_set_target returns true, if the target was already missed. In that case, keep pushing samples, until we have caught up. - } while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update)); + } 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_PWM) +} // namespace MozziPrivate +#include +namespace MozziPrivate { + /** Implementation notes: + * - This uses, straight out of the box, PWMAudio from Arduino-pico + * - thanks to that, it uses DMA transfer to update the audio output + * - implementation is extremely similar to I2S case. + * - PWMAudio expects 16bits samples. + */ +# if (MOZZI_AUDIO_CHANNELS > 1) + PWMAudio pwm(MOZZI_AUDIO_PIN_1,true); + inline bool canBufferAudioOutput() { + return (pwm.availableForWrite()>1); // we will need to transfer 2 samples, for it to be non-blocking we need to ensure there is enough room. +} +# else + PWMAudio pwm(MOZZI_AUDIO_PIN_1); + inline bool canBufferAudioOutput() { + return (pwm.availableForWrite()); +} +# endif + + + inline void audioOutput(const AudioOutput f) { + pwm.write(f.l()); + # if (MOZZI_AUDIO_CHANNELS > 1) + pwm.write(f.r()); + #endif + } + +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC) +} // namespace MozziPrivate #include +namespace MozziPrivate { 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) - // 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); - // 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 . +#if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) + + 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 . # 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 -# endif + gpio_set_drive_strength(MOZZI_AUDIO_PIN_2, GPIO_DRIVE_STRENGTH_12MA); // highest we can get #endif + pwm.setBuffers(MOZZI_RP2040_BUFFERS, (size_t) (MOZZI_RP2040_BUFFER_SIZE/MOZZI_RP2040_BUFFERS)); + + pwm.begin(MOZZI_AUDIO_RATE); +# endif +#if MOZZI_IS(MOZZI_AUDIO_MODE, 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,35 +257,49 @@ 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); + next_audio_update_shifted = to_us_since_boot(next_audio_update) << 8; // 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 } void stopMozzi() { -#if (RP2040_AUDIO_OUT_MODE == PWM_VIA_BARE_CHIP) || (EXTERNAL_AUDIO_OUTPUT == true) +#if MOZZI_IS(MOZZI_AUDIO_MODE, 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(); +#elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) + pwm.end(); #endif } ////// END audio output code ////// + +//// BEGIN Random seeding //////// +void MozziRandPrivate::autoSeed() { +#warning Automatic random seeding is not implemented on this platform +} +//// END Random seeding //////// + +} // namespace MozziPrivate + +#undef MOZZI_RP2040_BUFFERS +#undef MOZZI_RP2040_BUFFER_SIZE diff --git a/MozziGuts_impl_SAMD.hpp b/internal/MozziGuts_impl_SAMD.hpp similarity index 69% rename from MozziGuts_impl_SAMD.hpp rename to internal/MozziGuts_impl_SAMD.hpp index 03cc61910..c1183ec91 100644 --- a/MozziGuts_impl_SAMD.hpp +++ b/internal/MozziGuts_impl_SAMD.hpp @@ -1,43 +1,43 @@ /* - * 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" #endif +namespace MozziPrivate { + ////// BEGIN analog input code //////// -//#define MOZZI_FAST_ANALOG_IMPLEMENTED // not yet +#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) { 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; @@ -94,41 +94,49 @@ 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 -#if (EXTERNAL_AUDIO_OUTPUT != true) // otherwise, the last stage - audioOutput() - will be provided by the user -#include "AudioConfigSAMD21.h" +namespace MozziPrivate { + +#endif // MOZZI_AUDIO_MODE + +#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() { @@ -136,3 +144,11 @@ void stopMozzi() { interrupts(); } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +void MozziRandPrivate::autoSeed() { +#warning Automatic random seeding is not implemented on this platform +} +//// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_STM32.hpp b/internal/MozziGuts_impl_STM32.hpp similarity index 50% rename from MozziGuts_impl_STM32.hpp rename to internal/MozziGuts_impl_STM32.hpp index bf8164d24..6a90cc466 100644 --- a/MozziGuts_impl_STM32.hpp +++ b/internal/MozziGuts_impl_STM32.hpp @@ -1,20 +1,25 @@ /* - * 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" +namespace MozziPrivate { + ////// 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) + +} // 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() @@ -38,13 +43,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,36 +54,44 @@ 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_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 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_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); @@ -96,39 +102,66 @@ 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_EXTERNAL_TIMED) audio_update_timer.pause(); +#endif } //// END AUDIO OUTPUT code /////// + +//// BEGIN Random seeding //////// +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. + 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 //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_STM32duino.hpp b/internal/MozziGuts_impl_STM32duino.hpp similarity index 59% rename from MozziGuts_impl_STM32duino.hpp rename to internal/MozziGuts_impl_STM32duino.hpp index aca71c978..6d983caba 100644 --- a/MozziGuts_impl_STM32duino.hpp +++ b/internal/MozziGuts_impl_STM32duino.hpp @@ -1,21 +1,20 @@ /* - * 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" +namespace MozziPrivate { ////// 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. @@ -37,7 +36,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) { @@ -61,9 +62,6 @@ void startSecondADCReadOnCurrentChannel() { conversion_running = true; } -void setupFastAnalogRead(int8_t /*speed*/) { -} - void setupMozziADC(int8_t /*speed*/) { } @@ -77,47 +75,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); + //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); @@ -126,42 +129,55 @@ 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)) - // static_assert(MAX_CARRIER_FREQ >= AUDIO_RATE); // Unfortunately, we cannot test this at compile time. F_CPU expands to a runtime variable +# define MAX_CARRIER_FREQ (F_CPU / (1 << MOZZI_AUDIO_BITS_PER_CHANNEL)) + // 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); -# 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 /////// + +//// BEGIN Random seeding //////// +void MozziRandPrivate::autoSeed() { +#warning Automatic random seeding is not implemented on this platform +} +//// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_STM32duino_analog.hpp b/internal/MozziGuts_impl_STM32duino_analog.hpp similarity index 97% rename from MozziGuts_impl_STM32duino_analog.hpp rename to internal/MozziGuts_impl_STM32duino_analog.hpp index c1a852b2a..782237356 100644 --- a/MozziGuts_impl_STM32duino_analog.hpp +++ b/internal/MozziGuts_impl_STM32duino_analog.hpp @@ -1,4 +1,16 @@ +/* + * 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 @@ -310,3 +322,5 @@ bool adc_setup_read(PinName pin, uint32_t resolution) { return HAL_OK; } + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_TEENSY.hpp b/internal/MozziGuts_impl_TEENSY.hpp similarity index 53% rename from MozziGuts_impl_TEENSY.hpp rename to internal/MozziGuts_impl_TEENSY.hpp index ef0262d22..46b846f29 100644 --- a/MozziGuts_impl_TEENSY.hpp +++ b/internal/MozziGuts_impl_TEENSY.hpp @@ -1,31 +1,31 @@ /* - * 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" #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 +namespace MozziPrivate { ////// 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.* +} //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 int8_t teensy_adc=0; @@ -44,14 +44,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 @@ -69,45 +71,58 @@ 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) +} // namespace MozziPrivate +#include "IntervalTimer.h" +namespace MozziPrivate { 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 /////// + +//// BEGIN Random seeding //////// +void MozziRandPrivate::autoSeed() { +#warning Automatic random seeding is not implemented on this platform +} +//// END Random seeding //////// + +} // namespace MozziPrivate diff --git a/MozziGuts_impl_template.hpp b/internal/MozziGuts_impl_template.hpp similarity index 56% rename from MozziGuts_impl_template.hpp rename to internal/MozziGuts_impl_template.hpp index a478cf57e..429a87bc8 100644 --- a/MozziGuts_impl_template.hpp +++ b/internal/MozziGuts_impl_template.hpp @@ -1,24 +1,25 @@ /* - * 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! +/** @file MozziGuts_impl_template.hpp Template for implementation of new ports + * + * README! * This file is meant to be used as a template when adding support for a new platform. Please read these instructions, first. * * 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 * @@ -37,17 +38,38 @@ #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 //////// -/** 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 + * + * 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 -#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 +91,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 +111,14 @@ void stm32_adc_eoc_handler() { advanceADCStep(); } */ + +/** 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) { +} + +#endif + ////// END analog input code //////// ////// BEGIN audio output code ////// @@ -110,23 +133,34 @@ void stm32_adc_eoc_handler() { * 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 } @@ -134,3 +168,17 @@ void stopMozzi() { // Add here code to pause whatever mechanism moves audio samples to the output } ////// END audio output code ////// + +//// BEGIN Random seeding //////// +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. + // 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 seeding is not implemented on this platform +} +//// END Random seeding //////// + +} // namespace MozziPrivate 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_checks_avr.h b/internal/config_checks_avr.h new file mode 100644 index 000000000..0f847a7ed --- /dev/null +++ b/internal/config_checks_avr.h @@ -0,0 +1,172 @@ +/* + * 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 */ + +/** + * @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: + * - MOZZI_OUTPUT_PWM + * - MOZZI_OUTPUT_2PIN_PWM + * - MOZZI_OUTPUT_EXTERNAL_TIMED + * - MOZZI_OUTPUT_EXTERNAL_CUSTOM + * + * 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 + * 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. 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 + * + * 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 +#endif + +#if not defined(MOZZI_AUDIO_RATE) +#define MOZZI_AUDIO_RATE 16384 +#endif + +#if not defined(MOZZI_ANALOG_READ) +#define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD +#endif + +// 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 +#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) +#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 +#define MOZZI_AUDIO_PIN_1_REGISTER OCR1A +# endif +# 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 + +# if !defined(MOZZI_PWM_RATE) +#define MOZZI_PWM_RATE 125000 +# endif + +# if !defined(MOZZI_AUDIO_BITS_PER_CHANNEL) +#define MOZZI_AUDIO_BITS_PER_CHANNEL 7 +# endif + +#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 + +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) +#include "../config/known_16bit_timers.h" + +#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 +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN); +# endif +#endif diff --git a/internal/config_checks_esp32.h b/internal/config_checks_esp32.h new file mode 100644 index 000000000..5912cff11 --- /dev/null +++ b/internal/config_checks_esp32.h @@ -0,0 +1,147 @@ +/* + * 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 + +/** + * @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 + +#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_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 MOZZI_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_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_OUTPUT_I2S_DAC, 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 + +#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 new file mode 100644 index 000000000..206c868ac --- /dev/null +++ b/internal/config_checks_esp8266.h @@ -0,0 +1,121 @@ +/* + * 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 + +/** + * @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 +#endif + +#include "disable_2pinmode_on_github_workflow.h" +#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 +# 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) +# 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 + +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10 + +#endif // #ifndef CONFIG_CHECK_ESP8266_H diff --git a/internal/config_checks_generic.h b/internal/config_checks_generic.h new file mode 100644 index 000000000..cb446ea7b --- /dev/null +++ b/internal/config_checks_generic.h @@ -0,0 +1,202 @@ +/* + * 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. + * +*/ + +/** @page hardware Hardware and configuration + * + * Mozzi works on many different platforms, but not the same output modes are available on all hardware. For boards specific notes + * and configuration options, see the relevant sub-pages in this section: + * + * - @subpage hardware_avr + * - @subpage hardware_esp32 + * - @subpage hardware_esp8266 + * - @subpage hardware_mbed + * - @subpage hardware_renesas + * - @subpage hardware_rp2040 + * - @subpage hardware_samd + * - @subpage hardware_stm32duino + * - @subpage hardware_stm32_maple + * - (@subpage hardware_stm32_disambiguation) + * - @subpage hardware_teensy3 + * - @subpage hardware_teensy4 +*/ + +/** 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 + +#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 +#endif + +#if not defined(MOZZI_AUDIO_CHANNELS) +#define MOZZI_AUDIO_CHANNELS MOZZI_MONO +#endif + +//MOZZI_AUDIO_MODE -> hardware specific +//MOZZI_AUDIO_RATE -> hardware specific + +#if not defined(MOZZI_CONTROL_RATE) +# 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 +#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 +#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 + +//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" +#elif IS_ESP32() +#include "config_checks_esp32.h" +#elif IS_ESP8266() +#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 +#error Problem detecting hardware +#endif + + +/// 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 + + + +/// 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 + +#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 + +// 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) + +#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 + +#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)) +#endif + +#if !defined(MOZZI_AUDIO_BITS_OPTIMISTIC) +#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 +#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 +#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 + +#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 +# 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 +// 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_mbed.h b/internal/config_checks_mbed.h new file mode 100644 index 000000000..7ac69ba91 --- /dev/null +++ b/internal/config_checks_mbed.h @@ -0,0 +1,128 @@ +/* + * 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 + +/** + * @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 + +#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_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 MOZZI_AUDIO_RATE) +#endif + +#if !defined(MOZZI_ANALOG_READ) +# 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) + +#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 + +// 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 new file mode 100644 index 000000000..64ac380d9 --- /dev/null +++ b/internal/config_checks_renesas.h @@ -0,0 +1,83 @@ +/* + * 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 + +/** + * @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. + * + * @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 + +#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) + +#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 MOZZI_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 +# include "disable_stereo_on_github_workflow.h" +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 new file mode 100644 index 000000000..5ba884415 --- /dev/null +++ b/internal/config_checks_rp2040.h @@ -0,0 +1,130 @@ +/* + * 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 + +/** + * @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_PWM + * - MOZZI_OUTPUT_I2S_DAC + * + * The default mode is @ref rp2040_pwm . + * + * @section rp2040_pwm 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. + * + * 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. 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: + * @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 or MOZZI_I2S_FORMAT_PLAIN (default) + * @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 +#endif + +#include "disable_2pinmode_on_github_workflow.h" +#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 16 // PWMAudio expects 16bits +# 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 +# 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 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 + +#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) + +#endif // #ifndef CONFIG_CHECK_RP2040_H diff --git a/internal/config_checks_samd21.h b/internal/config_checks_samd21.h new file mode 100644 index 000000000..bc474ccdc --- /dev/null +++ b/internal/config_checks_samd21.h @@ -0,0 +1,82 @@ +/* + * 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 + +/** + * @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 + +#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) + +#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 MOZZI_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 +# include "disable_stereo_on_github_workflow.h" +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 new file mode 100644 index 000000000..59cd4b05d --- /dev/null +++ b/internal/config_checks_stm32duino.h @@ -0,0 +1,145 @@ +/* + * 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 + +/** +* @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 +* */ + +/** + * @page hardware_stm32duino Mozzi on STM32duino-based boards. + * + * port by Thomas Friedrichsmeier + * + * @note + * Be sure to understand the info given at @ref hardware_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 + +#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 TIM2 +# endif +#endif + +#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 +# include "disable_stereo_on_github_workflow.h" +MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1) +# if !defined(MOZZI_AUDIO_PER_CHANNEL) +# define MOZZI_AUDIO_BITS_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 + +#define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION ADC_RESOLUTION + +#endif // #ifndef CONFIG_CHECKS_STM32DUINO_H diff --git a/internal/config_checks_stm32maple.h b/internal/config_checks_stm32maple.h new file mode 100644 index 000000000..1157cc3a3 --- /dev/null +++ b/internal/config_checks_stm32maple.h @@ -0,0 +1,137 @@ +/* + * 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 + +/** + * @page hardware_stm32_maple Mozzi on STM32-boards with libmaple based core. + * port by Thomas Friedrichsmeier + * + * @note + * Be sure to understand the info given at @ref hardware_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 @ref @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/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(). + * + * - 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 + +#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 +# 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 +# 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 + +// 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 new file mode 100644 index 000000000..8c04eeb4f --- /dev/null +++ b/internal/config_checks_teensy.h @@ -0,0 +1,155 @@ +/* + * 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 + +/** @ingroup hardware + * @page hardware_teensy3 Mozzi on Teensy 3.0/3.1/3.2/3.4/3.5/LC boards. + * + * port by Tim Barrass + * + * @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() +# 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 +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 MOZZI_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 +# 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 +# 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 + +//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 new file mode 100644 index 000000000..5afdbda24 --- /dev/null +++ b/internal/config_checks_template.h @@ -0,0 +1,128 @@ +/** 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 + */ + +/* + * 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 */ +#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: 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. + * + * @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 + +/** 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: */ +# 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 + + +/** 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 +*/ 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 diff --git a/internal/mozzi_macros.h b/internal/mozzi_macros.h new file mode 100644 index 000000000..e3b14085e --- /dev/null +++ b/internal/mozzi_macros.h @@ -0,0 +1,107 @@ +/* + * 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 +#define MOZZI_MACROS_H + + +// internal dummy that should be distinct from any valid config value +#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, ...) \ + 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: @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)) + +/** @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)) + +/** @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). + * + * Example: @code + * #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, ...) 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)) + +/** @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. + * + * 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 preprocessor logic: " #X " != " #Y "."); + +/** @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 diff --git a/internal/mozzi_rand_p.h b/internal/mozzi_rand_p.h new file mode 100644 index 000000000..64b62a5ed --- /dev/null +++ b/internal/mozzi_rand_p.h @@ -0,0 +1,47 @@ +/* + * 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 + +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; + + 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 +}; + +inline void randSeed(uint32_t seed) { MozziRandPrivate::x = seed; }; + +} + +#endif diff --git a/teensyPinMap.h b/internal/teensyPinMap.h similarity index 89% rename from teensyPinMap.h rename to internal/teensyPinMap.h index 6904e124a..bacfb15d7 100644 --- a/teensyPinMap.h +++ b/internal/teensyPinMap.h @@ -1,22 +1,18 @@ /* * 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 -#include "mozzi_config.h" - - - inline uint8_t teensyPinMap(uint8_t pin) { if (pin < 24) return pin-14; // common to all teensys diff --git a/twi_nonblock.cpp b/internal/twi_nonblock.hpp similarity index 98% rename from twi_nonblock.cpp rename to internal/twi_nonblock.hpp index b2af78880..3d38e2d61 100644 --- a/twi_nonblock.cpp +++ b/internal/twi_nonblock.hpp @@ -1,16 +1,20 @@ /* * 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. * */ #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 @@ -597,4 +601,3 @@ ISR(TWI_vect) } } -#endif 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/library.properties b/library.properties index 053ce5357..87574f3d9 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Mozzi -version=1.1.2 +version=2.0.0 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,5 @@ category=Signal Input/Output url=https://sensorium.github.io/Mozzi/ architectures=* dot_a_linkage=false -includes=MozziGuts.h +includes=Mozzi.h +depends=FixMath diff --git a/meta.h b/meta.h index 85f99cc5b..098e666c7 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. @@ -6,6 +17,15 @@ Template meta-programming extras. #ifndef META_H_ #define META_H_ +/** @defgroup soundtables Look-up-tables and python scripts to generate tables or convert sounds. + +Look-up-tables and python scripts to generate tables or convert sounds. Includes ready-to-use wave tables and a few example samples which are in the Mozzi/tables and Mozzi/samples folders. You can convert your own sounds from a program like Audacity to tables for Mozzi with a script called char2mozzi.py, in Mozzi/python. Read the int8_t2mozzi.py file for instructions. Also check out the other scripts in the python folder for templates to use if you want to do your own thing. +*/ + +/** @defgroup util Utility functions, and debugging + +Utility functions. Includes functions for debugging and profiling high frequency code with an oscilloscope when serial is too slow, some miscellaneous functions used internally by Mozzi, python scripts for converting or generating sound tables, and assorted meta-programming utils. +*/ /** @ingroup util Enables you to instantiate a template based on an integer value. diff --git a/mozzi_analog.cpp b/mozzi_analog.cpp deleted file mode 100644 index 927bc40a9..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_config.h" -#include "mozzi_analog.h" - -#include "hardware_defines.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<= 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 - -// 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 - +// for setupFastAnalogRead() +enum ANALOG_READ_SPEED {FAST_ADC,FASTER_ADC,FASTEST_ADC}; -// 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 +/** @defgroup analog +@brief Efficient analog input functions for sensors and audio. -// for setupFastAnalogRead() -enum ANALOG_READ_SPEED {FAST_ADC,FASTER_ADC,FASTEST_ADC}; +Helps produce glitch-free audio by allowing analog input functions which normally block processing to be performed in the background. +*/ /** @ingroup analog @@ -121,31 +83,51 @@ and ADC6 do not have digital input buffers, and therefore do not require Digital Input Disable bits. @param channel_num the analog input channel you wish to use. */ -void disconnectDigitalIn(uint8_t channel_num); - +inline void disconnectDigitalIn(uint8_t channel_num) { +#if IS_AVR() + DIDR0 |= 1< 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 uint16_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); - +inline uint16_t mozziAnalogRead(uint8_t pin) { return mozziAnalogRead(pin); } +#else +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); 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 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 69c1d7a85..7fba4783d 100644 --- a/mozzi_fixmath.h +++ b/mozzi_fixmath.h @@ -1,24 +1,30 @@ /* * 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. * */ #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 + +@note For new sketches it is recommended to utitlize the FixMath library with its typesafe classes UFix and SFix, instead of these + typedefs! See https://github.com/tomcombriat/FixMath . These are provided for backwards compatibility, only. -/**@ingroup fixmath +Fixed point fractional number types and conversion routines. Fixed point is often best for fast audio code for Arduino, and these can ease some of the pain.

Note
Take care when converting that the important bits of your numbers will fit in the types you choose! + +Timing: converting between fixed and float 10-12us, converting between fixed types about 1us. +*/ + +/** @ingroup fixmath @{ */ // types diff --git a/mozzi_midi.h b/mozzi_midi.h index 94f9bb64d..44796ae76 100644 --- a/mozzi_midi.h +++ b/mozzi_midi.h @@ -1,23 +1,65 @@ +/* + * 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_ #include "mozzi_fixmath.h" -#include "mozzi_pgmspace.h" +#include "FixMath.h" +#include "mozzi_pgmspace.h" +/** @brief Internal. Do not use in your sketches. +Internal helper class. Not intended for use in your sketches, and details may change without notic. */ class MidiToFreqPrivate { private: friend int mtof(uint8_t); friend int mtof(int); - friend Q16n16 Q16n16_mtof(Q16n16); + 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]; }; - - - +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 + }; + + +/** @defgroup midi Midi note number to frequency conversions + +Useful if you like playing notes in tune. +*/ /** @ingroup midi Converts midi note number to frequency. Caution: this can take up to 400 @@ -93,4 +135,52 @@ inline Q16n16 Q16n16_mtof(Q16n16 midival_fractional) return (Q16n16) (freq1+ diff_fraction); }; +/** @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())); +}; + +/** @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())); +}; + +/** @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())); +}; + +/** @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_ */ 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 - }; 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.cpp b/mozzi_rand.cpp deleted file mode 100644 index 1564e3641..000000000 --- a/mozzi_rand.cpp +++ /dev/null @@ -1,264 +0,0 @@ -#include "mozzi_rand.h" - -#include "hardware_defines.h" - -#if IS_STM32() -//#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 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 - // static unsigned long x=123456789, y=362436069, z=521288629; - unsigned long 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; -} - - -#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 - - -/** @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 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 -*/ -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_STM32() - // 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 -} - - - -/** @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..7abf9fab1 100644 --- a/mozzi_rand.h +++ b/mozzi_rand.h @@ -1,31 +1,167 @@ +/* + * 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_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include +#include "internal/mozzi_rand_p.h" + +/** @defgroup random Fast random number generator functions + +These replace Arduino random() which is so slow it will stop your audio. They can even be used to generate audio noise. +*/ + +/** @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 MozziPrivate::MozziRandPrivate::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) { MozziPrivate::randSeed(seed); }; + +/** @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. +*/ +inline void randSeed() { MozziPrivate::MozziRandPrivate::autoSeed(); }; + +/** @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); }; + +/** @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; +} + +/** @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); +} + +/** @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. -unsigned long xorshift96(); +@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 int rand(int minval, int maxval) +{ + return (int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); +} -void xorshiftSeed(unsigned long seed); -void randSeed(unsigned long seed); -void randSeed(); +/** @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. -int8_t rand(int8_t minval, int8_t maxval); -int8_t rand(int8_t maxval); +@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 int rand(int maxval) +{ + return (int) (((xorshift96() & 0xFFFF) * maxval)>>16); +} -uint8_t rand(uint8_t minval, uint8_t maxval); -uint8_t rand(uint8_t 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 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 unsigned int rand(unsigned int minval, unsigned int maxval) +{ + return (unsigned int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval); +} -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 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 minval, unsigned int maxval); -unsigned int rand(unsigned int maxval); +@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 unsigned int rand(unsigned int maxval) +{ + return (unsigned int) (((xorshift96() & 0xFFFF) * maxval)>>16); +} -uint8_t randMidiNote(); +/** @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_ */ diff --git a/mozzi_utils.cpp b/mozzi_utils.cpp deleted file mode 100644 index 52dafd600..000000000 --- a/mozzi_utils.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "mozzi_utils.h" - -/** @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 -*/ - -/* NOTE: previous version 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 - */ - 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..d275b95ff 100644 --- a/mozzi_utils.h +++ b/mozzi_utils.h @@ -1,13 +1,19 @@ +/* + * 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_ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include #include "hardware_defines.h" @@ -59,8 +65,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_ */ 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/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/twi_nonblock.h b/twi_nonblock.h index 6bc894079..954770f9a 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_ @@ -85,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 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 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 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 -