PDA

View Full Version : Teensyduino 1.52 Beta #6



Paul
05-14-2020, 10:40 PM
Here is a sixth (and hopefully last) beta test for Teensyduino 1.52.

My hope is to release 1.52 within the next 24-48 hours. Please give this last beta a try with any large or complex libraries and programs you may have.


Linux 32 bit:
https://www.pjrc.com/teensy/td_152-beta6/TeensyduinoInstall.linux32

Linux 64 bit:
https://www.pjrc.com/teensy/td_152-beta6/TeensyduinoInstall.linux64

Linux ARM:
https://www.pjrc.com/teensy/td_152-beta6/TeensyduinoInstall.linuxarm

Linux ARM64:
https://www.pjrc.com/teensy/td_152-beta6/TeensyduinoInstall.linuxaarch64

MacOS 10.10 to 10.15:
https://www.pjrc.com/teensy/td_152-beta6/Teensyduino_MacOS_Catalina.zip

MacOS 10.8 to 10.14:
https://www.pjrc.com/teensy/td_152-beta6/TeensyduinoInstall.dmg

Windows:
https://www.pjrc.com/teensy/td_152-beta6/TeensyduinoInstall.exe


Changes since Teensyduino 1.52-beta5 (https://forum.pjrc.com/threads/60864-Teensyduino-1-52-Beta-5):

Increase PSRAM clock to 88 MHz & fix error in writing clock setting
Use strong drive & hysteresis for FlexSPI2 pins
Disable non-working Audio PWM output on Teensy 4.x
Minor improvement in OctoWS2811 for Teensy 4.x

defragster
05-14-2020, 10:51 PM
Win 10 install over 1.8.12 Good!

IDE Compile of recent T_4.1 PSRAM logger - using two buffers of 3.14 Million Bytes with 200,000 _isr() timer updates per second running without error where loop() does validation check on full data buffer each 983 ms during _isr() logging

mjs513
05-14-2020, 11:29 PM
Same here installed on a Win10x64 over 1.8.12 no problem.

Ran the memtest sketch @1.008Ghz successfully - all tests passed. Also ran flashtes6 which tests the FLASH (SPIFFS) along with PSRAM at 1.008GHz and no issues.

bicycleguy
05-15-2020, 12:16 AM
What beta #5 gives, b #6 taketh away!
The text munging at 24 MHz CPU speed https://forum.pjrc.com/threads/60864-Teensyduino-1-52-Beta-5?p=239150&viewfull=1#post239150 that b5 fixed 6 has reverted.

This https://forum.pjrc.com/threads/57326-T4-0-Memory-trying-to-make-sense-of-the-different-regions?p=238989&viewfull=1#post238989 shows the issue directly. I don't care about the debug optimization but the 24 MHz would be nice for low power but I don't think I can trust it.

I don't think it's a terminal problem because:
(all 24MHz, fastest)
1. compiled loaded and ran in b5 into T4.1 result ok
2. unplug t4.1, quit b5, quit tdb5
3. start b6, plug in T4 and open terminal window still ok
4. recompile (settings will all stay the same) and run result bad
5. leave the bad in T4
6. quit b6 tdb6 and open b5 result still bad
7. try to compile and load. result compiles but won't load until the T4 button is pressed. Is this Frank's button pressing problem?

mjs513
05-15-2020, 12:57 AM
Modified your sketch and ran it on a T4.1 at 24Mhz with IDE1.8.12 and 1.52-b6. Had no issues running the modified sketch but did have an issue with your sketch in the zip. Main difference is that I am using @Frank B's library since he has changed it recently and for using the T4.1:

extern "C" uint32_t set_arm_clock(uint32_t frequency);
static uint32_t t0;
#define MHZ_MHZ 1000000

#include "T4_PowerButton.h"


void setup() {
while (!Serial && millis() < 4000);
//set_arm_clock(24 * MHZ_MHZ);
flexRamInfo();
// Serial.println(memfree());
}

void loop() {
} Try this and see if it works for you.

defragster
05-15-2020, 01:12 AM
I compiled the sketch from zip at 24 Mhz w/1.52b6 and there was some upload grief and print issue - though using TyComm 'GUI Bootloader button' {same USB toggle as IDE AFAIK} as not in IDE just now. Using whatever T4_PowerButton.h that was here - seems to work.

24 Mhz has been an edge case IIRC - not expected to work? Garbage spew in prints is common since T_4?

I edited build.txt to support 26 Mhz and that seems to look better. Not sure where the 'jump in function / power is'


teensy41.menu.speed.26=26 MHz
teensy41.menu.speed.26.build.fcpu=26000000


Adding this at 24 Mhz this misses some chars and sometime garb char - at 26 Mhz it scrolls perfectly:

void loop() {
delay(500);
flexRamInfo();
}

KurtE
05-15-2020, 01:29 AM
Again a quick FYI - I updated to beta 6, and on the T4.1 beta thread posted a external memory allocator sketch, quick and very dirty.

bicycleguy
05-15-2020, 04:30 AM
Sorry for the delay getting back. Where do I find "T4_PowerButton.h"

PhilB
05-15-2020, 04:43 AM
Installed beta 6 over Teensyduino 1.50.

I'm getting a connection error connecting a serial terminal via USB to grblHAL built for a Teensy 4.0 with 1.52 beta 6 and using the PJRC USB library.

I can connect no problem to grblHAL built with Teensyduino 1.50 using the PJRC USB Library. Same USB cable in both cases. Teensy 4.0 in both cases.

grblHAL can also use the arduino USB class library and a serial terminal can connect to it when built with 1.52 beta 6. No problem connecting.

Since grblHAL is huge, I'm willing to do some digging to figure this out. I'm not the author of this code but am working with him. Any suggest of what to look for?

In summary:
built with 1.50, using PJRC USB Library - serial terminal connects
built with 1.52#6, using PJRC USB Library - serial terminal fails to connect
built with 1.52#6, using Arduino USB Class library - serial terminal connects
built with 1.50, using Arduino USB Class Library - serial terminal connects

grblHAL can be found here. (https://github.com/terjeio/grblHAL)

defragster
05-15-2020, 05:12 AM
Are PJRC USB Library and Arduino USB Class library referring to IDE Serial monitors or other 'libraries'?

cross post - answered below ...

PhilB
05-15-2020, 05:12 AM
Here is the source for the interface to the PJRC USB code. C++ first, .h second. Note that USB_SERIAL_GRBL == 2 causes this code to be compiled. This code remains unchanged between 1.50 and 1.52#6.

/*

usb_serial_pjrc.c - driver code for IMXRT1062 processor (on Teensy 4.0 board) : USB serial port wrapper, PJRC version

Part of GrblHAL

Copyright (c) 2018-2020 Terje Io


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

Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.

*/

//#include "avr/pgmspace.h"
#include "usb_serial.h"

#include "driver.h"

#if USB_SERIAL_GRBL == 2

#define BLOCK_RX_BUFFER_SIZE 20

static stream_block_tx_buffer_t txbuf = {0};
static char rxbuf[BLOCK_RX_BUFFER_SIZE];
static stream_rx_buffer_t usb_rxbuffer, usb_rxbackup;

void usb_serialInit(void)
{
// usb_serial_configure(); // Done somewhere already - do not call again

txbuf.max_length = usb_serial_write_buffer_free(); // 6144
txbuf.max_length = (txbuf.max_length > BLOCK_TX_BUFFER_SIZE ? BLOCK_TX_BUFFER_SIZE : txbuf.max_length) - 20;
}

//
// Returns number of characters in serial input buffer
//
uint16_t usb_serialRxCount (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
return (uint16_t)BUFCOUNT(head, tail, RX_BUFFER_SIZE);
}

//
// Returns number of free characters in serial input buffer
//
uint16_t usb_serialRxFree (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
return (uint16_t)((RX_BUFFER_SIZE - 1) - BUFCOUNT(head, tail, RX_BUFFER_SIZE));
}

//
// Flushes the serial input buffer (including the USB buffer)
//
void usb_serialRxFlush (void)
{
usb_serial_flush_input();
usb_rxbuffer.tail = usb_rxbuffer.head;
}

//
// Flushes and adds a CAN character to the serial input buffer
//
void usb_serialRxCancel (void)
{
usb_rxbuffer.data[usb_rxbuffer.head] = CMD_RESET;
usb_rxbuffer.tail = usb_rxbuffer.head;
usb_rxbuffer.head = (usb_rxbuffer.tail + 1) & (RX_BUFFER_SIZE - 1);
}

//
// Writes a character to the serial output stream
//
bool usb_serialPutC (const char c)
{
usb_serial_putchar(c);

return true;
}

//
// Writes a null terminated string to the serial output stream, blocks if buffer full
//
void usb_serialWriteS (const char *s)
{
if(*s == '\0')
return;

size_t length = strlen(s);

if((length + txbuf.length) < BLOCK_TX_BUFFER_SIZE) {

memcpy(txbuf.s, s, length);
txbuf.length += length;
txbuf.s += length;

if(s[length - 1] == ASCII_LF || txbuf.length > txbuf.max_length) {

size_t txfree;
txbuf.s = txbuf.data;

while(txbuf.length) {

if((txfree = usb_serial_write_buffer_free()) > 10) {

length = txfree < txbuf.length ? txfree : txbuf.length;

usb_serial_write(txbuf.s, length); //

txbuf.length -= length;
txbuf.s += length;
}

if(txbuf.length && !hal.stream_blocking_callback()) {
txbuf.length = 0;
txbuf.s = txbuf.data;
return;
}
}
txbuf.s = txbuf.data;
}
}
}

//
// Writes a null terminated string to the serial output stream followed by EOL, blocks if buffer full
//
void usb_serialWriteLn (const char *s)
{
usb_serialWriteS(s);
usb_serialWriteS(ASCII_EOL);
}

//
// Writes a number of characters from string to the serial output stream followed by EOL, blocks if buffer full
//
void usb_serialWrite (const char *s, uint16_t length)
{
char *ptr = (char *)s;

while(length--)
usb_serialPutC(*ptr++);
}

//
// serialGetC - returns -1 if no data available
//
int16_t usb_serialGetC (void)
{
uint16_t bptr = usb_rxbuffer.tail;

if(bptr == usb_rxbuffer.head)
return -1; // no data available else EOF

char data = usb_rxbuffer.data[bptr++]; // Get next character, increment tmp pointer
usb_rxbuffer.tail = bptr & (RX_BUFFER_SIZE - 1); // and update pointer

return (int16_t)data;
}

// "dummy" version of serialGetC
static int16_t serialGetNull (void)
{
return -1;
}

bool usb_serialSuspendInput (bool suspend)
{
if(suspend)
hal.stream.read = serialGetNull;
else if(usb_rxbuffer.backup)
memcpy(&usb_rxbuffer, &usb_rxbackup, sizeof(stream_rx_buffer_t));

return usb_rxbuffer.tail != usb_rxbuffer.head;
}

//
// This function get called from the systick interrupt handler,
// used here to get characters off the USB serial input stream and buffer
// them for processing by grbl. Real time command characters are stripped out
// and submitted for realtime processing.
//
void usb_execute_realtime (uint_fast16_t state)
{
char c, *dp;
int avail, free;

if((avail = usb_serial_available())) {

dp = rxbuf;
free = usb_serialRxFree();
free = free > BLOCK_RX_BUFFER_SIZE ? BLOCK_RX_BUFFER_SIZE : free;

avail = usb_serial_read(rxbuf, avail > free ? free : avail);

while(avail--) {
c = *dp++;
if(c == CMD_TOOL_ACK && !usb_rxbuffer.backup) {
memcpy(&usb_rxbackup, &usb_rxbuffer, sizeof(stream_rx_buffer_t));
usb_rxbuffer.backup = true;
usb_rxbuffer.tail = usb_rxbuffer.head;
hal.stream.read = usb_serialGetC; // restore normal input
} else if(!hal.stream.enqueue_realtime_command(c)) {
uint32_t bptr = (usb_rxbuffer.head + 1) & (RX_BUFFER_SIZE - 1); // Get next head pointer
if(bptr == usb_rxbuffer.tail) // If buffer full
usb_rxbuffer.overflow = On; // flag overflow,
else {
usb_rxbuffer.data[usb_rxbuffer.head] = c; // else add character data to buffer
usb_rxbuffer.head = bptr; // and update pointer
}
}
}
}
}

#endif


/*

usb_serial.h - driver code for IMXRT1062 processor (on Teensy 4.0 board)

Part of GrblHAL

Copyright (c) 2018-2020 Terje Io

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

Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef _USB_SERIAL_H_
#define _USB_SERIAL_H_

#include <stdbool.h>
#include <stdint.h>

extern void usb_execute_realtime (uint_fast16_t state);

#define usb_serial_poll() usb_execute_realtime(0)

void usb_serialInit(void);
int16_t usb_serialGetC(void);
bool usb_serialPutC(const char c);
void usb_serialWriteS(const char *s);
void usb_serialWriteLn(const char *s);
void usb_serialWrite(const char *s, uint16_t length);
bool usb_serialSuspendInput (bool suspend);

uint16_t usb_serialTxCount(void);
uint16_t usb_serialRxCount(void);
uint16_t usb_serialRxFree(void);
void usb_serialRxFlush(void);
void usb_serialRxCancel(void);

#endif

PhilB
05-15-2020, 05:16 AM
Are PJRC USB Library and Arduino USB Class library referring to IDE Serial monitors or other 'libraries'?

cross post - answered below ...
Sorry about that.

PhilB
05-15-2020, 05:25 AM
For what it's worth, here is the arduino code wrapper that does work correctly when built with 1.52#6
C++ file:

/*

usb_serial_ard.cpp - driver code for IMXRT1062 processor (on Teensy 4.0 board) : USB serial port wrapper

Part of GrblHAL

Copyright (c) 2018-2020 Terje Io


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

Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.

*/

#include <string.h>

#include "Arduino.h"

#include "driver.h"

#if USB_SERIAL_GRBL == 1

#ifdef __cplusplus
extern "C" {
#endif

#define BLOCK_RX_BUFFER_SIZE 20

static stream_block_tx_buffer_t txbuf = {0};
static char rxbuf[BLOCK_RX_BUFFER_SIZE];
static stream_rx_buffer_t usb_rxbuffer, usb_rxbackup;

void usb_serialInit(void)
{
txbuf.s = txbuf.data;

SerialUSB.begin(BAUD_RATE);

#if USB_SERIAL_WAIT
while(!SerialUSB); // Wait for connection
#endif

txbuf.max_length = SerialUSB.availableForWrite(); // 6144 bytes
txbuf.max_length = (txbuf.max_length > BLOCK_TX_BUFFER_SIZE ? BLOCK_TX_BUFFER_SIZE : txbuf.max_length) - 20;
}

//
// Returns number of characters in serial input buffer
//
uint16_t usb_serialRxCount (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
return (uint16_t)BUFCOUNT(head, tail, RX_BUFFER_SIZE);
}

//
// Returns number of free characters in serial input buffer
//
uint16_t usb_serialRxFree (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
return (uint16_t)((RX_BUFFER_SIZE - 1) - BUFCOUNT(head, tail, RX_BUFFER_SIZE));
}

//
// Flushes the serial input buffer (including the USB buffer)
//
void usb_serialRxFlush (void)
{
SerialUSB.flush();
usb_rxbuffer.tail = usb_rxbuffer.head;
}

//
// Flushes and adds a CAN character to the serial input buffer
//
void usb_serialRxCancel (void)
{
usb_rxbuffer.data[usb_rxbuffer.head] = CMD_RESET;
usb_rxbuffer.tail = usb_rxbuffer.head;
usb_rxbuffer.head = (usb_rxbuffer.tail + 1) & (RX_BUFFER_SIZE - 1);
}

//
// Writes a character to the serial output stream
//
bool usb_serialPutC (const char c)
{
SerialUSB.write(c);

return true;
}

//
// Writes a null terminated string to the serial output stream, blocks if buffer full.
// Buffers locally up to 40 characters or until the string is terminated with a ASCII_LF character.
// NOTE: grbl always sends ASCII_LF terminated strings!
//
void usb_serialWriteS (const char *s)
{
if(*s == '\0')
return;

size_t length = strlen(s);

if((length + txbuf.length) < BLOCK_TX_BUFFER_SIZE) {

memcpy(txbuf.s, s, length);
txbuf.length += length;
txbuf.s += length;

if(s[length - 1] == ASCII_LF || txbuf.length > txbuf.max_length) {

size_t txfree;
txbuf.s = txbuf.data;

while(txbuf.length) {

if((txfree = SerialUSB.availableForWrite()) > 10) {

length = txfree < txbuf.length ? txfree : txbuf.length;

SerialUSB.write((uint8_t *)txbuf.s, length); // doc is wrong - does not return bytes sent!

txbuf.length -= length;
txbuf.s += length;
}

if(txbuf.length && !hal.stream_blocking_callback()) {
txbuf.length = 0;
txbuf.s = txbuf.data;
return;
}
}
txbuf.s = txbuf.data;
}
}
}

//
// Writes a null terminated string to the serial output stream followed by EOL, blocks if buffer full
//
void usb_serialWriteLn (const char *s)
{
usb_serialWriteS(s);
usb_serialWriteS(ASCII_EOL);
}

//
// Writes a number of characters from string to the serial output stream followed by EOL, blocks if buffer full
//
void usb_serialWrite (const char *s, uint16_t length)
{
char *ptr = (char *)s;

while(length--)
usb_serialPutC(*ptr++);
}

//
// serialGetC - returns -1 if no data available
//
int16_t usb_serialGetC (void)
{
uint16_t bptr = usb_rxbuffer.tail;

if(bptr == usb_rxbuffer.head)
return -1; // no data available else EOF

char data = usb_rxbuffer.data[bptr++]; // Get next character, increment tmp pointer
usb_rxbuffer.tail = bptr & (RX_BUFFER_SIZE - 1); // and update pointer

return (int16_t)data;
}

// "dummy" version of serialGetC
static int16_t serialGetNull (void)
{
return -1;
}

bool usb_serialSuspendInput (bool suspend)
{
if(suspend)
hal.stream.read = serialGetNull;
else if(usb_rxbuffer.backup)
memcpy(&usb_rxbuffer, &usb_rxbackup, sizeof(stream_rx_buffer_t));

return usb_rxbuffer.tail != usb_rxbuffer.head;
}

//
// This function get called from the systick interrupt handler,
// used here to get characters off the USB serial input stream and buffer
// them for processing by grbl. Real time command characters are stripped out
// and submitted for realtime processing.
//
void usb_execute_realtime (uint_fast16_t state)
{
char c, *dp;
int avail, free;

if((avail = SerialUSB.available())) {

dp = rxbuf;
free = usb_serialRxFree();
free = free > BLOCK_RX_BUFFER_SIZE ? BLOCK_RX_BUFFER_SIZE : free;

avail = SerialUSB.readBytes(rxbuf, avail > free ? free : avail);

while(avail--) {
c = *dp++;
if(c == CMD_TOOL_ACK && !usb_rxbuffer.backup) {
memcpy(&usb_rxbackup, &usb_rxbuffer, sizeof(stream_rx_buffer_t));
usb_rxbuffer.backup = true;
usb_rxbuffer.tail = usb_rxbuffer.head;
hal.stream.read = usb_serialGetC; // restore normal input
} else if(!hal.stream.enqueue_realtime_command(c)) {
uint32_t bptr = (usb_rxbuffer.head + 1) & (RX_BUFFER_SIZE - 1); // Get next head pointer
if(bptr == usb_rxbuffer.tail) // If buffer full
usb_rxbuffer.overflow = On; // flag overflow,
else {
usb_rxbuffer.data[usb_rxbuffer.head] = c; // else add character data to buffer
usb_rxbuffer.head = bptr; // and update pointer
}
}
}
}
}

#ifdef __cplusplus
}
#endif

#endif

.h file:

/*

usb_serial_ard.h - driver code for IMXRT1062 processor (on Teensy 4.0 board)

Part of GrblHAL

Copyright (c) 2018-2020 Terje Io

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

Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef _USB_SERIAL_H_
#define _USB_SERIAL_H_

#include <stdbool.h>
#include <stdint.h>

extern void usb_execute_realtime (uint_fast16_t state);

#define usb_serial_poll() usb_execute_realtime(0)

void usb_serialInit(void);
int16_t usb_serialGetC(void);
bool usb_serialPutC(const char c);
void usb_serialWriteS(const char *s);
void usb_serialWriteLn(const char *s);
void usb_serialWrite(const char *s, uint16_t length);
bool usb_serialSuspendInput (bool suspend);

uint16_t usb_serialTxCount(void);
uint16_t usb_serialRxCount(void);
uint16_t usb_serialRxFree(void);
void usb_serialRxFlush(void);
void usb_serialRxCancel(void);

#endif

MichaelMeissner
05-15-2020, 05:52 AM
Sorry for the delay getting back. Where do I find "T4_PowerButton.h"

Frank B wrote it:

https://github.com/FrankBoesing/T4_PowerButton.git

PaulStoffregen
05-15-2020, 06:57 AM
but the 24 MHz would be nice for low power but I don't think I can trust it.

I've committed a workaround for USB serial corruption at 24 MHz.

https://github.com/PaulStoffregen/cores/commit/e5a9b19465ad8a2faaa35dd61e2631343007c807

defragster
05-15-2020, 08:54 AM
I've committed a workaround for USB serial corruption at 24 MHz.

https://github.com/PaulStoffregen/cores/commit/e5a9b19465ad8a2faaa35dd61e2631343007c807

That seems a safe change - since non-DMAMEM is where it all started.

DD4WH
05-15-2020, 12:42 PM
Win10, Arduino 1.8.12, TD 1.52 beta6, T4.1 and Teensy audio shield version D, 2 PSRAM chips, using EXTRAM as part of the audio buffering --> works with partitioned convolution filtering


/*
* (c) DD4WH 15/05/2020
*
* Real Time PARTITIONED BLOCK CONVOLUTION FILTERING (STEREO)
*
* thanks a lot to Brian Millier and Warren Pratt for your help!
*
* using a guitar cabinet impulse response with up to about 20000 coefficients per channel
*
* uses Teensy 4.1 and Teensy audio shield rev D, uses PSRAM chip(s) soldered to underside of T4.1
*
* inspired by and uses code from wdsp library by Warren Pratt
* https://github.com/g0orx/wdsp/blob/master/firmin.c
*
************************************************** *******************************

GNU GPL LICENSE v3

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 3 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, see <http://www.gnu.org/licenses/>

************************************************** *******************************
*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <arm_math.h>
#include <arm_const_structs.h> // in the Teensy 4.0 audio library, the ARM CMSIS DSP lib is already a newer version
#include <utility/imxrt_hw.h> // necessary for setting the sample rate, thanks FrankB !
#include <T4_PowerButton.h> // for flexRamInfo

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// USER DEFINES

// Choose only one of these impulse responses !

//#define IR1 // 512 taps // MG impulse response from bmillier github @44.1ksps
//#define IR2 // 4096 taps // impulse response @44.1ksps
//#define IR3 // 7552 taps // impulse response @44.1ksps
//#define IR4 // 17920 taps // impulse response 400ms @44.1ksps
//#define IR5 // 21632 taps // impulse response 490ms @44.1ksps
//#define IR6 // 5760 taps, 18.72% load vs. 15.00%
//#define IR7 // 22016 taps, 50.62% load, 93.48% RAM1, 32064 bytes free
//#define IR8 // 25552 taps, too much !
// about 25000 taps is MAXIMUM --> about 0.5 seconds
//#define LPMINPHASE512 // 512 taps minimum phase 2.7kHz lowpass filter
//#define LPMINPHASE1024 // 1024 taps minimum phase 2.7kHz lowpass filter
#define LPMINPHASE2048PASSTHRU // 2048 taps minimum phase 19.0kHz lowpass filter
//#define LPMINPHASE4096 // 4096 taps minimum phase 2.7kHz lowpass filter
const float32_t PROGMEM audio_gain = 2.5; // has to be adjusted from 1.0 to 10.0 depending on the filter gain / impulse resonse gain
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

#if defined(IR1)
#include "impulse_response_1.h"
const int nc = 512; // number of taps for the FIR filter
#elif defined(IR2)
#include "impulse_response_2.h"
const int nc = 4096; // number of taps for the FIR filter
#elif defined(IR3)
#include "impulse_response_3.h"
const int nc = 7552; // number of taps for the FIR filter
#elif defined(IR5)
#include "impulse_response_5.h"
const int nc = 21632; // number of taps for the FIR filter
#elif defined(IR6)
#include "impulse_response_6.h"
const int nc = 5760; // number of taps for the FIR filter,
#elif defined(IR7)
#include "impulse_response_7.h"
const int nc = 22016; // number of taps for the FIR filter,
#elif defined(IR8)
#include "impulse_response_8.h"
const int nc = 25552; // number of taps for the FIR filter,
#elif defined(LPMINPHASE512)
#include "lp_minphase_512.h"
const int nc = 512;
#elif defined(LPMINPHASE1024)
#include "lp_minphase_1024.h"
const int nc = 1024;
#elif defined(LPMINPHASE2048PASSTHRU)
#include "lp_minphase_2048passthru.h"
const int nc = 2048;
#elif defined(LPMINPHASE4096)
#include "lp_minphase_4096.h"
const int nc = 4096;
#else
#include "impulse_response_4.h"
const int nc = 17920; // number of taps for the FIR filter
#endif

extern "C" uint32_t set_arm_clock(uint32_t frequency);

//#define LATENCY_TEST
const double PROGMEM FHiCut = 2500.0;
const double PROGMEM FLoCut = -FHiCut;
// define your sample rate
const double PROGMEM SAMPLE_RATE = 44100;
// the latency of the filter is meant to be the same regardless of the number of taps for the filter
// partition size of 128 translates to a latency of 128/sample rate, ie. to 2.9msec with 44.1ksps

// latency can even be reduced by setting partitionsize to 64
// however, this only works, if you set AUDIO_BLOCK_SAMPLES to 64 in AudioStream.h
const int PROGMEM partitionsize = 128;

#define DEBUG
#define FOURPI (2.0 * TWO_PI)
#define SIXPI (3.0 * TWO_PI)
#define BUFFER_SIZE partitionsize
int32_t sum;
int idx_t = 0;
int16_t *sp_L;
int16_t *sp_R;
uint8_t PROGMEM FIR_filter_window = 1;
const uint32_t PROGMEM FFT_L = 2 * partitionsize;
float32_t mean = 1;
uint8_t first_block = 1;
const uint32_t PROGMEM FFT_length = FFT_L;
const int PROGMEM nfor = nc / partitionsize; // number of partition blocks --> nfor = nc / partitionsize
//float DMAMEM cplxcoeffs[nc * 2]; // this holds the initial complex coefficients for the filter BEFORE partitioning
float32_t DMAMEM maskgen[FFT_L * 2];
//float32_t DMAMEM fmask[nfor][FFT_L * 2]; //
EXTMEM float32_t fmask[nfor][FFT_L * 2]; //
float32_t DMAMEM fftin[FFT_L * 2];
float32_t accum[FFT_L * 2];
float fftout[nfor][FFT_L * 2]; //

int buffidx = 0;
int k = 0;
//int idxmask = nfor - 1;

uint32_t all_samples_counter = 0;
uint8_t no_more_latency_test = 0;

const uint32_t N_B = FFT_L / 2 / BUFFER_SIZE;
uint32_t N_BLOCKS = N_B;
float32_t DMAMEM float_buffer_L [BUFFER_SIZE * N_B];
float32_t DMAMEM float_buffer_R [BUFFER_SIZE * N_B];
float32_t DMAMEM last_sample_buffer_L [BUFFER_SIZE * N_B];
float32_t DMAMEM last_sample_buffer_R [BUFFER_SIZE * N_B];
// complex FFT with the new library CMSIS V4.5
const static arm_cfft_instance_f32 *S;
// complex iFFT with the new library CMSIS V4.5
const static arm_cfft_instance_f32 *iS;
// FFT instance for direct calculation of the filter mask
// from the impulse response of the FIR - the coefficients
const static arm_cfft_instance_f32 *maskS;

// this audio comes from the codec by I2S
AudioInputI2S i2s_in;
AudioRecordQueue Q_in_L;
AudioRecordQueue Q_in_R;
AudioMixer4 mixleft;
AudioMixer4 mixright;
AudioPlayQueue Q_out_L;
AudioPlayQueue Q_out_R;
AudioOutputI2S i2s_out;

AudioConnection patchCord1(i2s_in, 0, Q_in_L, 0);
AudioConnection patchCord2(i2s_in, 1, Q_in_R, 0);

AudioConnection patchCord3(Q_out_L, 0, mixleft, 0);
AudioConnection patchCord4(Q_out_R, 0, mixright, 0);
AudioConnection patchCord9(mixleft, 0, i2s_out, 1);
AudioConnection patchCord10(mixright, 0, i2s_out, 0);
AudioControlSGTL5000 codec;

void setup() {
Serial.begin(115200);
while(!Serial);

AudioMemory(10);
delay(100);

// Enable the audio shield, select input, and enable output
codec.enable();
codec.adcHighPassFilterDisable(); //
codec.inputSelect(AUDIO_INPUT_LINEIN); // AUDIO_INPUT_MIC
codec.volume(0.6);

set_arm_clock(600000000);

/************************************************** **************************************
Audio Setup
************************************************** **************************************/
mixleft.gain(0, 1.0);
mixright.gain(0, 1.0);

setI2SFreq(SAMPLE_RATE);

/************************************************** **************************************
properly initialise variables in DMAMEM
************************************************** **************************************/

for(unsigned jj = 0; jj < nfor; jj++)
{
for(unsigned ii = 0; ii < FFT_L * 2; ii++)
{
fftout[jj][ii] = 0.1;
fmask[jj][ii] = 0.0;
}
}

/* for (unsigned i = 0; i < FFT_length * 2; i++)
{
cplxcoeffs[i] = 0.0;
}
*/

/************************************************** **************************************
init complex FFTs
************************************************** **************************************/
switch (FFT_length)
{
case 128:
S = &arm_cfft_sR_f32_len128;
iS = &arm_cfft_sR_f32_len128;
maskS = &arm_cfft_sR_f32_len128;
break;
case 256:
S = &arm_cfft_sR_f32_len256;
iS = &arm_cfft_sR_f32_len256;
maskS = &arm_cfft_sR_f32_len256;
break;
}

/************************************************** **************************************
Calculate the FFT of the FIR filter coefficients once to produce the FIR filter mask
************************************************** **************************************/
init_partitioned_filter_masks();

flexRamInfo();

Serial.println();
Serial.print("AUDIO_BLOCK_SAMPLES: "); Serial.println(AUDIO_BLOCK_SAMPLES);

Serial.println();

/************************************************** **************************************
begin to queue the audio from the audio library
************************************************** **************************************/
delay(100);
Q_in_L.begin();
Q_in_R.begin();

} // END OF SETUP
elapsedMillis msec = 0;
void loop() {
elapsedMicros usec = 0;
// are there at least N_BLOCKS buffers in each channel available ?
if (Q_in_L.available() > N_BLOCKS + 0 && Q_in_R.available() > N_BLOCKS + 0)
{

// get audio samples from the audio buffers and convert them to float
for (unsigned i = 0; i < N_BLOCKS; i++)
{
sp_L = Q_in_L.readBuffer();
sp_R = Q_in_R.readBuffer();

// convert to float one buffer_size
// float_buffer samples are now standardized from > -1.0 to < 1.0
arm_q15_to_float (sp_L, &float_buffer_L[BUFFER_SIZE * i], BUFFER_SIZE); // convert int_buffer to float 32bit
arm_q15_to_float (sp_R, &float_buffer_R[BUFFER_SIZE * i], BUFFER_SIZE); // convert int_buffer to float 32bit
Q_in_L.freeBuffer();
Q_in_R.freeBuffer();
}

/************************************************** ********************************
Digital convolution
************************************************** ********************************/
// basis for this was Lyons, R. (2011): Understanding Digital Processing.
// "Fast FIR Filtering using the FFT", pages 688 - 694
// numbers for the steps taken from that source
// Method used here: overlap-and-save

// ONLY FOR the VERY FIRST FFT: fill first samples with zeros
if (first_block) // fill real & imaginaries with zeros for the first BLOCKSIZE samples
{
for (unsigned i = 0; i < partitionsize * 4; i++)
{
fftin[i] = 0.0;
}
first_block = 0;
}
else
{ // HERE IT STARTS for all other instances
// fill FFT_buffer with last events audio samples
for (unsigned i = 0; i < partitionsize; i++)
{
fftin[i * 2] = last_sample_buffer_L[i]; // real
fftin[i * 2 + 1] = last_sample_buffer_R[i]; // imaginary
}
}

// copy recent samples to last_sample_buffer for next time!
for (unsigned i = 0; i < partitionsize; i++)
{
last_sample_buffer_L [i] = float_buffer_L[i];
last_sample_buffer_R [i] = float_buffer_R[i];
}

// now fill recent audio samples into FFT_buffer (left channel: re, right channel: im)
for (unsigned i = 0; i < partitionsize; i++)
{
fftin[FFT_length + i * 2] = float_buffer_L[i]; // real
fftin[FFT_length + i * 2 + 1] = float_buffer_R[i]; // imaginary
}

#if defined(LATENCY_TEST)
if(msec > 2000 && !no_more_latency_test)
{
// latency test
fftin[42] = 10.0; fftin[44] = -10.0;
fftin[43] = 10.0; fftin[45] = -10.0;
no_more_latency_test = 1;
}
if(no_more_latency_test == 1) all_samples_counter += partitionsize;
#endif
/************************************************** ********************************
Complex Forward FFT
************************************************** ********************************/
// calculation is performed in-place the FFT_buffer [re, im, re, im, re, im . . .]
arm_cfft_f32(S, fftin, 0, 1);
for(unsigned i = 0; i < partitionsize * 4; i++)
{
fftout[buffidx][i] = fftin[i];
}

/************************************************** ********************************
Complex multiplication with filter mask (precalculated coefficients subjected to an FFT)
this is taken from wdsp library by Warren Pratt firmin.c
************************************************** ********************************/
k = buffidx;

for(unsigned i = 0; i < partitionsize * 4; i++)
{
accum[i] = 0.0;
}

for(unsigned j = 0; j < nfor; j++)
{
for(unsigned i = 0; i < 2 * partitionsize; i= i + 4 )
{
// doing 8 of these complex multiplies inside one loop saves a HUGE LOT of processor cycles
accum[2 * i + 0] += fftout[k][2 * i + 0] * fmask[j][2 * i + 0] -
fftout[k][2 * i + 1] * fmask[j][2 * i + 1];
accum[2 * i + 1] += fftout[k][2 * i + 0] * fmask[j][2 * i + 1] +
fftout[k][2 * i + 1] * fmask[j][2 * i + 0];
accum[2 * i + 2] += fftout[k][2 * i + 2] * fmask[j][2 * i + 2] -
fftout[k][2 * i + 3] * fmask[j][2 * i + 3];
accum[2 * i + 3] += fftout[k][2 * i + 2] * fmask[j][2 * i + 3] +
fftout[k][2 * i + 3] * fmask[j][2 * i + 2];
accum[2 * i + 4] += fftout[k][2 * i + 4] * fmask[j][2 * i + 4] -
fftout[k][2 * i + 5] * fmask[j][2 * i + 5];
accum[2 * i + 5] += fftout[k][2 * i + 4] * fmask[j][2 * i + 5] +
fftout[k][2 * i + 5] * fmask[j][2 * i + 4];
accum[2 * i + 6] += fftout[k][2 * i + 6] * fmask[j][2 * i + 6] -
fftout[k][2 * i + 7] * fmask[j][2 * i + 7];
accum[2 * i + 7] += fftout[k][2 * i + 6] * fmask[j][2 * i + 7] +
fftout[k][2 * i + 7] * fmask[j][2 * i + 6];
}
k = k - 1;
if(k < 0)
{
k = nfor - 1;
}

} // end nfor loop

buffidx = buffidx + 1;
if(buffidx >= nfor)
{
buffidx = 0;
}
/************************************************** ********************************
Complex inverse FFT
************************************************** ********************************/
arm_cfft_f32(iS, accum, 1, 1);

/************************************************** ********************************
Overlap and save algorithm, which simply means yu take only half of the buffer
and discard the other half (which contains unusable time-aliased audio).
Whether you take the left or the right part is determined by the position
of the zero-padding in the filter-mask-buffer before doing the FFT of the
impulse response coefficients
************************************************** ********************************/
for (unsigned i = 0; i < partitionsize; i++)
{
//float_buffer_L[i] = accum[partitionsize * 2 + i * 2 + 0];
//float_buffer_R[i] = accum[partitionsize * 2 + i * 2 + 1];
float_buffer_L[i] = accum[i * 2 + 0] * audio_gain;
float_buffer_R[i] = accum[i * 2 + 1] * audio_gain;
}

/************************************************** ********************************
Serial print the first output samples in order to check for latency
************************************************** ********************************/
#if defined(LATENCY_TEST)
if(no_more_latency_test == 1)
{
no_more_latency_test = 2;
for(unsigned i = 0; i < partitionsize; i++)
{
if(accum[i * 2 + 0] * audio_gain > 0.1 || accum[i * 2 + 0] * audio_gain < -0.1)
{
Serial.print(i + all_samples_counter - 21); Serial.print(" left: "); Serial.println(accum[i * 2 + 0]);
Serial.print(i + all_samples_counter - 21); Serial.print(" right: "); Serial.println(accum[i * 2 + 1]);
}
}
}
#endif

/************************************************** ********************
CONVERT TO INTEGER AND PLAY AUDIO - Push audio into I2S audio chain
************************************************** ********************/
for (int i = 0; i < N_BLOCKS; i++)
{
sp_L = Q_out_L.getBuffer();
sp_R = Q_out_R.getBuffer();
arm_float_to_q15 (&float_buffer_L[BUFFER_SIZE * i], sp_L, BUFFER_SIZE);
arm_float_to_q15 (&float_buffer_R[BUFFER_SIZE * i], sp_R, BUFFER_SIZE);
Q_out_L.playBuffer(); // play it !
Q_out_R.playBuffer(); // play it !
}

/************************************************** ********************************
PRINT ROUTINE FOR ELAPSED MICROSECONDS
************************************************** ********************************/
#ifdef DEBUG
sum = sum + usec;
idx_t++;
if (idx_t > 400) {
mean = sum / idx_t;
if (mean / 29.00 / N_BLOCKS * SAMPLE_RATE / AUDIO_SAMPLE_RATE_EXACT < 100.0)
{
Serial.print("processor load: ");
Serial.print (mean / 29.00 / N_BLOCKS * SAMPLE_RATE / AUDIO_SAMPLE_RATE_EXACT);
Serial.println("%");
}
else
{
Serial.println("100%");
}
Serial.print (mean);
Serial.print (" microsec for ");
Serial.print (N_BLOCKS);
Serial.print (" stereo blocks ");
Serial.print("FFT-length = "); Serial.print(FFT_length);
Serial.print("; FIR filter length = "); Serial.println(nc);
Serial.print("k = "); Serial.println(k);
Serial.print("buffidx = "); Serial.println(buffidx);
idx_t = 0;
sum = 0;
}
#endif
} // end of audio process loop

/************************************************** ********************************
Add button check etc. here
************************************************** ********************************/

}

void init_partitioned_filter_masks()
{
for(unsigned j = 0; j < nfor;j++)
{
// fill with zeroes
for (unsigned i = 0; i < partitionsize * 4; i++)
{
maskgen[i] = 0.0;
}
// take part of impulse response and fill into maskgen
for (unsigned i = 0; i < partitionsize; i++)
{
// THIS IS FOR REAL IMPULSE RESPONSES OR FIR COEFFICIENTS
// FOR COMPLEX USE THE PART BELOW
// the position of the impulse response coeffs (right or left aligned)
// determines the useable part of the audio in the overlap-and-save (left or right part of the iFFT buffer)
maskgen[i * 2 + partitionsize * 2] = guitar_cabinet_impulse[i + j * partitionsize];
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
* THIS COMMENTED OUT PART IS FOR COMPLEX FILTER COEFFS
*
* // take part of impulse response and fill into maskgen
for (unsigned i = 0; i < partitionsize * 2; i++)
{
// the position of the impulse response coeffs (right or left aligned)
// determines the useable part of the audio in the overlap-and-save (left or right part of the iFFT buffer)
maskgen[i + partitionsize * 2] = guitar_cabinet_impulse[i + j * partitionsize * 2];
}
*/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// perform complex FFT on maskgen
arm_cfft_f32(maskS, maskgen, 0, 1);
// fill into fmask array
for (unsigned i = 0; i < partitionsize * 4; i++)
{
fmask[j][i] = maskgen[i];
}
}
}

void setI2SFreq(int freq) {
// thanks FrankB !
// PLL between 27*24 = 648MHz und 54*24=1296MHz
int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
int n2 = 1 + (24000000 * 27) / (freq * 256 * n1);
double C = ((double)freq * 256 * n1 * n2) / 24000000;
int c0 = C;
int c2 = 10000;
int c1 = C * c2 - (c0 * c2);
set_audioClock(c0, c1, c2, true);
CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
| CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
| CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
//Serial.printf("SetI2SFreq(%d)\n",freq);
}


lp_minphase_2048passthru.h


// lowpass minimum phase filter 2048 taps
// built with Filterbuilder in MATLAB
// F6dB = 19000Hz
// Fs = 44100Hz

const float32_t guitar_cabinet_impulse [2048] =
{0.188376212697746,
0.609744257768420,
0.432502990817439,
-0.260851507457041,
-0.0716236237630232,
0.214323991136647,
-0.161365374641131,
0.0237767814580456,
0.0928163219842420,
-0.135118698255703,
0.103116320519838,
-0.0295475144538609,
-0.0446533915503357,
0.0888262290404382,
-0.0911557750322311,
0.0580364100591744,
-0.00742446990385644,
-0.0399165548550217,
0.0679648332075189,
-0.0697754031374546,
0.0480606089930208,
-0.0126844536056776,
-0.0235427462390931,
0.0492115912631957,
-0.0575291638393862,
0.0476912543045393,
-0.0243353796495332,
-0.00446813256775726,
0.0299137392110943,
-0.0450136699826800,
0.0463381524541060,
-0.0345851763595976,
0.0139767592045872,
0.00921741105173279,
-0.0285424251285965,
0.0390814455730213,
-0.0386119874843127,
0.0279589451090431,
-0.0105352974980706,
-0.00873524800102179,
0.0247861485096508,
-0.0336996884106026,
0.0336093796781321,
-0.0250239730705730,
0.0105412989482191,
0.00592966947488590,
-0.0202118528304379,
0.0288966106796321,
-0.0301253546919541,
0.0239475252971108,
-0.0121990874902116,
-0.00203728046261946,
0.0152353479811855,
-0.0242860919886000,
0.0272108262665234,
-0.0235692958460962,
0.0144860387273242,
-0.00231115168235606,
-0.00998538048902091,
0.0195315549136629,
-0.0242126167350033,
0.0231240726044307,
-0.0167259265912168,
0.00667834387745169,
0.00458806243996135,
-0.0144571785487827,
0.0207282579672892,
-0.0220968857078188,
0.0184137473816448,
-0.0106734168617837,
0.000747690181822247,
0.00906601851378224,
-0.0165730148886592,
0.0201661337829325,
-0.0191616844641809,
0.0139185196381061,
-0.00572271718460774,
-0.00352757333862824,
0.0117603244746568,
-0.0171903577031558,
0.0187012128221475,
-0.0160678963934138,
0.00997786710378808,
-0.00185292405369186,
-0.00648240726192207,
0.0132089639932368,
-0.0169068150647420,
0.0168505248746309,
-0.0131455748731331,
0.00668184799448849,
0.00107994459006863,
-0.00843785705464697,
0.0138202345969508,
-0.0161185858566201,
0.0149120519808907,
-0.0105389797836274,
0.00400494272305699,
0.00324846982046374,
-0.00966106825148907,
0.0138880530425993,
-0.0150795366710582,
0.0130481315355333,
-0.00829237191844751,
0.00187496951293478,
0.00481459402457996,
-0.0103602110852002,
0.0136174334337516,
-0.0139474658309171,
0.0113395629550761,
-0.00639908586492490,
0.000207086090721632,
0.00591611171589314,
-0.0106917262533880,
0.0131482272913238,
-0.0128170709957136,
0.00981948598120196,
-0.00482887263438223,
-0.00108049672811815,
0.00666453698583931,
-0.0107705657114569,
0.0125740258889085,
-0.0117424013581045,
0.00849413355438199,
-0.00354270088492919,
-0.00206013781719028,
0.00714753194769072,
-0.0106798867713560,
0.0119562128097787,
-0.0107517711463428,
0.00735532778085626,
-0.00250044402264655,
-0.00279298808840412,
0.00743276303887444,
-0.0104791044236197,
0.0113340455174083,
-0.00985751239547072,
0.00638787214310574,
-0.00166459799921573,
-0.00332934500175505,
0.00757182511072265,
-0.0102101837505212,
0.0107317425869680,
-0.00906228041684714,
0.00557382609659900,
-0.00100183077000674,
-0.00370987984305920,
0.00760370956078989,
-0.00990239741537146,
0.0101634042045163,
-0.00836308872246020,
0.00489489448176051,
-0.000483384635128046,
-0.00396711569277497,
0.00755767367808610,
-0.00957585416435412,
0.00963640006631904,
-0.00775386170946838,
0.00433368977848434,
-8.49040713301339e-05,
-0.00412686623812680,
0.00745553047938764,
-0.00924408543252659,
0.00915368748410902,
-0.00722702602650273,
0.00387433061402738,
0.000213995016015720,
-0.00420951561195576,
0.00731343756551010,
-0.00891592767304978,
0.00871538869336734,
-0.00677448214170173,
0.00350265810184821,
0.000430244744305489,
-0.00423110387770272,
0.00714327644611003,
-0.00859688574692890,
0.00831985781727594,
-0.00638817894834733,
0.00320623991702628,
0.000577845889882329,
-0.00420422230755352,
0.00695370755938820,
-0.00829011734114946,
0.00796439752431786,
-0.00606043638620441,
0.00297426365918490,
0.000668348067738725,
-0.00413873908641934,
0.00675097315619145,
-0.00799714208210711,
0.00764573592597484,
-0.00578411000098383,
0.00279737911659205,
0.000711272928189012,
-0.00404238114143664,
0.00653950660822658,
-0.00771835140486314,
0.00736033997901889,
-0.00555265826099363,
0.00266752385574190,
0.000714476907993315,
-0.00392119731512019,
0.00632239401439889,
-0.00745337439688967,
0.00710461772490716,
-0.00536015161618996,
0.00257775099398084,
0.000684456742274376,
-0.00377992546588345,
0.00610172373667268,
-0.00720133977424443,
0.00687504544702174,
-0.00520124827663377,
0.00252206899814197,
0.000626603728509190,
-0.00362228263502862,
0.00587885104685003,
-0.00696106295745854,
0.00666824441793309,
-0.00507115248542723,
0.00249529787694065,
0.000545413608088387,
-0.00345119405404649,
0.00565459856053961,
-0.00673117920845564,
0.00648102418965294,
-0.00496556508123985,
0.00249294308260706,
0.000444658832080773,
-0.00326897374262742,
0.00542940811343292,
-0.00651023793088230,
0.00631040396868109,
-0.00488063228965999,
0.00251108667628781,
0.000327529401254785,
-0.00307746691677087,
0.00520345593515642,
-0.00629676912583160,
0.00615362002329018,
-0.00481289629441447,
0.00254629457534224,
0.000196747573196137,
-0.00287816221080032,
0.00497673997234402,
-0.00608932979524788,
0.00600812437302589,
-0.00475924942045787,
0.00259553815911336,
5.46610972381561e-05,
-0.00267228014389187,
0.00474914613364723,
-0.00588653605217872,
0.00587157841475042,
-0.00471689289810231,
0.00265612855887354,
-9.66812386163079e-05,
-0.00246084278009891,
0.00452049849250868,
-0.00568708500629865,
0.00574184383476222,
-0.00468330049903172,
0.00272566193562468,
-0.000255468572375195,
-0.00224472851273542,
0.00429059726429047,
-0.00548976937787382,
0.00561697236353525,
-0.00465618698441342,
0.00280197420639850,
-0.000420078836367184,
-0.00202471503723905,
0.00405924742868738,
-0.00529348694273263,
0.00549519533963690,
-0.00463348108244507,
0.00288310383116996,
-0.000589039371764448,
-0.00180151292262031,
0.00382628018295628,
-0.00509724635730816,
0.00537491371378213,
-0.00461330264516409,
0.00296726146886425,
-0.000760995596880393,
-0.00157579165752979,
0.00359156884866079,
-0.00490017040570248,
0.00525468880114547,
-0.00459394354860407,
0.00305280545526029,
-0.000934686288504388,
-0.00134819962693978,
0.00335504044502553,
-0.00470149741625753,
0.00513323392771536,
-0.00457385187844132,
0.00313822217382763,
-0.00110892430118308,
-0.00111937922612877,
0.00311668390535645,
-0.00450058141655805,
0.00500940705368441,
-0.00455161901549750,
0.00322211058354557,
-0.00128258182067582,
-0.000889977980124677,
0.00287655559895149,
-0.00429689135364692,
0.00488220430706699,
-0.00452596921519763,
0.00330317023368520,
-0.00145457935847506,
-0.000660656408952999,
0.00263478269596198,
-0.00409000961923940,
0.00475075434675688,
-0.00449575128517523,
0.00338019218725197,
-0.00162387784219265,
-0.000432093225022521,
0.00239156479879718,
-0.00387963006725214,
0.00461431348209284,
-0.00445993207597534,
0.00345205238854140,
-0.00178947330163546,
-0.000204988307861821,
0.00214717412175967,
-0.00366555559253704,
0.00447226139824981,
-0.00441759145225292,
0.00351770707776175,
-0.00195039371239266,
1.99361922551272e-05,
0.00190195444374008,
-0.00344769532250594,
0.00432409735900015,
-0.00436791846953438,
0.00357618984849006,
-0.00210569760864032,
0.000241936281792610,
0.00165631903327309,
-0.00322606146501196,
0.00416943678148925,
-0.00431020852391110,
0.00362661007639303,
-0.00225447417267019,
0.000460247860766867,
0.00141074768548761,
-0.00300076581476315,
0.00400800805479338,
-0.00424386126186337,
0.00366815245041371,
-0.00239584454299186,
0.000674089559460540,
0.00116578296214420,
-0.00277201591267578,
0.00383964949693832,
-0.00416837905492251,
0.00370007736420543,
-0.00252896412056793,
0.000882666512215588,
0.000922025718001928,
-0.00254011082857845,
0.00366430631010560,
-0.00408336583058901,
0.00372172194263338,
-0.00265302563225449,
0.00108517488761338,
0.000680130029255795,
-0.00230543658988340,
0.00348202749761621,
-0.00398852615926779,
0.00373250155087642,
-0.00276726283044735,
0.00128080706506403,
0.000440797550493291,
-0.00206846122548356,
0.00329296261339980,
-0.00388366442008415,
0.00373191160767161,
-0.00287095463971551,
0.00146875733946131,
0.000204771378375336,
-0.00182972941477046,
0.00309735829331381,
-0.00376868394552629,
0.00371952955826872,
-0.00296342962768478,
0.00164822803629794,
-2.71705316225228e-05,
-0.00158985674027927,
0.00289555449090756,
-0.00364358601502350,
0.00369501687450128,
-0.00304407065165419,
0.00181843593617329,
-0.000254222319018842,
-0.00134952355758917,
0.00268798039044371,
-0.00350846863714505,
0.00365812097604112,
-0.00311231959176735,
0.00197861892336681,
-0.000475557515812779,
-0.00110946846917659,
0.00247514992320915,
-0.00336352500576895,
0.00360867695926182,
-0.00316768203793703,
0.00212804275527246,
-0.000690336602332254,
-0.000870481434291353,
0.00225765688649181,
-0.00320904158490612,
0.00354660903556421,
-0.00320973184267005,
0.00226600786956117,
-0.000897714771561881,
-0.000633396535397445,
0.00203616963724316,
-0.00304539576539728,
0.00347193163017351,
-0.00323811546271120,
0.00239185616018906,
-0.00109684986025156,
-0.000399084409077812,
0.00181142533488899,
-0.00287305302865428,
0.00338475001818441,
-0.00325255597094193,
0.00250497761252151,
-0.00128691034645716,
-0.000168444404762536,
0.00158422375348886,
-0.00269256360585783,
0.00328526048330481,
-0.00325285669383629,
0.00260481674075210,
-0.00146708337588551,
5.76035068455486e-05,
0.00135542066949194,
-0.00250455860308875,
0.00317374992697006,
-0.00323890439552313,
0.00269087875679839,
-0.00163658274885384,
0.000278127032707282,
0.00112592081866850,
-0.00230974555762463,
0.00305059487422428,
-0.00321067192636367,
0.00276273536717927,
-0.00179465678022168,
0.000492189991197148,
0.000896670487736927,
-0.00210890345773505,
0.00291625986763938,
-0.00316822030891345,
0.00282003016349443,
-0.00194059598346008,
0.000698860845755975,
0.000668649740619196,
-0.00190287719753795,
0.00277129520515672,
-0.00311170018702853,
0.00286248351911511,
-0.00207374049160058,
0.000897221255194017,
0.000442864347256569,
-0.00169257151412131,
0.00261633403004166,
-0.00304135262489355,
0.00288989695342873,
-0.00219348717898428,
0.00108637461492771,
0.000220337431859401,
-0.00147894438569319,
0.00245208872678438,
-0.00295750918246272,
0.00290215687706305,
-0.00229929636871001,
0.00126545447465140,
2.10092212065279e-06,
-0.00126299996583902,
0.00227934666293417,
-0.00286059126901612,
0.00289923768158793,
-0.00239069809028886,
0.00143363278448857,
-0.000210813137481784,
-0.00104578107821535,
0.00209896528535871,
-0.00275110876326812,
0.00288120415001753,
-0.00246729782777897,
0.00159012791201566,
-0.000417381375625844,
-0.000828361310374796,
0.00191186657255369,
-0.00262965787078947,
0.00284821312266044,
-0.00252878169059202,
0.00173421235587139,
-0.000616597899563247,
-0.000611836750970100,
0.00171903086887882,
-0.00249691820574776,
0.00280051437697256,
-0.00257492092783812,
0.00186522004562668,
-0.000807483025708662,
-0.000397317476683252,
0.00152149017814263,
-0.00235364915697378,
0.00273845075147838,
-0.00260557579236088,
0.00198255323591437,
-0.000989091913406546,
-0.000185918779961979,
0.00132032089701677,
-0.00220068547801858,
0.00266245741914861,
-0.00262069863665647,
0.00208568884349580,
-0.00116052296143840,
2.12477125691420e-05,
0.00111663610553657,
-0.00203893220389939,
0.00257306038107856,
-0.00262033627380124,
0.00217418424295477,
-0.00132092596235774,
0.000223083037085222,
0.000911577410537076,
-0.00186935884746691,
0.00247087410892524,
-0.00260463150359041,
0.00224768239306050,
-0.00146950987438703,
0.000418509856559851,
0.000706306459295395,
-0.00169299298628783,
0.00235659840023048,
-0.00257382383134186,
0.00230591629494663,
-0.00160555018929426,
0.000606481369926604,
0.000501996151823632,
-0.00151091323301473,
0.00223101442181552,
-0.00252824932950802,
0.00234871269524472,
-0.00172839579446589,
0.000785990055733125,
0.000299821647115624,
-0.00132424166722916,
0.00209497998657631,
-0.00246833963772019,
0.00237599500686053,
-0.00183747527019835,
0.000956076172632336,
0.000100951239315356,
-0.00113413579804877,
0.00194942409595531,
-0.00239462011463343,
0.00238778541676121,
-0.00193230256939718,
0.00111583595883902,
-9.34628308079320e-05,
-0.000941780090171882,
0.00179534077021721,
-0.00230770711972953,
0.00238420613136310,
-0.00201248199622436,
0.00126442941725240,
-0.000282293522894000,
-0.000748377168274348,
0.00163378224107288,
-0.00220830447101214,
0.00236547976678932,
-0.00207771246259200,
0.00140108765277887,
-0.000464448046779919,
-0.000555138734051347,
0.00146585152943555,
-0.00209719907095118,
0.00233192883775786,
-0.00212779094087045,
0.00152511964744328,
-0.000638876702290915,
-0.000363276310568136,
0.00129269450415261,
-0.00197525575620896,
0.00228397436898895,
-0.00216261510025939,
0.00163591843565438,
-0.000804581448079798,
-0.000173991874683324,
0.00111549145523233,
-0.00184341139323808,
0.00222213361108633,
-0.00218218507291035,
0.00173296659693110,
-0.000960624098187486,
1.15315175784317e-05,
0.000935448293991771,
-0.00170266828600774,
0.00214701689422472,
-0.00218660434608419,
0.00181584102516521,
-0.00110613408575673,
0.000192139046707458,
0.000753787416815930,
-0.00155408693157111,
0.00205932362310761,
-0.00217607974762636,
0.00188421691224188,
-0.00124031570687911,
0.000366713286535143,
0.000571738340750424,
-0.00139877818730210,
0.00195983744258290,
-0.00215092051137686,
0.00193787089220512,
-0.00136245476110017,
0.000534183106178842,
0.000390528200123893,
-0.00123789494139866,
0.00184942063373018,
-0.00211153645209318,
0.00197668333933658,
-0.00147192454976748,
0.000693532256147867,
0.000211372167834863,
-0.00107262332250910,
0.00172900775321373,
-0.00205843521921376,
0.00200063975064977,
-0.00156819113380346,
0.000843807521760560,
3.54639239984359e-05,
-0.000904173572336532,
0.00159959861112284,
-0.00199221869215088,
0.00200983123984183,
-0.00165081783754176,
0.000984126405509245,
-0.000136033775770629,
-0.000733770614645501,
0.00146225059844705,
-0.00191357850022756,
0.00200445407931848,
-0.00171946890338217,
0.00111368421364702,
-0.000301998299382757,
-0.000562644460262456,
0.00131807048754098,
-0.00182329074568377,
0.00198480834051689,
-0.00177391230528757,
0.00123176052334086,
-0.000461356060300356,
-0.000392020491994706,
0.00116820572929885,
-0.00172220993914445,
0.00195129559515489,
-0.00181402164824586,
0.00133772493194401,
-0.000613091042256133,
-0.000223109746575025,
0.00101383535734535,
-0.00161126221855423,
0.00190441571597266,
-0.00183977714818220,
0.00143104203139691,
-0.000756252850393931,
-5.70992923476780e-05,
0.000856160583059822,
-0.00149143791867612,
0.00184476280801277,
-0.00185126568782621,
0.00151127558377822,
-0.000889964226130819,
0.000104857230992199,
0.000696395155684493,
-0.00136378354450091,
0.00177302029166164,
-0.00184867992751158,
0.00157809182859177,
-0.00101342793912873,
0.000261648806339588,
0.000535755575474543,
-0.00122939321903299,
0.00168995517886303,
-0.00183231647479185,
0.00163126188954322,
-0.00112593298208299,
0.000412215868194025,
0.000375451276860843,
-0.00108939970367350,
0.00159641160617380,
-0.00180257314111792,
0.00167066326320188,
-0.00122686002015127,
0.000555558698097878,
0.000216674849023119,
-0.000944965060231650,
0.00149330367651757,
-0.00175994529469449,
0.00169628036843158,
-0.00131568603212921,
0.000690745295002342,
6.05924022977017e-05,
-0.000797271046413678,
0.00138160767594101,
-0.00170502134979096,
0.00170820414829734,
-0.00139198810076994,
0.000816918649712736,
-9.16658345434020e-05,
-0.000647509337066696,
0.00126235373811103,
-0.00163847742951364,
0.00170663072391484,
-0.00145544631073710,
0.000933303345574874,
-0.000239014590137417,
-0.000496871663576527,
0.00113661703832840,
-0.00156107125222132,
0.00169185911523085,
-0.00150584572682584,
0.00103921142687706,
-0.000380422214985805,
-0.000346539968691366,
0.00100550859879606,
-0.00147363530368902,
0.00166428805049061,
-0.00154307743573274,
0.00113404747840351,
-0.000514918853619526,
-0.000197676662878969,
0.000870165791299811,
-0.00137706935143732,
0.00162441188605997,
-0.00156713863076541,
0.00121731285897107,
-0.000641604034402021,
-5.14150914133227e-05,
0.000731742637047601,
-0.00127233238648892,
0.00157281569241642,
-0.00157813175682296,
0.00128860906344747,
-0.000759653626428525,
9.11497168400558e-05,
0.000591399982242034,
-0.00116043405561291,
0.00151016953638601,
-0.00157626270690655,
0.00134764016929881,
-0.000868326074798318,
0.000228969916656933,
0.000450295653712353,
-0.00104242567147836,
0.00143722202054055,
-0.00156183809302863,
0.00139421434381913,
-0.000966967865375598,
0.000361053244472949,
0.000309574689879127,
-0.000919390894196611,
0.00135479314983940,
-0.00153526162352727,
0.00142824440576757,
-0.00105501816138774,
0.000486470867110590,
0.000170359746343780,
-0.000792436177861570,
0.00126376659861295,
-0.00149702963174339,
0.00144974744893774,
-0.00113201259041353,
0.000604364625907471,
3.37417420984307e-05,
-0.000662681048416368,
0.00116508142954225,
-0.00144772577386191,
0.00145884349964673,
-0.00119758610982729,
0.000713953571117969,
-9.92291229597288e-05,
-0.000531248349425964,
0.00105972338295267,
-0.00138801498638724,
0.00145575326787426,
-0.00125147496707373,
0.000814539764067264,
-0.000227551931742202,
-0.000399254511062966,
0.000948715792411918,
-0.00131863673463246,
0.00144079498331614,
-0.00129351770880298,
0.000905513270008403,
-0.000350283090281084,
-0.000267799960007765,
0.000833110229864334,
-0.00124039763545992,
0.00141438036537664,
-0.00132365524389978,
0.000986356297289276,
-0.000466543770502085,
-0.000137959763941642,
0.000713976981069488,
-0.00115416353670673,
0.00137700978102876,
-0.00134192998075128,
0.00105664646948041,
-0.000575526707666961,
-1.07745767641816e-05,
0.000592395418192709,
-0.00106085110854094,
0.00132926661559475,
-0.00134848401888293,
0.00111605917290967,
-0.000676502256036406,
0.000112757997092214,
0.000469444396843653,
-0.000961419060732242,
0.00127181094558312,
-0.00134355645393896,
0.00116436898851638,
-0.000768823683027487,
0.000231691566392697,
0.000346192741514619,
-0.000856859048049688,
0.00120537255397545,
-0.00132747979680338,
0.00120145017807606,
-0.000851931621114070,
0.000345138540873378,
0.000223689940953746,
-0.000748186383347534,
0.00113074338864712,
-0.00130067558104340,
0.00122727625274777,
-0.000925357678036410,
0.000452277102570230,
0.000102957112056718,
-0.000636430619138664,
0.00104876951299587,
-0.00126364917510980,
0.00124191860881226,
-0.000988727139241529,
0.000552357471337524,
-1.50216532421029e-05,
-0.000522626117648580,
0.000960342655832593,
-0.00121698388270298,
0.00124554426937522,
-0.00104176077010630,
0.000644707421131218,
-0.000129307492238469,
-0.000407802691700999,
0.000866391436311578,
-0.00116133438282170,
0.00123841275855064,
-0.00108427569589365,
0.000728737000184590,
-0.000239014443364420,
-0.000292976409123360,
0.000767872359765572,
-0.00109741959071642,
0.00122087215032766,
-0.00111618537139706,
0.000803942418783560,
-0.000343316526984709,
-0.000179140641246118,
0.000665760660403769,
-0.00102601499625366,
0.00119335432359574,
-0.00113749862747795,
0.000869909057718182,
-0.000441454147073551,
-6.72574651680260e-05,
0.000561041110449280,
-0.000947944590413191,
0.00115636950711101,
-0.00114831784433366,
0.000926313604487218,
-0.000532739787741292,
4.17505307360025e-05,
0.000454698854899098,
-0.000864072433434103,
0.00111050014317413,
-0.00114883624699316,
0.000972925274682861,
-0.000616562925390159,
0.000147007926987542,
0.000347710395454734,
-0.000775293982086686,
0.00105639417158967,
-0.00113933439015138,
0.00100960614618346,
-0.000692394142759168,
0.000247693596996108,
0.000241034786729180,
-0.000682527243769892,
0.000994757785162431,
-0.00112017585746418,
0.00103631059512812,
-0.000759788399151499,
0.000343047195689907,
0.000135605141243735,
-0.000586703857975554,
0.000926347744220793,
-0.00109180223487667,
0.00105308385623016,
-0.000818387437101733,
0.000432374957296644,
3.23205238822443e-05,
-0.000488760194579383,
0.000851963335020951,
-0.00105472742115395,
0.00106005973698705,
-0.000867921319106833,
0.000515054760796427,
-6.79616933056587e-05,
-0.000389628552301354,
0.000772438048305727,
-0.00100953133001733,
0.00105745750865632,
-0.000908209075058714,
0.000590540405541599,
-0.000164432931574560,
-0.000290228560981843,
0.000688631085813660,
-0.000956853079102576,
0.00104557803962625,
-0.000939158493976822,
0.000658365090692593,
-0.000256339919972748,
-0.000191458847027888,
0.000601418756758660,
-0.000897383715876238,
0.00102479919728049,
-0.000960765048385673,
0.000718144055929873,
-0.000342990551612894,
-9.41890567922852e-05,
0.000511685865530700,
-0.000831858569065285,
0.000995570580663502,
-0.000973109979124018,
0.000769576361960528,
-0.000423759020987623,
7.47674009255649e-07,
0.000420317195142116,
-0.000761049330912880,
0.000958407671343980,
-0.000976357597983724,
0.000812445840836740,
-0.000498090236383143,
9.25617687134534e-05,
0.000328189135570331,
-0.000685755918440407,
0.000913885437301910,
-0.000970751814753698,
0.000846621182401278,
-0.000565503439863131,
0.000180513680611250,
0.000236161570699114,
-0.000606798230834139,
0.000862631490621889,
-0.000956611963646774,
0.000872055197737216,
-0.000625595037150047,
0.000263919756968448,
0.000145070076292613,
-0.000525007858523441,
0.000805318846595854,
-0.000934327950852837,
0.000888783246735074,
-0.000678040584201582,
0.000342157403409571,
5.57185475119292e-05,
-0.000441219881152038,
0.000742658419762617,
-0.000904354842050037,
0.000896920918904361,
-0.000722595988905713,
0.000414669575132826,
-3.11277436209477e-05,
-0.000356264765685995,
0.000675391266025821,
-0.000867206884637578,
0.000896660937950153,
-0.000759097858508003,
0.000480968493376045,
-0.000114748531178838,
-0.000270960510422622,
0.000604280716454429,
-0.000823451091929042,
0.000888269382632123,
-0.000787463053715871,
0.000540638604593054,
-0.000194474361357694,
-0.000186105077157140,
0.000530104457816367,
-0.000773700442352323,
0.000872081263777798,
-0.000807687456914398,
0.000593338759534745,
-0.000269691769599871,
-0.000102469185255881,
0.000453646638499354,
-0.000718606763235004,
0.000848495502057089,
-0.000819843968120180,
0.000638803590524567,
-0.000339847771195942,
-2.07895494039735e-05,
0.000375690097627492,
-0.000658853394878594,
0.000817969387934502,
-0.000824079782220827,
0.000676844100815445,
-0.000404453644711684,
5.82373843174885e-05,
0.000297008788903831,
-0.000595147712926964,
0.000781012587226665,
-0.000820612987056977,
0.000707347478436932,
-0.000463087985492271,
0.000133961156577536,
0.000218360467368454,
-0.000528213580250500,
0.000738180760681151,
-0.000809728527317579,
0.000730276146880271,
-0.000515399008691873,
0.000205782413605523,
0.000140479712834131,
-0.000458783811412582,
0.000690068865964042,
-0.000791773585159772,
0.000745666070727370,
-0.000561106085365192,
0.000273157375616782,
6.40713669361738e-05,
-0.000387592740694911,
0.000637304238923744,
-0.000767152454330754,
0.000753624369396000,
-0.000600000528349283,
0.000335601639385704,
-1.01955706686618e-05,
-0.000315368955731914,
0.000580539515951984,
-0.000736320964257945,
0.000754326271113311,
-0.000631945632916913,
0.000392693290121792,
-8.16935387030475e-05,
-0.000242828260408976,
0.000520445463551803,
-0.000699780502242398,
0.000748011430628734,
-0.000656875961432833,
0.000444075271057753,
-0.000149841416596581,
-0.000170666979939790,
0.000457703840302133,
-0.000658071762165737,
0.000734979720887916,
-0.000674795956454404,
0.000489457067889812,
-0.000214108961003483,
-9.95556012144273e-05,
0.000393000296749796,
-0.000611768217934431,
0.000715586487014560,
-0.000685777843240696,
0.000528615638155606,
-0.000274020575488659,
-3.01328725683906e-05,
0.000327017447838386,
-0.000561469457244702,
0.000690237376642782,
-0.000689958911031570,
0.000561395638877267,
-0.000329158433436391,
3.69996255855600e-05,
0.000260428149778270,
-0.000507794415362536,
0.000659382782048884,
-0.000687538188378873,
0.000587708940515261,
-0.000379164909017987,
0.000101282365426875,
0.000193889077520598,
-0.000451374610996274,
0.000623511991883925,
-0.000678772591841515,
0.000607533481476982,
-0.000423744340177517,
0.000162202208766184,
0.000128034625643256,
-0.000392847420931919,
0.000583147085087077,
-0.000663972566627468,
0.000620911454823322,
-0.000462664087741533,
0.000219296128792530,
6.34712236514219e-05,
-0.000332849491385928,
0.000538836664426311,
-0.000643497300969825,
0.000627946883712083,
-0.000495754910131432,
0.000272154304958382,
7.72106527668276e-07,
-0.000272010354057353,
0.000491149502992288,
-0.000617749582557563,
0.000628802636357016,
-0.000522910683481695,
0.000320422588247682,
-5.95274317629924e-05,
-0.000210946285219040,
0.000440668152280284,
-0.000587170337721956,
0.000623696903360808,
-0.000544087459931726,
0.000363804305826698,
-0.000116934239517115,
-0.000150254493399819,
0.000387982603373066,
-0.000552232942079756,
0.000612899209617793,
-0.000559301912489865,
0.000402061415877053,
-0.000171000951348116,
-9.05076748989731e-05,
0.000333684054065826,
-0.000513437358573535,
0.000596726005184733,
-0.000568629190172413,
0.000435015015075047,
-0.000221329039918761,
-3.22489898592615e-05,
0.000278358854007759,
-0.000471304174622651,
0.000575535899607900,
-0.000572200224853782,
0.000462545207407146,
-0.000267571261661645,
2.40124939087561e-05,
0.000222582689463424,
-0.000426368611555910,
0.000549724605391889,
-0.000570198543345074,
0.000484590367570885,
-0.000309433497982653,
7.78058703324559e-05,
0.000166915047971033,
-0.000379174552410618,
0.000519719635757651,
-0.000562856610671117,
0.000501145799394512,
-0.000346675964826455,
0.000128701919629218,
0.000111894042739982,
-0.000330268682009116,
0.000485974848713848,
-0.000550451789147975,
0.000512261851445500,
-0.000379113827209615,
0.000176316097044542,
5.80316104154263e-05,
-0.000280194767246492,
0.000448964870971188,
-0.000533301935027270,
0.000518041495684628,
-0.000406617196508756,
0.000220310939159943,
5.80915527426502e-06,
-0.000229488165889445,
0.000409179494591505,
-0.000511760720627247,
0.000518637437591681,
-0.000429110556339805,
0.000260397900582641,
-4.43263497407220e-05,
-0.000178670597273732,
0.000367118089566103,
-0.000486212725664940,
0.000514248789883496,
-0.000446571627203143,
0.000296338609758977,
-9.19657663315663e-05,
-0.000128245231457169,
0.000323284100904909,
-0.000457068361981575,
0.000505117364194213,
-0.000459029704236157,
0.000327945551907999,
-0.000136740681408659,
-7.86921329207721e-05,
0.000278179678557902,
-0.000424758686433972,
0.000491523622246400,
-0.000466563491089488,
0.000355082175246678,
-0.000178325755239739,
-3.04641198829631e-05,
0.000232300516742108,
-0.000389730181368257,
0.000473782367435070,
-0.000469298493835844,
0.000377662464049699,
-0.000216440543217957,
1.60169622465051e-05,
0.000186130922527491,
-0.000352439534402233,
0.000452238198545104,
-0.000467403988435141,
0.000395649970721416,
-0.000250850760019768,
6.03634905321185e-05,
0.000140139190548981,
-0.000313348501248095,
0.000427260816724576,
-0.000461089635880700,
0.000409056361095609,
-0.000281369016884544,
0.000102224847936856,
9.47732982388040e-05,
-0.000272918880767624,
0.000399240210603392,
-0.000450601767088031,
0.000417939478674959,
-0.000307855011936882,
0.000141289692345961,
5.04569875750264e-05,
-0.000231607683806753,
0.000368581811670834,
-0.000436219421068369,
0.000422400995612942,
-0.000330215222211920,
0.000177287738433970,
7.58623513911096e-06,
-0.000189862512413271,
0.000335701642468964,
-0.000418250160775089,
0.000422583664915979,
-0.000348402092790901,
0.000209991022350125,
-3.34738475853319e-05,
-0.000148117211647312,
0.000301021528160587,
-0.000397025730213148,
0.000418668225237926,
-0.000362412753188837,
0.000239214658568675,
-7.23916561305031e-05,
-0.000106787837021786,
0.000264964429404187,
-0.000372897621646563,
0.000410870019361637,
-0.000372287310013837,
0.000264817114244931,
-0.000108871292907130,
-6.62689480413706e-05,
0.000227949918110932,
-0.000346232570978058,
0.000399435341994498,
-0.000378106715422049,
0.000286699981523114,
-0.000142654272732914,
-2.69302939374010e-05,
0.000190389879835580,
-0.000317408077864799,
0.000384637607612263,
-0.000379990287628163,
0.000304807306201063,
-0.000173520773834363,
1.08861177975202e-05,
0.000152684448844907,
-0.000286807965735765,
0.000366773356769903,
-0.000378092901125374,
0.000319124471048734,
-0.000201290414447190,
4.68685378107449e-05,
0.000115218228395930,
-0.000254818041692141,
0.000346158161569649,
-0.000372601890885614,
0.000329676668116906,
-0.000225822563992293,
8.07375583155444e-05,
7.83568287152220e-05,
-0.000221821904253685,
0.000323122480761650,
-0.000363733721480666,
0.000336526990548596,
-0.000247016203515952,
0.000112247757234614,
4.24437540437656e-05,
-0.000188196945189192,
0.000298007521030389,
-0.000351730473773133,
0.000339774191812132,
-0.000264809365574582,
0.000141188912377077,
7.79764595656689e-06,
-0.000154310567659399,
0.000271161134387602,
-0.000336856179207288,
0.000339550132427436,
-0.000279178156638569,
0.000167386772657694,
-2.52900827146534e-05,
-0.000120516672531367,
0.000242933810446189,
-0.000319393064810153,
0.000336016967644785,
-0.000290135403063641,
0.000190703405227062,
-5.65572201793840e-05,
-8.71524305321173e-05,
0.000213674800597969,
-0.000299637744974060,
0.000329364111972449,
-0.000297728945661717,
0.000211037122960751,
-8.57723273161247e-05,
-5.45353733109249e-05,
0.000183728410933103,
-0.000277897408945772,
0.000319805024856528,
-0.000302039611319325,
0.000228322015780829,
-0.000112735897263987,
-2.29608209385437e-05,
0.000153430506030549,
-0.000254486049228494,
0.000307573862686030,
-0.000303178905912279,
0.000242527100213937,
-0.000137281117111114,
7.30033523579021e-06,
0.000123105249949880,
-0.000229720770505216,
0.000292922038724463,
-0.000301286459640106,
0.000253655117779784,
-0.000159274229215575,
3.60034845920927e-05,
9.30621167690355e-05,
-0.000203918222030338,
0.000276114740327413,
-0.000296527270429427,
0.000261741011042686,
-0.000178614516206882,
6.29317835053456e-05,
6.35931853423578e-05,
-0.000177391176527107,
0.000257427429370752,
-0.000289088772606025,
0.000266850094912291,
-0.000195233905942410,
8.78972584955165e-05,
3.49707508874002e-05,
-0.000150445309823505,
0.000237142384856679,
-0.000279177783598086,
0.000269075971428415,
-0.000209096229889560,
0.000110741537327149,
7.44526608530055e-06,
-0.000123376200135580,
0.000215545326216810,
-0.000267017374832038,
0.000268538224122432,
-0.000220196166615947,
0.000131336227696372,
-1.87563955743337e-05,
-9.64665624043059e-05,
0.000192922131808071,
-0.000252843685497536,
0.000265379913813642,
-0.000228557874872624,
0.000149582935323636,
-4.34323301785881e-05,
-6.99837507791663e-05,
0.000169555701416514,
-0.000236902727086258,
0.000259764914425040,
-0.000234233348698301,
0.000165412932789527,
-6.64066381031749e-05,
-4.41775582148218e-05,
0.000145723008065119,
-0.000219447235191615,
0.000251875150700741,
-0.000237300550497779,
0.000178786528283539,
-8.75301399492884e-05,
-1.92782936186099e-05,
0.000121692324639181,
-0.000200733565328068,
0.000241907733045669,
-0.000237861309107664,
0.000189692110701649,
-0.000106680732130426,
4.50481013032483e-06,
9.77207024091708e-05,
-0.000181018711655215,
0.000230072074234532,
-0.000236039069272536,
0.000198144940810403,
-0.000123763442717051,
2.69848983345917e-05,
7.40516688244340e-05,
-0.000160557434864838,
0.000216586977792589,
-0.000231976475561013,
0.000204185674783137,
-0.000138710154973346,
4.79984606869687e-05,
5.09132049997089e-05,
-0.000139599566916384,
0.000201677774145669,
-0.000225832869939003,
0.000207878683238877,
-0.000151479056895540,
6.74060053942129e-05,
2.85159790346672e-05,
-0.000118387481783846,
0.000185573498558612,
-0.000217781700629465,
0.000209310165667662,
-0.000162053801388181,
8.50924152924897e-05,
7.05186956453470e-06,
-9.71537792265648e-05,
0.000168504168072874,
-0.000208007895912176,
0.000208586105310435,
-0.000170442417095546,
0.000100967004728756,
-1.33072212552245e-05,
-7.61191957458708e-05,
0.000150698183918165,
-0.000196705240633591,
0.000205830105356773,
-0.000176676000024605,
0.000114963305824497,
-3.24102791839204e-05,
-5.54907418569306e-05,
0.000132379865371671,
-0.000184073766363031,
0.000201181115979662,
-0.000180807193536547,
0.000127038575228745,
-5.01277953367820e-05,
-3.54600972052203e-05,
0.000113767161034625,
-0.000170317206171403,
0.000194791104551260,
-0.000182908504338874,
0.000137173062053058,
-6.63521154583115e-05,
-1.62022492551869e-05,
9.50695339833217e-05,
-0.000155640518881772,
0.000186822677670859,
-0.000183070457050786,
0.000145369031533720,
-8.09975051500945e-05,
2.12559048589932e-06,
7.64860654053013e-05,
-0.000140247538908800,
0.000177446714536424,
-0.000181399650296004,
0.000151649599016530,
-9.39999736435878e-05,
1.93848288223896e-05,
5.82037575782806e-05,
-0.000124338739968729,
0.000166840006490354,
-0.000178016706090723,
0.000156057365543311,
-0.000105316838685233,
3.54560566637589e-05,
4.03960768917472e-05,
-0.000108109166276448,
0.000155182962654831,
-0.000173054175672365,
0.000158652908641844,
-0.000114926079134319,
5.02393771313967e-05,
2.32217195289552e-05,
-9.17465217580026e-05,
0.000142657380597930,
-0.000166654405394924,
0.000159513134913013,
-0.000122825474135530,
6.36544847717181e-05,
6.82361260221398e-06,
-7.54294443736157e-05,
0.000129444315385494,
-0.000158967394375891,
0.000158729522599144,
-0.000129031549353854,
7.56405031096346e-05,
-8.67183733331277e-06,
-5.93259871475699e-05,
0.000115722081146003,
-0.000150148690895136,
0.000156406301163626,
-0.000133578377322378,
8.61556239564951e-05,
-2.31552845431723e-05,
-4.35922803312279e-05,
0.000101664365247479,
-0.000140357307314415,
0.000152658551633607,
-0.000136516206059851,
9.51765124188815e-05,
-3.65347254584677e-05,
-2.83714352266867e-05,
8.74385286051978e-05,
-0.000129753738476453,
0.000147610311414145,
-0.000137910006150880,
0.000102697559609732,
-4.87355955071818e-05,
-1.37926245695630e-05,
7.32040363770285e-05,
-0.000118498031457477,
0.000141392641188929,
-0.000137837883078596,
0.000108729931404002,
-5.97006177255799e-05,
2.95846827881819e-08,
5.91111032202778e-05,
-0.000106748004651542,
0.000134141749064100,
-0.000136389460224527,
0.000113300506204820,
-6.93894923277792e-05,
1.29957272178115e-05,
4.52994876363378e-05,
-9.46575540414564e-05,
0.000125997125227105,
-0.000133664181277609,
0.000116450656817408,
-7.77783755578806e-05,
2.50217037892235e-05,
3.18974960068090e-05,
-8.23751187460442e-05,
0.000117099753299065,
-0.000129769601548325,
0.000118234933763554,
-8.48591948961380e-05,
3.60388494941422e-05,
1.90211827901564e-05,
-7.00423007388360e-05,
0.000107590413116842,
-0.000124819687744192,
0.000118719677768838,
-9.06388284136985e-05,
4.59938262807270e-05,
6.77372748869314e-06,
-5.77926338854438e-05,
9.76080699072671e-05,
-0.000118933129140552,
0.000117981563868806,
-9.51381479763870e-05,
5.48483402868338e-05,
-4.75500178988882e-06,
-4.57505109770968e-05,
8.72883675851576e-05,
-0.000112231675123534,
0.000116106089321701,
-9.83909332885501e-05,
6.25786747835931e-05,
-1.54886815154860e-05,
-3.40303032480609e-05,
7.67622694617877e-05,
-0.000104838553179924,
0.000113186063714312,
-0.000100442712686734,
6.91750948342575e-05,
-2.53646062913600e-05,
-2.27356340152867e-05,
6.61548177336021e-05,
-9.68769464433398e-05,
0.000109320085550577,
-0.000101349518894484,
7.46411071782343e-05,
-3.43335844271261e-05,
-1.19588346592544e-05,
5.55840476099060e-05,
-8.84685705272249e-05,
0.000104611048898905,
-0.000101176601847389,
7.89926162502628e-05,
-4.23596903087532e-05,
-1.78055484407792e-06,
4.51600345946115e-05,
-7.97323373243405e-05,
9.91646702789666e-05,
-9.99970894123996e-05,
8.22569630858602e-05,
-4.94198535533731e-05,
7.73044783014208e-06,
3.49841095865886e-05,
-7.07831454761339e-05,
9.30880819402389e-05,
-9.78906453573534e-05,
8.44718937672007e-05,
-5.55033255994904e-05,
1.65173663256915e-05,
2.51482237433532e-05,
-6.17307903966461e-05,
8.64884924197881e-05,
-9.49421291897842e-05,
8.56844670951370e-05,
-6.06110354372092e-05,
2.45352627654101e-05,
1.57344547334473e-05,
-5.26789906302710e-05,
7.94719141941528e-05,
-9.12402599175422e-05,
8.59498994336594e-05,
-6.47548241883523e-05,
3.17508302046613e-05,
6.81468147959116e-06,
-4.37245646773611e-05,
7.21420003100827e-05,
-8.68763318239560e-05,
8.53303968378907e-05,
-6.79566093148694e-05,
3.81420395083240e-05,
-1.54960784393911e-06,
-3.49567335027389e-05,
6.45989734913665e-05,
-8.19429696885905e-05,
8.38939685342046e-05,
-7.02474737089914e-05,
4.36976700550079e-05,
-9.30737030014720e-06,
-2.64565565390446e-05,
5.69386604445289e-05,
-7.65329416302733e-05,
8.17132365458137e-05,
-7.16666904680223e-05,
4.84167260159093e-05,
-1.64179195193185e-05,
-1.82965146307303e-05,
4.92516511006942e-05,
-7.07380548955613e-05,
7.88642753829743e-05,
-7.22607213605023e-05,
5.23077773574168e-05,
-2.28507279641721e-05,
-1.05402127869497e-05,
4.16225651072354e-05,
-6.46481232575567e-05,
7.54254718691516e-05,
-7.20821792034151e-05,
5.53882142108408e-05,
-2.85851072733613e-05,
-3.24221991439569e-06,
3.41294451881241e-05,
-5.83500305492881e-05,
7.14764344047816e-05,
-7.11887845402872e-05,
5.76834426668659e-05,
-3.36097889932510e-05,
3.55197069788484e-06,
2.68432705002762e-05,
-5.19268901082108e-05,
6.70969555046596e-05,
-6.96423242940776e-05,
5.92260297735991e-05,
-3.79224107325946e-05,
9.80585939986252e-06,
1.98275973779508e-05,
-4.54573155161122e-05,
6.23660525079285e-05,
-6.75076418589765e-05,
6.00548319901233e-05,
-4.15289437831710e-05,
1.54917710787129e-05,
1.31382944524579e-05,
-3.90147728293356e-05,
5.73610566606221e-05,
-6.48516314344463e-05,
6.02140778167643e-05,
-4.44430304989604e-05,
2.05905650447362e-05,
6.82341282385755e-06,
-3.26670589779793e-05,
5.21568005987864e-05,
-6.17422867908078e-05,
5.97524547790278e-05,
-4.66852764763862e-05,
2.50912610969713e-05,
9.23160502731698e-07,
-2.64758863732271e-05,
4.68248935945603e-05,
-5.82478042189226e-05,
5.87222070084887e-05,
-4.82825093384025e-05,
2.89905936458929e-05,
-4.53002646962241e-06,
-2.04965696755587e-05,
4.14330852462044e-05,
-5.44357437174647e-05,
5.71782504808843e-05,
-4.92670122653822e-05,
3.22925049826769e-05,
-9.51132865537019e-06,
-1.47778028906065e-05,
3.60447080699851e-05,
-5.03722408607885e-05,
5.51773003208649e-05,
-4.96757259197749e-05,
3.50075662195750e-05,
-1.40032863881818e-05,
-9.36155133474686e-06,
3.07182279102158e-05,
-4.61213025226825e-05,
5.27770432545914e-05,
-4.95494513761928e-05,
3.71523564677863e-05,
-1.79954670322576e-05,
-4.28303862522960e-06,
2.55068928494401e-05,
-4.17441865985924e-05,
5.00353667550297e-05,
-4.89320728625287e-05,
3.87488235476092e-05,
-2.14840808670344e-05,
4.29193943820314e-07,
2.04584580969955e-05,
-3.72988447269434e-05,
4.70096230007786e-05,
-4.78697791998594e-05,
3.98236057035167e-05,
-2.44715266846507e-05,
4.75313751237594e-06,
1.56150074875582e-05,
-3.28394518581882e-05,
4.37559560586719e-05,
-4.64103133361077e-05,
4.04073408753056e-05,
-2.69658852855969e-05,
8.67308334245886e-06,
1.10128731101717e-05,
-2.84160325289578e-05,
4.03287079018627e-05,
-4.46022717899888e-05,
4.05339917886075e-05,
-2.89803964272556e-05,
1.21793484050168e-05,
6.68261101925047e-06,
-2.40741434418611e-05,
3.67798674704759e-05,
-4.24944218360976e-05,
4.02401563530905e-05,
-3.05328879751869e-05,
1.52679255814066e-05,
2.64906892578061e-06,
-1.98546500069739e-05,
3.31586003724534e-05,
-4.01350730764233e-05,
3.95643976090557e-05,
-3.16451866320707e-05,
1.79400817749700e-05,
-1.06847019347601e-06,
-1.57935892057936e-05,
2.95108600554460e-05,
-3.75715125639281e-05,
3.85466101129540e-05,
-3.23425344797131e-05,
2.02019327946803e-05,
-4.45609890257817e-06,
-1.19220894766209e-05,
2.58790554584687e-05,
-3.48494828768016e-05,
3.72274052793807e-05,
-3.26529946747502e-05,
2.20639775630144e-05,
-7.50503210654737e-06,
-8.26636711758603e-06,
2.23017934457658e-05,
-3.20127206009306e-05,
3.56475328440866e-05,
-3.26068631902281e-05,
2.35406085444957e-05,
-1.02113047743536e-05,
-4.84778781083232e-06,
1.88136910518458e-05,
-2.91025561506954e-05,
3.38473435685448e-05,
-3.22360940887413e-05,
2.46496043386581e-05,
-1.25754232045394e-05,
-1.68299577898747e-06,
1.54452654393360e-05,
-2.61575893232091e-05,
3.18663145824847e-05,
-3.15737659182695e-05,
2.54116387705280e-05,
-1.46020097336118e-05,
1.21593376076612e-06,
1.22228540450536e-05,
-2.32133905948690e-05,
2.97425852017874e-05,
-3.06535352341131e-05,
2.58497493827160e-05,
-1.62993795776686e-05,
3.84125227748637e-06,
9.16863744021602e-06,
-2.03023065692612e-05,
2.75125868145283e-05,
-2.95091642466831e-05,
2.59888539674946e-05,
-1.76791380620272e-05,
6.18929154249461e-06,
6.30068374802497e-06,
-1.74532946041181e-05,
2.52106988923676e-05,
-2.81740622439520e-05,
2.58552619692626e-05,
-1.87557516364141e-05,
8.26017199065317e-06,
3.63305085334796e-06,
-1.46918190969495e-05,
2.28689607360518e-05,
-2.66808678004884e-05,
2.54762054152313e-05,
-1.95461139975496e-05,
1.00574832730159e-05,
1.17593443289160e-06,
-1.20398028974600e-05,
2.05168375221023e-05,
-2.50610745666737e-05,
2.48793945371205e-05,
-2.00691137200834e-05,
1.15879423934172e-05,
-1.06414156847778e-06,
-9.51563485898980e-06,
1.81810475931188e-05,
-2.33447144069641e-05,
2.40926193930910e-05,
-2.03452312763585e-05,
1.28610633619747e-05,
-3.08413000396668e-06,
-7.13419175493583e-06,
1.58854062780980e-05,
-2.15600508674769e-05,
2.31433477794885e-05,
-2.03961132127523e-05,
1.38887825085080e-05,
-4.88420149585254e-06,
-4.90693973616174e-06,
1.36507573899247e-05,
-1.97333598521286e-05,
2.20584019716092e-05,
-2.02442100782731e-05,
1.46851289725802e-05,
-6.46751145286717e-06,
-2.84202588361863e-06,
1.14949056725800e-05,
-1.78887153437735e-05,
2.08636372278522e-05,
-1.99124066292791e-05,
1.52658735505728e-05,
-7.83992995227965e-06,
-9.44420822187621e-07,
9.43260982898625e-06,
-1.60478387704375e-05,
1.95836797695954e-05,
-1.94237007097493e-05,
1.56482103841807e-05,
-9.00978623649399e-06,
7.83935171525027e-07,
7.47559434188931e-06,
-1.42299775536068e-05,
1.82416981707318e-05,
-1.88009128682218e-05,
1.58504607159106e-05,
-9.98762184626575e-06,
2.34397923979176e-06,
5.63258285698431e-06,
-1.24518164027521e-05,
1.68592128359527e-05,
-1.80664326865193e-05,
1.58918048894794e-05,
-1.07859578789703e-05,
3.73936902154455e-06,
3.90935492255855e-06,
-1.07274297870248e-05,
1.54559601577405e-05,
-1.72420263899694e-05,
1.57920740103668e-05,
-1.14191116148137e-05,
4.97635752757253e-06,
2.30879343896842e-06,
-9.06824899987317e-06,
1.40497925507715e-05,
-1.63486953125997e-05,
1.55715983257221e-05,
-1.19030650926603e-05,
6.06370470402950e-06,
8.30918840263758e-07,
-7.48304360703323e-06,
1.26566195715797e-05,
-1.54065957222224e-05,
1.52511255347221e-05,
-1.22553973042141e-05,
7.01263066199327e-06,
-5.27082777352689e-07,
-5.97794100561358e-06,
1.12904325578539e-05,
-1.44350800553639e-05,
1.48518830033058e-05,
-1.24953609862035e-05,
7.83688974868656e-06,
-1.77090615013304e-06,
-4.55643346870285e-06,
9.96338395092646e-06,
-1.34528523657699e-05,
1.43957928743317e-05,
-1.26441201123289e-05,
8.55297713240174e-06,
-2.90924368516500e-06,
-3.21940168225997e-06,
8.68597881265877e-06,
-1.24783204737776e-05,
1.39059369573861e-05,
-1.27252423867432e-05,
9.18053946157448e-06,
-3.95400162400142e-06,
-1.96518267115819e-06,
7.46746833689904e-06,
-1.15302896023228e-05,
1.34074519140775e-05,
-1.27656335795821e-05,
9.74314819775609e-06,
-4.92071364573165e-06,
-7.89667830093251e-07,
6.31652156619124e-06,
-1.06291506895824e-05,
1.29290502220271e-05,
-1.27971007825138e-05,
1.02695560607792e-05,
-5.82915212092074e-06,
3.13414308251919e-07,
5.24248964105051e-06,
-9.79900452764784e-06,
1.25056655617670e-05,
-1.28590029701837e-05,
1.07957464296650e-05,
-6.70420248231589e-06,
1.35179297681228e-06,
4.25780302111296e-06,
-9.07149451284387e-06,
1.21830882765184e-05,
-1.30027582486976e-05,
1.13682439504335e-05,
-7.57699294323568e-06,
2.33294728637344e-06,
3.38263268891172e-06,
-8.49286708977784e-06,
1.20262029291099e-05,
-1.32995252750538e-05,
1.20493020612022e-05,
-8.48586098462860e-06,
3.25978434029312e-06,
2.65452191613282e-06,
-8.13766917263592e-06,
1.21342735686686e-05,
-1.38536956203430e-05,
1.29249345064615e-05,
-9.47578755905232e-06,
4.11974512253393e-06,
2.14919930540155e-06,
-8.13654050316106e-06,
1.26703746372138e-05,
-1.48269616572805e-05,
1.41162808512093e-05,
-1.05911145259137e-05,
4.85614683002586e-06,
2.02861897580210e-06,
-8.73619719903648e-06,
1.39208631902521e-05,
-1.64816070082674e-05,
1.57909355674412e-05,
-1.18430416023770e-05,
5.28808185753392e-06,
2.66094124771436e-06,
-1.04386263683022e-05,
1.64215975327003e-05,
-1.92549125409221e-05,
1.81482847160588e-05,
-1.30808136873314e-05,
4.86560151127938e-06,
4.95120163609831e-06,
-1.43520955794852e-05,
2.12334518816518e-05,
-2.38484307014892e-05,
2.12227652221487e-05,
-1.34538992145464e-05,
1.81620815985303e-06,
1.13759543984696e-05,
-2.31531129861752e-05,
3.04792287756776e-05,
-3.09507101925077e-05,
2.34736968392414e-05,
-8.76736432618021e-06,
-1.04535730643650e-05,
2.97298720115906e-05,
-4.35934020642341e-05,
4.67552223855731e-05,
-3.56182455059900e-05,
9.88930618457279e-06,
2.60263717555172e-05,
-6.22569633814163e-05,
8.38585089834099e-05,
-7.31798787850616e-05,
1.56918903602002e-05,
8.74751988628250e-05,
-0.000192683277298794,
0.000154400644547547,
0.000410523562181980,
0.000128991905841930};

Frank B
05-15-2020, 02:11 PM
@DD4wh: What is this for? :-)

You have used PROGMEM for several simple variables and even consts - I wouldn't do that.
This moves 4 Bytes from the fast RAM1 to the slower RAM2. They may be cached.. but ... if you use the EXTMEM (uses the same small 32kB cache) extensively the chance is not very high.
Overall it might be not a big difference in the code above, but It's a good Idea o keep such things in mind for other projects.

Edit: This comment was wrong... :)

