You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
25 KiB
188 lines
25 KiB
/**
|
|
* Spectral peak detection algorithm with interpolation
|
|
*
|
|
* Written by Ondřej Hruška "MightyPork", Dec 30, 2017
|
|
*
|
|
* This source code is hereby released to the public domain
|
|
* for anyone to use for anything they want.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
/**
|
|
* Rolling average centered at a bin
|
|
*
|
|
* @param arr - array of bins
|
|
* @param count - number of bins
|
|
* @param pos - position we're intersted in
|
|
* @param len - size of the rolling window, centered around the position
|
|
* @return average within the window, excluding bin at position 'pos'
|
|
*/
|
|
static float ravg(float *arr, uint32_t count, uint32_t pos, uint32_t len)
|
|
{
|
|
// XXX this needs some adjustments, it's not perfectly centered
|
|
|
|
// if we're at the end or beginning, use only bins we have available
|
|
uint32_t from = (pos > len/2 ? pos-len/2 : 0);
|
|
uint32_t to = (pos < count-len/2 ? pos+len/2 : count-1);
|
|
|
|
float acu = 0;
|
|
for (uint32_t i = from; i <= to; i++) {
|
|
if (i == pos) continue;
|
|
acu += arr[i];
|
|
}
|
|
acu /= (to - from); // not +1 because we skip the middle
|
|
|
|
return acu;
|
|
}
|
|
|
|
/** A detected peak struct */
|
|
struct peak {
|
|
float position; // precise position, unit is 1 bin
|
|
float magnitude; // precise magnitude
|
|
float weight; // sorting weight (internal use)
|
|
};
|
|
|
|
/**
|
|
* Quadratic interpolation to find the real peak position and magnitude
|
|
*
|
|
* @param pk - peak struct to store the results in
|
|
* @param values - the bins array
|
|
* @param vcount - size of the bins array
|
|
* @param pos - position of the peak we're triyng to analyze
|
|
*/
|
|
static void qinterp(struct peak *pk, const float *values, uint32_t vcount, uint32_t pos)
|
|
{
|
|
float a = (pos>0?values[pos-1]:values[pos]);
|
|
float b = values[pos];
|
|
float c = (pos<vcount-2?values[pos+1]:values[pos]);
|
|
|
|
float p = 0.5 * (a-c)/(a-2*b+c);
|
|
|
|
pk->position = pos + p;
|
|
pk->magnitude = b - 0.25 * (a - c) * p;
|
|
}
|
|
|
|
/** Copy a peak */
|
|
static void cpy_pk(struct peak *dest, const struct peak *src)
|
|
{
|
|
dest->position = src->position;
|
|
dest->magnitude = src->magnitude;
|
|
dest->weight = src->weight;
|
|
}
|
|
|
|
/**
|
|
* Detect peaks in a real float spectrum
|
|
*
|
|
* @param peaks - destination for the peak detect algorithm, peaks are sorted from the most important
|
|
* @param pcount - number of peaks to detect
|
|
* @param values - the spectrum as an array of bin magnitudes
|
|
* @param vcount - number of bins in the spectrum
|
|
* @return average level (excluding the peaks)
|
|
*/
|
|
float pkdetect(struct peak *peaks, uint32_t pcount, float *values, uint32_t vcount)
|
|
{
|
|
uint32_t used_peaks = 0;
|
|
|
|
// clear the table
|
|
for (uint32_t i = 0; i < pcount; i++) {
|
|
peaks[i].position
|
|
= peaks[i].magnitude
|
|
= peaks[i].weight = 0;
|
|
}
|
|
|
|
struct peak pk; // scratch peak
|
|
float prev = 0;
|
|
float sum = 0;
|
|
for (uint32_t i = 0; i < vcount; i++) {
|
|
float base = ravg(values, vcount, i, 32);
|
|
float raw = values[i];
|
|
float normed = raw / base;
|
|
if (i > 0) {
|
|
// difference from the previous bin (this serves as the primary peak detection factor)
|
|
float diff = normed - prev;
|
|
|
|
if (diff > 0) {
|
|
// find the precise position and magnitude
|
|
qinterp(&pk, values, vcount, i);
|
|
// weight for sorting the peaks
|
|
pk.weight = diff * pk.magnitude;
|
|
|
|
// try to fit it in the peak list
|
|
for (uint32_t j = 0; j < pcount; j++) {
|
|
if (pk.weight > peaks[j].weight) {
|
|
for (uint32_t k = used_peaks; k > j; k--) {
|
|
cpy_pk(&peaks[k], &peaks[k-1]);
|
|
}
|
|
cpy_pk(&peaks[j], &pk);
|
|
used_peaks++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
prev = normed;
|
|
sum += raw; // this is rms
|
|
}
|
|
|
|
// now remove some area around the found peaks (NOTE: this will cause double removal if two peaks happened to be very close together)
|
|
float pksum = 0;
|
|
const uint32_t pkexpand = 4;
|
|
for (uint32_t i = 0; i < pcount; i++) {
|
|
uint32_t pos = (uint32_t)roundf(peaks[i].position);
|
|
uint32_t from = (pos > pkexpand/2 ? pos-pkexpand/2 : 0);
|
|
uint32_t to = (pos < vcount-pkexpand/2 ? pos+pkexpand/2 : vcount-1);
|
|
for (uint32_t j = from; j <= to; j++) {
|
|
pksum += values[j];
|
|
}
|
|
}
|
|
|
|
float noise = (sum - pksum);
|
|
if (noise < 0) noise = 0;
|
|
return noise / vcount;
|
|
}
|
|
|
|
|
|
|
|
// this is just for the demo
|
|
union smp_union {
|
|
uint8_t bytes[4096];
|
|
float floats[1024];
|
|
};
|
|
|
|
union smp_union smp;
|
|
|
|
int main (void)
|
|
{
|
|
uint8_t b[] = {
|
|
0x53,0x6C,0x46,0x39,0x31,0x91,0xF8,0x38,0xFA,0xF9,0x70,0x38,0xB6,0xB3,0xE8,0x38,0xB0,0xA8,0xA3,0x39,0x5C,0x98,0xAD,0x3A,0xE1,0x38,0x00,0x3B,0x4D,0x09,0x7D,0x3A,0x1A,0xD2,0x26,0x3B,0xF9,0x85,0xD7,0x3A,0x5E,0xBB,0x0B,0x3B,0xF0,0x04,0xAD,0x3A,0xDF,0x95,0xCE,0x3A,0xD1,0x94,0x2E,0x39,0x0F,0xE2,0x68,0x39,0x4C,0xE9,0x02,0x39,0xFC,0xAA,0x4B,0x3A,0xB4,0x56,0xE2,0x3A,0xF1,0xA4,0x1C,0x3A,0x7C,0x4A,0x12,0x3A,0x7A,0xE4,0xDF,0x3A,0x3B,0xD6,0x57,0x3A,0x0E,0x1E,0x35,0x38,0x66,0x52,0x32,0x39,0xD6,0x0F,0x08,0x39,0xB3,0xBC,0x6E,0x39,0x25,0x9A,0xD8,0x39,0xE0,0xC9,0xF9,0x3A,0xD0,0x09,0x66,0x3A,0xA2,0x79,0x30,0x39,0xA9,0x0F,0x6D,0x39,0xC1,0x90,0xFF,0x39,0x36,0x8B,0xE2,0x39,0x77,0x5C,0x37,0x39,0x26,0xA8,0x0F,0x3A,0x1C,0x75,0xD5,0x39,0x29,0xD1,0xA3,0x38,0x2C,0x32,0x65,0x39,0x4A,0x0F,0xC7,0x38,0x31,0xE9,0x1D,0x3A,0x31,0xB6,0x8F,0x3B,0x6F,0x8D,0x94,0x3B,0x0E,0x90,0x24,0x3A,0xAA,0x62,0x1A,0x3A,0xFB,0xF1,0x99,0x39,0x77,0xE7,0xE4,0x37,0x09,0x0D,0x1D,0x39,0x2E,0x7D,0x1F,0x38,0x86,0xC1,0x41,0x38,0x8D,0xA6,0x80,0x38,0x48,0xD5,0x25,0x38,0xB4,0xC6,0x9C,0x39,0x94,0xAE,0x1F,0x3A,0x3C,0xDF,0x4A,0x3A,0x4E,0xF6,0xE7,0x3A,0x18,0x28,0xCE,0x3A,0xB2,0xEB,0xD5,0x39,0x79,0xE3,0x7C,0x39,0xCF,0x20,0xD0,0x39,0x5C,0xD7,0x1F,0x39,0x19,0x70,0x00,0x39,0xD4,0xFD,0xA4,0x39,0x27,0x26,0x04,0x39,0x95,0xCA,0x93,0x38,0x0E,0x50,0x54,0x38,0xD6,0x89,0x32,0x38,0x3D,0x5A,0x33,0x38,0x34,0xC7,0x99,0x38,0x2F,0xF6,0x22,0x38,0x9A,0x71,0x97,0x38,0xBE,0x7A,0x82,0x38,0x7C,0x3F,0x1C,0x39,0xA8,0xFA,0x05,0x39,0x33,0xA1,0x07,0x39,0x1A,0xA6,0x39,0x39,0x83,0x9E,0x9D,0x38,0x24,0x7B,0x35,0x38,0x39,0xFA,0x28,0x38,0xF0,0x38,0x4B,0x38,0x32,0x2F,0x23,0x39,0x5D,0xBA,0x6E,0x38,0x9D,0x5D,0x7D,0x3A,0x20,0xCE,0x56,0x3A,0x3F,0xCD,0x4D,0x39,0x03,0x89,0x88,0x38,0x12,0xF9,0xB9,0x37,0x20,0xB8,0x8C,0x38,0x6F,0x9A,0x60,0x38,0x92,0x90,0x15,0x38,0xA3,0xB3,0xD9,0x38,0x3F,0x12,0x46,0x38,0x3F,0x0A,0x3F,0x38,0x3B,0x73,0xEB,0x37,0x2B,0xDC,0x46,0x38,0xED,0xA2,0xF5,0x37,0x5E,0x28,0xBE,0x38,0x1C,0x27,0xC8,0x38,0x2C,0x66,0x9C,0x37,0xCC,0x18,0x2E,0x37,0x4F,0x14,0xB9,0x37,0x19,0x72,0xBD,0x37,0xF6,0x24,0x85,0x37,0x72,0x3F,0xC9,0x37,0xEC,0x32,0xD7,0x34,0x32,0x77,0x52,0x37,0x61,0x7F,0x1A,0x37,0x7F,0x56,0xCF,0x37,0x96,0x8E,0x3F,0x38,0xE9,0xD3,0x37,0x39,0xA0,0xF5,0x60,0x39,0xE5,0x69,0x74,0x38,0xF6,0x15,0x78,0x37,0x74,0x4A,0xE2,0x37,0xEE,0x43,0x0A,0x38,0xFD,0x77,0xA6,0x37,0xDD,0xBD,0x96,0x37,0xF9,0x46,0xC1,0x37,0x1D,0x75,0x42,0x37,0xA8,0x2B,0x9E,0x36,0xC5,0xF5,0x88,0x37,0xA6,0xA6,0xE8,0x36,0x99,0x85,0x30,0x37,0x61,0x26,0x50,0x38,0x16,0x03,0xCE,0x37,0x6E,0x91,0x34,0x38,0x6F,0xC9,0x8C,0x38,0x74,0x03,0x02,0x38,0xE0,0xEF,0x8A,0x37,0x92,0xB6,0xFE,0x37,0x20,0x9E,0xE8,0x37,0x3D,0x15,0x9D,0x37,0xF7,0x03,0x9F,0x37,0x75,0xB9,0x8A,0x37,0xFD,0xE7,0xFA,0x36,0x76,0x6B,0x2B,0x37,0x36,0x09,0x84,0x36,0xC6,0x97,0x91,0x37,0x9D,0x7A,0xB4,0x37,0xFF,0xF3,0x97,0x37,0x61,0x97,0xC4,0x37,0x0C,0x42,0x39,0x37,0x65,0x10,0xBC,0x37,0x67,0xD7,0xCB,0x37,0x8A,0x7D,0xA7,0x37,0x06,0xBC,0x03,0x38,0xDA,0x35,0x7E,0x37,0x06,0x20,0x26,0x36,0x82,0x3E,0xAF,0x36,0x57,0x3E,0x14,0x37,0xED,0xFE,0x89,0x37,0x32,0xA4,0x9A,0x37,0x33,0x4E,0x05,0x37,0xDF,0x3F,0x02,0x37,0xDF,0xBE,0xD1,0x37,0xB8,0xA7,0xC2,0x37,0x7D,0x61,0xD8,0x36,0x27,0xA3,0xEC,0x36,0x6E,0x04,0x52,0x37,0x10,0xF7,0x29,0x37,0xA3,0x7E,0xD3,0x36,0xBC,0xA2,0xAC,0x37,0xD8,0x5D,0xCE,0x37,0x8F,0xD1,0xB7,0x37,0xCE,0x35,0x68,0x37,0x9D,0x14,0x82,0x37,0x86,0x54,0x4C,0x38,0x0C,0xB9,0xC3,0x37,0xE9,0xF1,0xB7,0x37,0x3C,0x7C,0xB2,0x37,0x8D,0xD4,0xD5,0x37,0x28,0xF3,0x97,0x37,0x57,0x92,0x70,0x37,0xCA,0x4E,0x68,0x36,0xED,0xC2,0x76,0x36,0xDC,0xDD,0x26,0x37,0x1A,0x70,0x91,0x37,0x86,0x64,0x65,0x37,0x9F,0xB2,0xB5,0x37,0xF5,0x6E,0xB0,0x37,0x10,0xB1,0xA4,0x37,0x7F,0x06,0x3B,0x37,0xDC,0x85,0xB9,0x37,0x3C,0xE1,0x30,0x38,0x12,0xF2,0x95,0x37,0xA8,0xB9,0x84,0x37,0x79,0xC8,0xBD,0x37,0x31,0xB9,0x95,0x37,0x92,0xFA,0x99,0x37,0x74,0x9E,0xBF,0x37,0xA0,0x52,0x2D,0x37,0x7B,0x56,0x43,0x37,0x3A,0xB3,0xBC,0x36,0x01,0xC6,0x19,0x37,0xD1,0x87,0x0E,0x38,0x77,0x9E,0x04,0x38,0x21,0xF1,0x60,0x37,0x37,0xA1,0xDB,0x37,0xE2,0xCC,0x00,0x38,0x52,0xF0,0x8C,0x37,0xCC,0x3A,0x73,0x37,0x28,0xF8,0x1A,0x37,0x19,0x73,0x80,0x37,0x36,0x79,0xBB,0x36,0x0D,0xA5,0x1F,0x37,0xAA,0x62,0xFC,0x35,0x82,0x00,0x6D,0x36,0x09,0x6D,0xEF,0x36,0x4A,0xD5,0x1C,0x37,0xFA,0xC7,0x62,0x37,0x2F,0xCB,0x2E,0x37,0x3A,0x5A,0x9B,0x37,0x4B,0x77,0x4D,0x36,0x1B,0xFA,0x9E,0x37,0x47,0xFB,0x8F,0x37,0xAA,0x49,0xAD,0x36,0xC9,0x48,0x23,0x37,0xA5,0x15,0x36,0x37,0x07,0x88,0x10,0x36,0xAB,0x59,0x27,0x37,0xF4,0xFE,0xBC,0x35,0x12,0xBE,0x3D,0x37,0x02,0x30,0x49,0x37,0xA6,0xDD,0x9B,0x36,0x6D,0xC6,0x6B,0x37,0xCD,0x55,0x4C,0x37,0xF6,0x19,0x34,0x37,0xC1,0xC1,0x80,0x37,0xBA,0x4B,0xBF,0x36,0xF5,0xC8,0x73,0x37,0x28,0xF5,0xB5,0x37,0x3C,0xE5,0x0D,0x37,0x19,0x47,0x04,0x36,0xD0,0xD2,0x2B,0x37,0x4F,0xE9,0xAF,0x37,0xA6,0x70,0x89,0x37,0x84,0x33,0x26,0x37,0xD5,0x22,0x16,0x37,0xEC,0xF3,0xB7,0x37,0xC2,0x93,0xDD,0x36,0x1B,0xED,0x67,0x37,0x73,0xB0,0x9F,0x37,0xFA,0x8D,0x69,0x37,0x3C,0xCD,0xBA,0x36,0x0A,0x34,0xC9,0x37,0x46,0xE4,0xB7,0x37,0x24,0x03,0xB4,0x37,0x08,0xB3,0x9B,0x36,0x8D,0xFD,0x5F,0x37,0x74,0x89,0x89,0x37,0x33,0x70,0x4C,0x37,0x15,0xB1,0x3C,0x37,0xC9,0x2F,0x29,0x37,0xBB,0xDC,0x9A,0x37,0xA9,0xFC,0xD6,0x36,0x3D,0x88,0xBE,0x37,0xEB,0xA8,0x2B,0x37,0xB1,0x85,0x4B,0x37,0x8F,0x84,0x9C,0x35,0xEF,0xA9,0x91,0x37,0xE3,0x89,0x8D,0x37,0x7E,0xFC,0xFE,0x36,0x59,0xCB,0x19,0x37,0xBA,0xC5,0x25,0x37,0xFB,0xE5,0x79,0x37,0xD8,0x39,0x5A,0x37,0x4C,0x91,0x9C,0x36,0xAB,0x16,0x64,0x37,0x18,0x30,0x2B,0x37,0x26,0xAD,0x77,0x35,0x28,0x0F,0xB5,0x36,0x17,0x85,0x84,0x36,0x91,0x06,0x98,0x35,0x59,0xB8,0x4D,0x37,0x8A,0x23,0x7B,0x37,0xB0,0x4D,0x89,0x37,0x95,0xF9,0x79,0x37,0xD4,0x76,0x2F,0x37,0x7A,0x4E,0x53,0x37,0x47,0x75,0x5B,0x37,0x3B,0xB7,0x75,0x37,0x3A,0x0E,0x91,0x36,0x49,0x8C,0xE5,0x37,0xE6,0x6E,0xA3,0x37,0xF7,0xFA,0xBE,0x36,0x71,0x11,0x30,0x36,0xA6,0xB5,0x5D,0x37,0x70,0x63,0xBC,0x37,0x31,0x35,0x1E,0x37,0xCE,0x6A,0x55,0x36,0xE3,0x8E,0xAE,0x36,0x51,0xB6,0x18,0x37,0xDC,0xAD,0x34,0x37,0xCE,0x79,0x61,0x37,0x92,0xC3,0xB3,0x37,0x6B,0xAB,0x22,0x37,0x0C,0xB9,0xC7,0x37,0xA3,0xCE,0x1A,0x38,0xE4,0x69,0x86,0x37,0xDD,0x7F,0x81,0x36,0x57,0x07,0x12,0x37,0xAF,0x3F,0xF9,0x35,0x22,0x1D,0x8C,0x37,0x7C,0xC7,0x24,0x37,0x3D,0xC7,0x42,0x37,0xC4,0x03,0xB9,0x37,0xE3,0xB3,0xC0,0x37,0x30,0x95,0xF5,0x37,0x32,0xB5,0xE6,0x37,0x18,0x9A,0xA9,0x37,0xC7,0x48,0xA2,0x37,0xBD,0x7E,0x64,0x37,0x26,0x01,0x07,0x37,0x57,0xBC,0xD5,0x36,0xFB,0x2C,0xBD,0x37,0x81,0x1B,0xBD,0x37,0xFD,0x31,0x04,0x37,0x46,0x10,0x40,0x37,0x9C,0x5A,0x1F,0x37,0xA5,0x46,0x6C,0x37,0x89,0xB0,0x71,0x37,0xF0,0x43,0x9F,0x37,0xD4,0x02,0x2E,0x37,0x77,0xDC,0xDB,0x37,0xF1,0x5A,0x77,0x37,0x49,0x57,0x2D,0x37,0xF3,0xB9,0x84,0x37,0xD8,0x69,0xAC,0x37,0x3F,0x2D,0x07,0x38,0x4D,0x9D,0x99,0x37,0x01,0x10,0xE0,0x36,0xD0,0xB9,0xE6,0x36,0x37,0x5D,0x3E,0x37,0x3D,0x4D,0x83,0x36,0x21,0xB7,0x43,0x37,0xBA,0x11,0x9D,0x37,0x86,0xD7,0x09,0x37,0x9B,0x4D,0x05,0x36,0x84,0x96,0x5E,0x37,0x8E,0xDB,0xA2,0x37,0x07,0x09,0x55,0x37,0x9C,0xB5,0x4E,0x37,0x6F,0x93,0xA9,0x37,0xF8,0x3C,0x73,0x37,0x79,0x84,0x76,0x37,0x32,0x00,0xD6,0x37,0x21,0xC4,0xE6,0x37,0xFB,0x4B,0xD1,0x37,0x42,0xEC,0xCB,0x37,0x0B,0x85,0x87,0x37,0x19,0x4F,0x60,0x37,0x35,0x28,0x6A,0x37,0xDE,0x8B,0x99,0x37,0xCD,0xE0,0x73,0x37,0x93,0x03,0x7D,0x37,0xC5,0x83,0xE7,0x37,0xF6,0x13,0x1D,0x38,0x71,0xA8,0xFB,0x37,0x84,0x8A,0xB8,0x37,0xD6,0xA1,0x43,0x37,0xD2,0x1B,0x6A,0x37,0x45,0xDE,0xD5,0x37,0x06,0x7A,0x5C,0x37,0x46,0xBA,0x87,0x37,0x4F,0x16,0xAB,0x36,0xF0,0x75,0x21,0x37,0x49,0xF1,0xE3,0x37,0x8F,0xE8,0x0F,0x38,0x85,0x87,0xA6,0x37,0x9F,0x87,0x40,0x37,0xBE,0x39,0x30,0x37,0x33,0x4B,0x47,0x37,0x9D,0x9B,0xBD,0x37,0x65,0x85,0x0C,0x37,0x66,0xD2,0xCD,0x36,0xA5,0xB9,0xCE,0x36,0x44,0x8F,0x05,0x37,0x2B,0x33,0x0C,0x37,0x66,0x90,0x62,0x37,0x65,0x31,0x91,0x37,0x8C,0x47,0x8D,0x37,0x9E,0x31,0x76,0x37,0xED,0xFA,0xB1,0x36,0x63,0x8C,0x9C,0x37,0x4A,0xEF,0x86,0x36,0xE5,0x6A,0xB1,0x37,0xC6,0x34,0xAC,0x37,0x61,0x09,0x73,0x37,0x3F,0x0E,0x94,0x37,0x1E,0x5F,0xD2,0x37,0x35,0xDE,0x85,0x37,0x09,0xD1,0xCE,0x36,0xE5,0x14,0x36,0x37,0xAB,0xE5,0xD3,0x36,0xB9,0x7B,0x5D,0x37,0x91,0x9C,0xB8,0x37,0x5C,0xA0,0x68,0x37,0x9D,0xBD,0x2C,0x37,0x77,0x39,0x9D,0x36,0x07,0x76,0x2D,0x37,0x1C,0x8D,0x43,0x37,0xBB,0xCB,0x07,0x38,0x8F,0x2E,0xE3,0x37,0x3C,0x61,0x43,0x36,0x9E,0x28,0x32,0x37,0x81,0x3E,0x9A,0x36,0xEE,0x03,0x51,0x37,0x72,0x25,0x48,0x36,0xFE,0x81,0x81,0x37,0x83,0xB7,0xD9,0x37,0xEA,0x53,0xD6,0x37,0x54,0xDD,0x2D,0x37,0x84,0x5E,0x8C,0x37,0xAA,0xD9,0x7D,0x37,0x98,0xEB,0x92,0x37,0x19,0xCD,0x27,0x37,0x83,0xA4,0x42,0x37,0x9E,0x72,0x6B,0x37,0xB5,0xF6,0x0E,0x37,0xFD,0x77,0x41,0x37,0xC3,0xBB,0xFB,0x36,0x3E,0x11,0x28,0x37,0x17,0xE1,0x58,0x37,0x78,0x25,0x0E,0x37,0x78,0x02,0xE5,0x36,0xCA,0xB2,0x7C,0x37,0x27,0x9C,0x9D,0x37,0x74,0xDE,0x8C,0x37,0x74,0x66,0x5E,0x37,0x9C,0x44,0x90,0x37,0x94,0x4E,0x8D,0x37,0x5F,0x83,0xC1,0x37,0xF0,0x5C,0x84,0x37,0x42,0x6B,0xFB,0x36,0x85,0x74,0x05,0x37,0xDC,0x60,0x5A,0x37,0x19,0x8A,0x85,0x37,0xFA,0x9D,0xF6,0x36,0xB7,0xB4,0x6C,0x36,0x80,0x5E,0x7B,0x37,0x25,0x57,0xB0,0x37,0x21,0x27,0x56,0x37,0xAA,0x5E,0xA4,0x36,0x24,0x90,0x92,0x37,0x95,0x50,0x74,0x37,0xEF,0xDA,0x67,0x37,0x8F,0x32,0x00,0x37,0x39,0xCD,0xA4,0x37,0xB0,0x4D,0x2B,0x37,0xC6,0xFD,0x95,0x37,0xF7,0x08,0xB4,0x37,0x14,0x22,0x98,0x37,0xCE,0xF3,0x74,0x37,0x64,0x17,0x66,0x37,0x4E,0xC2,0x87,0x36,0xF4,0xCA,0x06,0x37,0x90,0x82,0x2C,0x37,0x1A,0x52,0x7B,0x37,0x59,0x70,0x34,0x37,0x68,0xCA,0x99,0x36,0x38,0xB4,0x77,0x37,0x6D,0x62,0x78,0x37,0x50,0x6A,0x5F,0x37,0xB3,0xFC,0x07,0x37,0xE0,0x7D,0x24,0x37,0xC2,0x14,0x61,0x37,0x67,0x89,0x1B,0x37,0x57,0xF0,0x00,0x37,0xCA,0x4B,0x49,0x37,0xD9,0x5B,0x42,0x37,0x38,0xE2,0xC6,0x35,0x8B,0xF8,0x3C,0x37,0xB0,0x0E,0x8E,0x36,0x60,0xD2,0xD7,0x36,0xCE,0xF0,0x19,0x37,0x32,0x71,0x1B,0x37,0xDF,0xC6,0x33,0x37,0x6B,0xBB,0x9D,0x37,0x66,0xF9,0x9E,0x37,0xCE,0x31,0x15,0x37,0xE1,0xB7,0x25,0x37,0x94,0xBD,0x4B,0x36,0x9D,0x0B,0x73,0x37,0x5B,0x85,0x94,0x37,0x96,0x47,0xBD,0x37,0x37,0xA7,0x79,0x37,0x98,0xCB,0xB6,0x37,0x1D,0x52,0xC2,0x37,0xFD,0x79,0x25,0x37,0xB8,0x0B,0x0C,0x37,0x67,0x9D,0xB7,0x36,0xC8,0x38,0xF9,0x36,0x33,0x1B,0x8E,0x36,0x2A,0x0B,0xDA,0x36,0x1F,0xCA,0x12,0x37,0x48,0x02,0x11,0x37,0x03,0x74,0x8A,0x37,0x24,0xE9,0x9F,0x37,0x39,0xC6,0x42,0x37,0x3E,0xF4,0x8C,0x36,0x39,0xA3,0x56,0x37,0x70,0xEC,0x88,0x37,0xB6,0xE3,0x39,0x37,0xCD,0xC9,0xD2,0x35,0x8B,0x2B,0x96,0x36,0x4B,0x97,0x01,0x37,0xD4,0x9B,0xB7,0x37,0xA4,0x7E,0xD7,0x37,0x95,0xB6,0x92,0x37,0x8B,0x3F,0xA4,0x37,0x17,0xCA,0xF3,0x36,0x34,0x32,0x11,0x37,0xED,0xC1,0x2F,0x37,0x82,0x39,0xA9,0x37,0x5C,0xEC,0x38,0x37,0x49,0xE5,0x29,0x37,0xE5,0xA1,0x03,0x37,0x5E,0xA7,0xE8,0x36,0x66,0x3A,0x4E,0x37,0xA7,0x6B,0x15,0x37,0x89,0x37,0xBC,0x37,0x6A,0x9D,0xF2,0x37,0x86,0xB7,0x72,0x37,0xFD,0xAB,0x76,0x37,0xF7,0x30,0xA9,0x37,0x70,0x7F,0x78,0x37,0xD2,0xFF,0x42,0x37,0x83,0x2F,0xBD,0x37,0x42,0x46,0x33,0x37,0xD3,0x30,0x7A,0x37,0x45,0x0A,0xAA,0x37,0xE4,0xD2,0xD8,0x37,0x05,0xB8,0x8D,0x37,0x98,0x13,0xDB,0x37,0x4C,0xED,0x43,0x37,0x59,0x07,0x96,0x37,0xBE,0x50,0xF0,0x37,0xAD,0xFA,0x1F,0x38,0x20,0x8A,0x0A,0x38,0x60,0x16,0xB6,0x37,0x18,0xA7,0x58,0x37,0xB5,0x08,0x15,0x37,0x76,0x24,0x56,0x37,0xCB,0x63,0x18,0x37,0x87,0x4F,0x84,0x37,0x07,0x7B,0x18,0x37,0xB3,0x9D,0x8D,0x36,0xBA,0x9E,0xA5,0x37,0x47,0x5D,0xC0,0x37,0x1F,0x7E,0x21,0x36,0x18,0x88,0x9A,0x37,0x9B,0x10,0x16,0x37,0xDB,0x54,0x32,0x37,0xC9,0x50,0x62,0x37,0x26,0x06,0x6A,0x37,0xA9,0x48,0x0C,0x36,0xE4,0x76,0x1E,0x37,0xF8,0xF7,0x07,0x37,0x27,0x84,0x35,0x37,0xA5,0xAE,0x9B,0x36,0xEB,0x23,0x89,0x37,0x84,0x87,0x9A,0x37,0xCA,0x38,0xB5,0x37,0xE9,0x1E,0xF1,0x37,0xEE,0x25,0x55,0x37,0x65,0xE3,0x87,0x36,0xF3,0x0B,0x7C,0x37,0x14,0x86,0x87,0x37,0x8B,0xB3,0xED,0x36,0x02,0xA0,0x9C,0x37,0xBB,0xF1,0xCF,0x37,0x7A,0x61,0x0B,0x36,0x9F,0x86,0x5F,0x37,0x49,0xF3,0x8B,0x37,0x88,0x2A,0x84,0x37,0x3F,0xDD,0x26,0x37,0x03,0xA3,0x82,0x36,0x59,0xB4,0x28,0x37,0xDD,0x41,0x15,0x37,0x5A,0x83,0x85,0x37,0x4E,0x9E,0xAE,0x36,0x71,0x98,0xA8,0x37,0x8D,0xBF,0xBF,0x37,0x4D,0x45,0xE8,0x37,0xF7,0x18,0x0A,0x38,0x16,0x64,0x85,0x37,0xF8,0x85,0x79,0x36,0x86,0x4D,0x19,0x37,0xD7,0x2A,0xB7,0x37,0x2A,0xFE,0xB0,0x37,0x3E,0x79,0xAC,0x37,0x46,0xFE,0x95,0x36,0xD1,0xDC,0x91,0x37,0xF2,0x27,0x9C,0x37,0x99,0x25,0x6A,0x36,0x4C,0x17,0x62,0x37,0xE8,0x7D,0x57,0x37,0xC7,0x2F,0x18,0x37,0x02,0x07,0xE1,0x36,0x1A,0x5B,0x91,0x36,0x57,0x48,0x74,0x36,0x3C,0xE0,0x15,0x36,0x42,0x22,0x54,0x37,0x98,0xE9,0x2F,0x37,0xF4,0x9E,0xC3,0x37,0x8C,0x59,0x3B,0x38,0x77,0xCE,0x93,0x37,0xD7,0xD1,0x25,0x37,0x8D,0xF9,0xBE,0x36,0x95,0x6B,0x4E,0x36,0xED,0xEA,0xD4,0x36,0x5D,0x87,0x55,0x37,0xA4,0xBF,0xCE,0x37,0xD2,0xD1,0x8F,0x37,0xD0,0x97,0xD4,0x36,0x03,0x27,0x84,0x37,0x78,0xC4,0xCC,0x37,0xB9,0x3A,0xB4,0x37,0xFB,0xFA,0x8D,0x37,0x91,0x86,0x44,0x37,0x07,0x20,0x54,0x37,0xE6,0xFB,0xA8,0x36,0xED,0x26,0x17,0x37,0xE1,0x95,0xDF,0x36,0x52,0xAD,0x05,0x37,0xDB,0x43,0xEC,0x36,0x74,0x9E,0xF4,0x36,0x04,0x66,0x8A,0x37,0xFC,0xEB,0x61,0x37,0xA1,0x5C,0x51,0x37,0xCC,0x35,0xAD,0x37,0xA0,0x39,0x83,0x37,0xB4,0x91,0x8D,0x37,0x99,0xD3,0x2C,0x38,0x05,0x4E,0x0A,0x38,0x18,0xF3,0x52,0x37,0xE0,0xDA,0x33,0x36,0x30,0xA4,0x89,0x37,0xB0,0x66,0xB4,0x36,0xDC,0xFE,0x67,0x37,0x61,0xC0,0x0E,0x37,0x8E,0xD4,0xE4,0x36,0x1A,0xC0,0xF4,0x36,0x3E,0x8D,0xBA,0x37,0x28,0xE1,0xD4,0x36,0xFE,0xB0,0xA6,0x37,0x7E,0xDA,0xFC,0x36,0xD1,0xEC,0x18,0x38,0x60,0x0C,0xB4,0x37,0x5D,0xA4,0x3E,0x36,0x3F,0xC2,0x4C,0x36,0x10,0x0C,0x24,0x37,0x07,0xF1,0xB2,0x36,0x94,0x0A,0x25,0x37,0xF9,0x07,0x48,0x36,0x7D,0x8E,0xC0,0x36,0x2E,0xC6,0x27,0x37,0xA3,0xE7,0x0D,0x37,0x86,0xE9,0xE1,0x36,0x6C,0x54,0x91,0x37,0xAC,0x25,0xAB,0x37,0x4B,0xBE,0x7F,0x37,0x6B,0x8D,0x4B,0x37,0xCE,0xE9,0xAC,0x37,0x82,0x79,0xA6,0x37,0x81,0xEE,0x70,0x37,0x1B,0x5C,0x7E,0x37,0xA2,0x68,0xF3,0x37,0x41,0x26,0x66,0x38,0xBB,0xB7,0xBE,0x37,0x2E,0xB7,0xC1,0x37,0x47,0xA3,0xA5,0x37,0xC3,0x9D,0xB4,0x37,0x04,0xF7,0x9A,0x37,0x7E,0xE2,0x89,0x37,0xC0,0xEB,0x97,0x37,0xA5,0xA2,0x1E,0x38,0xF8,0x49,0x96,0x37,0x08,0xDF,0x81,0x37,0x3A,0x7E,0xA0,0x37,0x00,0xEC,0xEC,0x37,0xEE,0x70,0xA5,0x37,0xE0,0x72,0x5F,0x37,0xF1,0x8A,0x33,0x37,0xCC,0xB3,0x73,0x37,0xF6,0x3F,0xAB,0x36,0xDE,0xB0,0xCE,0x37,0x91,0x11,0x0B,0x38,0x8F,0x32,0x2C,0x37,0x28,0x13,0x6C,0x37,0x2F,0xF3,0x38,0x37,0x8D,0x26,0x19,0x37,0x96,0xF4,0xC6,0x37,0xEA,0xFF,0x13,0x38,0x2E,0x20,0xDD,0x37,0x27,0x58,0x2A,0x38,0xE5,0x5C,0x81,0x38,0xF1,0x43,0x07,0x38,0xDB,0x03,0xCD,0x37,0xCD,0xCB,0x4D,0x38,0xDB,0x3D,0xCA,0x37,0x31,0x5E,0x0A,0x37,0x52,0x60,0x0B,0x38,0x8C,0xF2,0x46,0x38,0xB5,0x40,0x1E,0x38,0xE4,0xD9,0xE3,0x36,0x90,0x95,0xD1,0x37,0x48,0xFC,0xF4,0x37,0xAF,0x83,0x05,0x38,0x45,0x0A,0xD2,0x37,0xA2,0x0B,0xE8,0x36,0x05,0x2B,0xD7,0x37,0xBE,0x2B,0x70,0x37,0xF6,0xA2,0x1D,0x38,0x21,0x56,0x37,0x38,0x0D,0x36,0x61,0x38,0x30,0x69,0x39,0x38,0x38,0x88,0xB6,0x37,0xB6,0xDA,0x3A,0x37,0xBE,0x42,0x8C,0x38,0xD9,0x28,0x7E,0x38,0x59,0x9C,0x06,0x38,0x9C,0x4C,0x05,0x38,0xEE,0xCE,0x8B,0x37,0x8F,0xD5,0xF6,0x37,0xF5,0xD4,0x77,0x36,0xCE,0x9B,0x19,0x38,0xE7,0x92,0x63,0x38,0xA4,0xE9,0x2B,0x38,0xE9,0xAB,0xDD,0x37,0xFD,0x63,0x1A,0x37,0x5C,0x8E,0x90,0x38,0x72,0x93,0x8E,0x38,0xCD,0x34,0x79,0x37,0xF2,0x14,0x2A,0x38,0x80,0x02,0x43,0x38,0xF5,0xA3,0xFC,0x37,0x15,0xDD,0x47,0x38,0x82,0xB9,0xA3,0x38,0xEF,0x7C,0xF4,0x37,0xD3,0xDE,0x86,0x38,0xE3,0x59,0xBE,0x38,0x50,0x27,0x55,0x38,0x21,0x1A,0x42,0x37,0x48,0x55,0xA1,0x37,0x35,0x95,0x99,0x37,0x56,0x44,0xF1,0x36,0x97,0x87,0x30,0x38,0xB8,0x3E,0x5B,0x38,0xC8,0x71,0x52,0x37,0x17,0x7C,0x26,0x37,0x9C,0x35,0x3E,0x37,0xA3,0x44,0xD8,0x37,0x40,0x94,0x32,0x38,0xA9,0xC2,0x50,0x38,0xE6,0x34,0x8D,0x38,0xA9,0xAF,0x9C,0x38,0x2A,0x2D,0x33,0x38,0x9A,0xB3,0x3C,0x38,0x8D,0x96,0x12,0x38,0x55,0xB8,0x02,0x38,0x45,0x4F,0x42,0x37,0x1A,0x42,0x97,0x37,0x8B,0xE5,0xD6,0x37,0x90,0xDF,0x64,0x37,0x70,0x42,0x03,0x38,0x47,0x20,0x15,0x38,0x3A,0xBB,0x3A,0x38,0x10,0x49,0xDB,0x37,0x8A,0xF3,0xCC,0x37,0x55,0x75,0x10,0x38,0xCE,0x13,0x8E,0x38,0x82,0x0A,0x39,0x38,0x5D,0x46,0x51,0x38,0xD8,0xFB,0xA6,0x38,0x19,0xDC,0x6C,0x38,0xA5,0xE0,0x80,0x38,0x9C,0x7D,0x52,0x38,0x72,0x5B,0x4B,0x38,0xE0,0xFC,0x62,0x38,0xFE,0xA3,0xA8,0x38,0xF8,0xC0,0x9F,0x38,0xE5,0x64,0x6A,0x38,0xB7,0x4E,0x68,0x38,0x6F,0xAD,0xCC,0x37,0xF4,0xAB,0xC8,0x36,0xB5,0xA7,0x90,0x38,0x2F,0xC8,0xAF,0x38,0x06,0x79,0x6F,0x38,0x7C,0x34,0x93,0x38,0x32,0x5B,0xF0,0x38,0x80,0xF4,0x26,0x39,0x5E,0x54,0xBD,0x38,0x7C,0x2B,0x5F,0x38,0x40,0xFF,0x6A,0x38,0x8B,0x1D,0xE3,0x37,0xDA,0x91,0x8B,0x37,0xD8,0x48,0x24,0x38,0x2C,0xC4,0xDC,0x37,0xC6,0xF0,0x39,0x38,0x79,0xBC,0xBD,0x37,0x03,0x93,0x82,0x38,0xCD,0x84,0x09,0x39,0xCC,0xBE,0xCD,0x38,0x74,0x68,0x02,0x38,0x25,0x6E,0x2E,0x38,0x98,0x59,0x23,0x38,0x3A,0x30,0x20,0x38,0xB8,0xD6,0x87,0x38,0x8B,0xBF,0x5D,0x38,0xC2,0x24,0xAF,0x37,0xBC,0x00,0x5B,0x38,0xDF,0x76,0x85,0x38,0x1D,0x9E,0x26,0x38,0x04,0x09,0xC4,0x38,0xA3,0x4C,0xEB,0x38,0x2D,0xD6,0xA7,0x38,0x54,0xCB,0xA7,0x38,0xF6,0x80,0xA3,0x38,0x2E,0x5A,0x30,0x37,0xB1,0xBC,0x83,0x38,0xA2,0xE3,0x93,0x38,0x18,0xEB,0xE7,0x37,0x3C,0x19,0xC6,0x37,0xEB,0x25,0xFC,0x37,0xE3,0x2A,0x68,0x38,0xF3,0x80,0xE4,0x37,0xE0,0xA2,0x02,0x38,0x6F,0x7F,0x12,0x38,0x1A,0x6B,0x9B,0x37,0x12,0x3C,0x8A,0x38,0x18,0x1A,0x60,0x38,0x4A,0x1D,0x5E,0x37,0x90,0xE3,0x34,0x38,0x1D,0xD2,0xB1,0x38,0x4D,0x39,0x2C,0x38,0x75,0x01,0xA7,0x37,0xD9,0x77,0x39,0x38,0xDD,0xB9,0x88,0x38,0x55,0x50,0x80,0x38,0x6B,0xD4,0x35,0x38,0x7B,0xA8,0x0D,0x38,0xBB,0x81,0xAF,0x38,0xC1,0x44,0xB5,0x38,0xC1,0x04,0x65,0x38,0x80,0x0E,0x9A,0x38,0x08,0xC6,0xCE,0x38,0xC7,0x06,0x6F,0x38,0x0D,0x5C,0xEC,0x36,0xA9,0x4F,0x5A,0x38,0x6B,0x9E,0xEF,0x37,0x0C,0xBD,0x8F,0x38,0x17,0xC7,0xA3,0x38,0x50,0x00,0x10,0x38,0x6C,0xF9,0xF4,0x37,0x7B,0xF5,0xA7,0x38,0x5D,0x3D,0xCA,0x38,0xBF,0x72,0x01,0x39,0x8A,0x5D,0xDF,0x38,0x3B,0x1B,0xAD,0x38,0x60,0xE5,0xBE,0x38,0x48,0x19,0xCC,0x38,0x11,0x47,0x80,0x38,0x72,0xD2,0xCE,0x37,0x12,0x75,0x38,0x37,0xB7,0x6E,0x26,0x38,0xB3,0x7A,0x02,0x38,0x81,0x34,0xEF,0x37,0x55,0xF9,0x70,0x38,0xB4,0x17,0x97,0x38,0x50,0x8F,0x91,0x38,0x54,0xC4,0xEC,0x37,0x36,0x96,0x84,0x38,0x71,0x8A,0x1D,0x38,0xB6,0xFB,0xD7,0x37,0xB3,0x1B,0xAE,0x37,0xF5,0x76,0x0B,0x38,0xAA,0x0E,0x11,0x38,0x38,0xC3,0x61,0x38,0x55,0x7A,0xED,0x37,0x9E,0xD6,0x9F,0x38,0x96,0x61,0x87,0x38,0xA7,0x45,0x92,0x38,0xB1,0x6B,0x67,0x38,0x71,0xF3,0x28,0x38,0x59,0x73,0xBC,0x38,0x5A,0xF9,0x9F,0x38,0x86,0x7C,0xA0,0x38,0x07,0x2C,0xD1,0x38,0x80,0xA3,0x9F,0x38,0x85,0x32,0x0D,0x38,0x98,0x82,0x93,0x38,0x88,0x34,0x4F,0x38,0xEA,0x4A,0x92,0x37,0x38,0x01,0x99,0x37,0xB5,0x04,0x94,0x37,0x8A,0xE4,0xEC,0x37,0x4B,0xA3,0x05,0x38,0xCE,0xE2,0x3E,0x38,0x4E,0x55,0x1C,0x38,0x7D,0x53,0xB0,0x38,0x40,0x34,0xF1,0x37,0x60,0x53,0x1B,0x38,0xB9,0x9E,0x2B,0x38,0x15,0xD6,0x89,0x38,0x9F,0x19,0xC5,0x38,0x12,0xA9,0x6F,0x38,0x5F,0x63,0x3B,0x38,0x03,0x5C,0x16,0x38,0x11,0x65,0x0D,0x38,0xF2,0xAD,0x49,0x38,0x53,0x2B,0x10,0x38,0x07,0x97,0xC0,0x37,0x6D,0x99,0xDF,0x37,0x24,0x73,0x36,0x38,0x10,0xBD,0x48,0x38,0xBF,0x96,0xF7,0x37,0x06,0x1D,0x7B,0x37,0x1E,0x04,0xA6,0x38,0x35,0xF5,0xBF,0x38,0x6E,0x55,0xBA,0x38,0xF9,0xC9,0x31,0x38,0x9E,0xFE,0x90,0x37,0xAE,0xE9,0x90,0x38,0x6C,0xFD,0xE2,0x38,0xEA,0x1F,0x91,0x38,0x29,0x95,0x88,0x38,0x42,0x05,0x41,0x38,0xD2,0x90,0x24,0x38,0x9E,0xCC,0x23,0x38,0x23,0x36,0x3E,0x37,0x89,0xA6,0x9E,0x37,0x4C,0x95,0x96,0x37,0xB0,0xA1,0xB6,0x37,0xB8,0x44,0x4E,0x38,0xD3,0x9C,0x92,0x37,0xD7,0xB9,0x30,0x38,0x94,0xF9,0x47,0x38,0xFE,0x46,0x4D,0x38,0x95,0xDE,0x44,0x38,0x95,0x10,0xD8,0x37,0x52,0x02,0x2D,0x38,0x8B,0x03,0x1B,0x38,0xF3,0x8B,0x13,0x38,0x8F,0x36,0x38,0x37,0x0C,0x6A,0x35,0x36,0x2D,0xC8,0xA4,0x37,0x3E,0x16,0x37,0x38,0x02,0x8A,0x9F,0x38,0xC7,0xDA,0xF6,0x37,0x88,0x19,0x2C,0x38,0xC1,0x40,0xD1,0x36,0x95,0x34,0x30,0x38,0x36,0x5F,0xBD,0x37,0x2D,0x7E,0x23,0x38,0x75,0xCD,0x15,0x38,0xC4,0xA1,0x38,0x38,0x9F,0x97,0x27,0x38,0x5D,0xCC,0x95,0x37,0x64,0x2E,0xCB,0x37,0xAB,0x90,0xAD,0x37,0x60,0x24,0x60,0x38,0xD2,0x58,0x42,0x38,0x6B,0x12,0x3B,0x37,0x09,0x3E,0xE6,0x37,0xFC,0x8A,0xE2,0x37,0x84,0x87,0x84,0x36,0xCF,0xC7,0xD3,0x37,0x49,0x55,0xD6,0x37,0x54,0x30,0xF8,0x37,0x3C,0xA9,0x2D,0x38,0xF0,0x34,0x18,0x38,0x8E,0x8A,0x17,0x38,0x3C,0x00,0x83,0x38,0x7C,0x08,0x09,0x38,0x0F,0x55,0x72,0x38,0x14,0xD3,0x75,0x38,0x2A,0x9C,0xB3,0x37,0x5C,0xC0,0x59,0x37,0x45,0xC8,0xE0,0x37,0x81,0xE0,0xCF,0x37,0x0E,0x9E,0x1A,0x37,0xD0,0x3E,0x8B,0x37,0x4B,0xBA,0x83,0x37,0xF7,0x2D,0x80,0x37,0xD8,0x11,0xAE,0x37,0xD4,0xDE,0xF7,0x37,0xB2,0x54,0xFB,0x37,0x76,0x02,0xB9,0x37,0x5D,0x9F,0x8A,0x37,0x58,0x36,0x10,0x38,0x69,0xF9,0x04,0x37,0xCD,0xF0,0x42,0x37,0x57,0x03,0xB4,0x37,0xA2,0x6A,0x46,0x37,0xE6,0x8F,0x5C,0x37,0x8F,0x96,0xD9,0x36,0x64,0x11,0x93,0x37,0x3E,0xE2,0xB0,0x37,0x37,0x75,0x9A,0x37,0x1B,0x57,0x85,0x37,0xD2,0xA6,0xAA,0x37,0x92,0xA4,0x87,0x37,0x9D,0xEA,0xE3,0x37,0x49,0xF9,0x10,0x37,0x9D,0x06,0xB9,0x37,0x4D,0xF4,0xFB,0x37,0xA2,0x6A,0x99,0x36,0x57,0x03,0xA2,0x37,0x22,0x91,0xA3,0x37,0x31,0x78,0xB5,0x37,0x67,0xDB,0xBD,0x36,0x53,0x10,0xAA,0x37,0x46,0xFD,0x29,0x37,0x0F,0x05,0x6A,0x36,0x39,0xBA,0x81,0x37,0x4F,0x34,0xAE,0x37,0x0D,0x65,0x9A,0x37,0x35,0x13,0x0E,0x38,0xD9,0x2D,0xCB,0x37,0xD9,0x47,0x19,0x38,0x2C,0x40,0x2D,0x37,0xEF,0x20,0x6E,0x36,0x6B,0x83,0x3E,0x37,0x4D,0x46,0x29,0x35
|
|
};
|
|
memcpy(smp.bytes, b, 4096);
|
|
uint32_t sample_count = 2048;
|
|
uint32_t bins_count = 1024;
|
|
|
|
// Peaks go here
|
|
struct peak peaks[10];
|
|
|
|
// Magic * *# @ * / +
|
|
float floor = pkdetect(&peaks[0], 10, smp.floats, bins_count);
|
|
|
|
// Show the results...
|
|
float bin = 21.7;
|
|
for (int i = 0; i < 10; i++) {
|
|
printf("pk %d ... %f @ %f Hz (weight %f)\r\n", i,
|
|
peaks[i].magnitude,
|
|
peaks[i].position*bin,
|
|
peaks[i].weight);
|
|
}
|
|
|
|
printf("Noise power per bin is %f\r\n", floor);
|
|
|
|
return 0;
|
|
}
|
|
|