PaulStoffregen
05-15-2020, 02:37 PM
Has anyone tested DMA-based ILI9341 or ILI9488 or similar displays with this last beta?

I'm going to test lots of libs here today. My hope is to finalize 1.52 soon, maybe even later today if everything is looking good.

mjs513
05-15-2020, 03:28 PM
Has anyone tested DMA-based ILI9341 or ILI9488 or similar displays with this last beta?

I'm going to test lots of libs here today. My hope is to finalize 1.52 soon, maybe even later today if everything is looking good.

Tried it @KurtE's ILI9341_t3n lib and the ILI9488 lib by setting the framebuffer to use - DMAMEM uint16_t tft_frame_buffer[ILI9488_TFTWIDTH * ILI9488_TFTHEIGHT];

Seems to working with no issues with and doing some heavy graphics stuff.

KurtE
05-15-2020, 03:29 PM
Has anyone tested DMA-based ILI9341 or ILI9488 or similar displays with this last beta?

I'm going to test lots of libs here today. My hope is to finalize 1.52 soon, maybe even later today if everything is looking good.

I have my ILI9488_t3 library hacked to run with display in EXTMEM and so far so good.

I have not tried ILI9341 yet with this beta. T4.1? or others as well?

Frank B
05-15-2020, 04:25 PM
Hm, now that I see the usage of PROGMEM above I wonder if there is any alignment... it should be minimum 4, but I don't see anything obvious in the files.
We should verify this.
If not, it would be a high-priority issue that needs a fix asap.

DD4WH
05-15-2020, 04:35 PM
@DD4wh: What is this for? :-)

You have used PROGMEM for several simple variables and even consts - I wouldn't do that.
This moves 4 Bytes from the fast RAM1 to the slower RAM2. They may be cached.. but ... if you use the EXTMEM (uses the same small 32kB cache) extensively the chance is not very high.
Overall it might be not a big difference in the code above, but It's a good Idea o keep such things in mind for other projects.
@FrankB:
* the sketch is for guitar cabinet emulation: combines applying large impulse responses to audio together with minimizing latency. (and it consumes a lot of processor power and a lot of memory, so is ideal for showing T4.1 its limits ;-)). For test purposes I did not use a real impulse response, but a minimum phase FIR lowpass filter with a cutoff at 19kHz, so actually a passthru . . . just to judge acoustically whether the file processing is correct :-)
* Maybe using PROGMEM here seems wrong for such small variable sizes . . . my intention was to absolutely minimize use of RAM1, because I need that RAM1 space for a very large array of float32_t
* I thought PROGMEM would be exactly the same as "const"!?

DD4WH
05-15-2020, 04:39 PM
Has anyone tested DMA-based ILI9341 or ILI9488 or similar displays with this last beta?

Win10, T4.0 with ADC PCM1808 and DAC PCM5102a and Ili9341_t3n (@70MHz) runs well with TD 1.52 beta6. Same setup also plays mp3 from SD card (flying wires soldered to a SD-card adapter) with FrankBs codec lib [Teensy Convolution SDR].

Frank B
05-15-2020, 04:57 PM
* I thought PROGMEM would be exactly the same as "const"!?
Ehhh.... yes, it uses adresses in the flash.
And forget my comment about the cache.. :) it was wrong.
Looks like I'm still tired. Need some sleep.. tztztz

DD4WH
05-15-2020, 05:08 PM
Need to read something about "cache" and how it works for the different RAM regions including EXTMEM. Do you have any suggestions where I could find something (beginners level, please :-) . . .)

KurtE
05-15-2020, 05:43 PM
Need to read something about "cache" and how it works for the different RAM regions including EXTMEM. Do you have any suggestions where I could find something (beginners level, please :-) . . .)

I am not sure there is a beginners level :D To me it is totally clear as mud.

When in doubt I typically look at the code. If you look in startup.c (Teensy4) at the function configure_cache

It will tell you how each area of memory is configured.


SCB_MPU_RBAR = 0x00000000 | REGION(i++); // trap NULL pointer deref
SCB_MPU_RASR = DEV_NOCACHE | NOACCESS | SIZE_32B;

SCB_MPU_RBAR = 0x00200000 | REGION(i++); // Boot ROM
SCB_MPU_RASR = MEM_CACHE_WT | READONLY | SIZE_128K;

SCB_MPU_RBAR = 0x20000000 | REGION(i++); // DTCM
SCB_MPU_RASR = MEM_NOCACHE | READWRITE | NOEXEC | SIZE_512K;

SCB_MPU_RBAR = ((uint32_t)&_ebss) | REGION(i++); // trap stack overflow
SCB_MPU_RASR = SCB_MPU_RASR_TEX(0) | NOACCESS | NOEXEC | SIZE_32B;

SCB_MPU_RBAR = 0x20200000 | REGION(i++); // RAM (AXI bus)
SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_1M;

SCB_MPU_RBAR = 0x40000000 | REGION(i++); // Peripherals
SCB_MPU_RASR = DEV_NOCACHE | READWRITE | NOEXEC | SIZE_64M;

SCB_MPU_RBAR = 0x60000000 | REGION(i++); // QSPI Flash
SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | SIZE_16M;

SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2
SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | NOEXEC | SIZE_256M;

SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2
SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_16M;


From here you can see how each area is configured. And you will see that DTCM (where most variables go) is not cached. That is because it is the fast memory.
You will then see most other areas are marked:MEM_CACHE_WBWA
These constants are also defined in the same file:

#define MEM_CACHE_WT SCB_MPU_RASR_TEX(0) | SCB_MPU_RASR_C
#define MEM_CACHE_WB SCB_MPU_RASR_TEX(0) | SCB_MPU_RASR_C | SCB_MPU_RASR_B
#define MEM_CACHE_WBWA SCB_MPU_RASR_TEX(1) | SCB_MPU_RASR_C | SCB_MPU_RASR_B
#define MEM_NOCACHE SCB_MPU_RASR_TEX(1)

I don't remember the exact define of WBWA - Write Back, write ??? - By usage I know that it means that the Cache contents and the memory contents may not necessarily be the same. Normally you don't care as most instructions work through the cache. However there are some other things like DMA that talk directly to the memory and not the cache.

So if your code is doing DMA into or out of these regions, there are things you need to do. Things like if you are writing out using dma, you need to tell the system to flush out the cache.... Likewise if you are reading stuff in by DMA, you need to tell system to delete the cache area...

But again I am not sure this is answering your question and as I mentioned, clear as mud!

MichaelMeissner
05-15-2020, 05:50 PM
Need to read something about "cache" and how it works for the different RAM regions including EXTMEM. Do you have any suggestions where I could find something (beginners level, please :-) . . .)

Here is a site with general information about cache memory in general that I found with a google search:

https://searchstorage.techtarget.com/definition/cache-memory


The Teensy 4.0 page has a better explanation of the memory layout right now than the 4.1 page (but it doesn't include the optional QSPI memory added in Teensy 4.1 at the moment):

https://www.pjrc.com/store/teensy40.html


In case DMA is also confusing, here is the wikipedia entry for it:

https://en.wikipedia.org/wiki/Direct_memory_access

DD4WH
05-15-2020, 06:15 PM
Thanks Kurt, thanks Michael! Excellent! Plugged out the Teensy and beginning to read now :-).

C0d3man
05-16-2020, 07:42 AM
Hi!

FYI:

I tried 1.52#6 on Linux (Kubuntu 20.04) and Arduino-1.8.12: Installation ok.

When I am trying to install my MicroDexed-project (which uses USBHost_t36.h) for Teensy-4.1, I am getting the following:


/usr/local/arduino-1.8.12-teensy/hardware/teensy/avr/libraries/USBHost_t36/adk.cpp: In member function 'void ADK::sendStr(Device_t*, uint8_t, char*)':
/usr/local/arduino-1.8.12-teensy/hardware/teensy/avr/libraries/USBHost_t36/adk.cpp:229:36: warning: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'char*' [-fpermissive]
strcpy(adkbuf, (unsigned char*)str);
^
In file included from /usr/local/arduino-1.8.12-teensy/hardware/tools/arm/arm-none-eabi/include/stdlib.h:11:0,
from /usr/local/arduino-1.8.12-teensy/hardware/teensy/avr/cores/teensy4/WProgram.h:34,
from /tmp/arduino_build_230358/pch/Arduino.h:6:
/usr/local/arduino-1.8.12-teensy/hardware/tools/arm/arm-none-eabi/include/string.h:34:8: note: initializing argument 1 of 'char* strcpy(char*, const char*)'
char *_EXFUN(strcpy,(char *__restrict, const char *__restrict));
^
/usr/local/arduino-1.8.12-teensy/hardware/teensy/avr/libraries/USBHost_t36/adk.cpp:229:36: warning: invalid conversion from 'unsigned char*' to 'const char*' [-fpermissive]
strcpy(adkbuf, (unsigned char*)str);
^
In file included from /usr/local/arduino-1.8.12-teensy/hardware/tools/arm/arm-none-eabi/include/stdlib.h:11:0,
from /usr/local/arduino-1.8.12-teensy/hardware/teensy/avr/cores/teensy4/WProgram.h:34,
from /tmp/arduino_build_230358/pch/Arduino.h:6:
/usr/local/arduino-1.8.12-teensy/hardware/tools/arm/arm-none-eabi/include/string.h:34:8: note: initializing argument 2 of 'char* strcpy(char*, const char*)'
char *_EXFUN(strcpy,(char *__restrict, const char *__restrict));
^
/usr/local/arduino-1.8.12-teensy/hardware/teensy/avr/libraries/USBHost_t36/adk.cpp: In member function 'void ADK::rx_data(const Transfer_t*)':
/usr/local/arduino-1.8.12-teensy/hardware/teensy/avr/libraries/USBHost_t36/adk.cpp:314:42: warning: invalid conversion from 'const uint8_t* {aka const unsigned char*}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]
uint8_t *p = (const uint8_t *)transfer->buffer;
^

For T_3.6 this works.

Regards, Holger

PaulStoffregen
05-16-2020, 08:00 AM
(which uses USBHost_t36.h) for Teensy-4.1, I am getting the following:

Fixed
https://github.com/PaulStoffregen/USBHost_t36/commit/d4f82a57f8d42fa0774178650437461d0d25d6f0

C0d3man
05-16-2020, 02:42 PM
Thanks @Paul (fixed minutes before 1.52 :))

W5UXH
05-17-2020, 08:47 PM
I just happened to be moving from Arduino 1.8.8 to 1.8.12 with Teensyduino 1.52-b5 yesterday. I immediately ran into the need to do some edits because of changes in the ADC library. I found the solution in the forum easily. I managed to get things working again with the new environment but now have a few warnings that do not appear to be related to my project code. My project functions are now working again (USB keyboard, TFT / touch display, A/D input decoding "Morse Code"). Can anyone tell me if I can just ignore warnings like those below?

Thanks, Chuck


/private/var/folders/tt/hmrg1j897131t24r2zh4ccg00000gn/T/AppTranslocation/CFD3AB6C-2458-499E-B3E1-2AF23C9741AA/d/T-1.52-b5-Arduino1.8.12.app/Contents/Java/hardware/teensy/avr/libraries/USBHost_t36/adk.cpp:229:36: warning: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'char*' [-fpermissive]

strcpy(adkbuf, (unsigned char*)str);


/private/var/folders/tt/hmrg1j897131t24r2zh4ccg00000gn/T/AppTranslocation/CFD3AB6C-2458-499E-B3E1-2AF23C9741AA/d/T-1.52-b5-Arduino1.8.12.app/Contents/Java/hardware/tools/arm/arm-none-eabi/include/string.h:34:8: note: initializing argument 1 of 'char* strcpy(char*, const char*)'

char *_EXFUN(strcpy,(char *__restrict, const char *__restrict));


/private/var/folders/tt/hmrg1j897131t24r2zh4ccg00000gn/T/AppTranslocation/CFD3AB6C-2458-499E-B3E1-2AF23C9741AA/d/T-1.52-b5-Arduino1.8.12.app/Contents/Java/hardware/teensy/avr/libraries/USBHost_t36/adk.cpp:314:42: warning: invalid conversion from 'const uint8_t* {aka const unsigned char*}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

uint8_t *p = (const uint8_t *)transfer->buffer;


Sketch uses 104416 bytes (9%) of program storage space. Maximum is 1048576 bytes.

Global variables use 24616 bytes (9%) of dynamic memory, leaving 237528 bytes for local variables. Maximum is 262144 bytes.