/*
 * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
 *
 * This file is part of PortaPack.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, 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; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 */

#include "proc_wideband_spectrum.hpp"

#include "event_m4.hpp"

#include "i2s.hpp"
using namespace lpc43xx;

#include <cstdint>
#include <cstddef>

#include <array>

// numpy.array(numpy.round(scipy.signal.windows.blackmanharris(1024) * 32767), dtype=numpy.int16)
static constexpr std::array<int16_t, 1024> window_blackmanharris_1024 { {
    2,     2,     2,     2,     2,     2,     3,     3,
    3,     3,     4,     4,     5,     5,     5,     6,
    7,     7,     8,     8,     9,    10,    11,    12,
   13,    14,    15,    16,    17,    18,    19,    20,
   22,    23,    24,    26,    27,    29,    31,    32,
   34,    36,    38,    40,    42,    44,    46,    48,
   51,    53,    56,    58,    61,    64,    67,    70,
   73,    76,    79,    82,    86,    89,    93,    97,
  100,   104,   109,   113,   117,   122,   126,   131,
  136,   141,   146,   151,   156,   162,   168,   173,
  179,   186,   192,   198,   205,   212,   219,   226,
  233,   241,   249,   256,   265,   273,   281,   290,
  299,   308,   317,   327,   337,   347,   357,   367,
  378,   389,   400,   411,   423,   435,   447,   459,
  472,   485,   498,   512,   526,   540,   554,   569,
  584,   599,   614,   630,   646,   663,   680,   697,
  714,   732,   750,   769,   788,   807,   827,   846,
  867,   887,   908,   930,   952,   974,   996,  1019,
 1043,  1066,  1091,  1115,  1140,  1166,  1192,  1218,
 1245,  1272,  1299,  1327,  1356,  1385,  1414,  1444,
 1475,  1506,  1537,  1569,  1601,  1634,  1667,  1701,
 1735,  1770,  1805,  1841,  1878,  1915,  1952,  1990,
 2029,  2068,  2107,  2147,  2188,  2229,  2271,  2314,
 2357,  2400,  2444,  2489,  2534,  2580,  2627,  2674,
 2721,  2770,  2819,  2868,  2918,  2969,  3020,  3072,
 3125,  3178,  3232,  3287,  3342,  3398,  3454,  3511,
 3569,  3628,  3687,  3746,  3807,  3868,  3930,  3992,
 4055,  4119,  4183,  4249,  4314,  4381,  4448,  4516,
 4585,  4654,  4724,  4794,  4866,  4938,  5010,  5084,
 5158,  5233,  5308,  5385,  5462,  5539,  5618,  5697,
 5776,  5857,  5938,  6020,  6103,  6186,  6270,  6355,
 6440,  6526,  6613,  6700,  6789,  6878,  6967,  7058,
 7149,  7240,  7333,  7426,  7520,  7614,  7710,  7805,
 7902,  7999,  8097,  8196,  8295,  8395,  8496,  8597,
 8699,  8802,  8905,  9009,  9114,  9219,  9325,  9431,
 9539,  9646,  9755,  9864,  9974, 10084, 10195, 10306,
10419, 10531, 10645, 10759, 10873, 10988, 11104, 11220,
11337, 11454, 11572, 11691, 11810, 11929, 12049, 12170,
12291, 12412, 12534, 12657, 12780, 12903, 13027, 13152,
13277, 13402, 13528, 13654, 13781, 13908, 14035, 14163,
14291, 14420, 14549, 14678, 14808, 14938, 15068, 15199,
15330, 15461, 15593, 15725, 15857, 15989, 16122, 16255,
16388, 16522, 16655, 16789, 16923, 17058, 17192, 17327,
17461, 17596, 17731, 17867, 18002, 18137, 18273, 18408,
18544, 18680, 18815, 18951, 19087, 19223, 19358, 19494,
19630, 19765, 19901, 20037, 20172, 20308, 20443, 20578,
20713, 20848, 20983, 21118, 21252, 21386, 21520, 21654,
21788, 21921, 22054, 22187, 22320, 22452, 22584, 22716,
22847, 22978, 23109, 23239, 23369, 23499, 23628, 23757,
23885, 24013, 24140, 24267, 24394, 24520, 24645, 24770,
24894, 25018, 25142, 25264, 25386, 25508, 25629, 25749,
25869, 25988, 26106, 26224, 26341, 26457, 26573, 26688,
26802, 26915, 27028, 27139, 27251, 27361, 27470, 27579,
27687, 27794, 27900, 28005, 28109, 28213, 28315, 28417,
28518, 28617, 28716, 28814, 28911, 29007, 29102, 29196,
29288, 29380, 29471, 29561, 29650, 29737, 29824, 29909,
29994, 30077, 30159, 30240, 30320, 30399, 30477, 30553,
30628, 30702, 30775, 30847, 30918, 30987, 31055, 31122,
31188, 31252, 31315, 31377, 31438, 31497, 31555, 31612,
31667, 31721, 31774, 31826, 31876, 31925, 31972, 32019,
32064, 32107, 32149, 32190, 32230, 32268, 32304, 32340,
32374, 32406, 32438, 32467, 32496, 32523, 32548, 32573,
32595, 32617, 32637, 32655, 32672, 32688, 32702, 32715,
32727, 32737, 32745, 32753, 32758, 32763, 32765, 32767,
32767, 32765, 32763, 32758, 32753, 32745, 32737, 32727,
32715, 32702, 32688, 32672, 32655, 32637, 32617, 32595,
32573, 32548, 32523, 32496, 32467, 32438, 32406, 32374,
32340, 32304, 32268, 32230, 32190, 32149, 32107, 32064,
32019, 31972, 31925, 31876, 31826, 31774, 31721, 31667,
31612, 31555, 31497, 31438, 31377, 31315, 31252, 31188,
31122, 31055, 30987, 30918, 30847, 30775, 30702, 30628,
30553, 30477, 30399, 30320, 30240, 30159, 30077, 29994,
29909, 29824, 29737, 29650, 29561, 29471, 29380, 29288,
29196, 29102, 29007, 28911, 28814, 28716, 28617, 28518,
28417, 28315, 28213, 28109, 28005, 27900, 27794, 27687,
27579, 27470, 27361, 27251, 27139, 27028, 26915, 26802,
26688, 26573, 26457, 26341, 26224, 26106, 25988, 25869,
25749, 25629, 25508, 25386, 25264, 25142, 25018, 24894,
24770, 24645, 24520, 24394, 24267, 24140, 24013, 23885,
23757, 23628, 23499, 23369, 23239, 23109, 22978, 22847,
22716, 22584, 22452, 22320, 22187, 22054, 21921, 21788,
21654, 21520, 21386, 21252, 21118, 20983, 20848, 20713,
20578, 20443, 20308, 20172, 20037, 19901, 19765, 19630,
19494, 19358, 19223, 19087, 18951, 18815, 18680, 18544,
18408, 18273, 18137, 18002, 17867, 17731, 17596, 17461,
17327, 17192, 17058, 16923, 16789, 16655, 16522, 16388,
16255, 16122, 15989, 15857, 15725, 15593, 15461, 15330,
15199, 15068, 14938, 14808, 14678, 14549, 14420, 14291,
14163, 14035, 13908, 13781, 13654, 13528, 13402, 13277,
13152, 13027, 12903, 12780, 12657, 12534, 12412, 12291,
12170, 12049, 11929, 11810, 11691, 11572, 11454, 11337,
11220, 11104, 10988, 10873, 10759, 10645, 10531, 10419,
10306, 10195, 10084,  9974,  9864,  9755,  9646,  9539,
 9431,  9325,  9219,  9114,  9009,  8905,  8802,  8699,
 8597,  8496,  8395,  8295,  8196,  8097,  7999,  7902,
 7805,  7710,  7614,  7520,  7426,  7333,  7240,  7149,
 7058,  6967,  6878,  6789,  6700,  6613,  6526,  6440,
 6355,  6270,  6186,  6103,  6020,  5938,  5857,  5776,
 5697,  5618,  5539,  5462,  5385,  5308,  5233,  5158,
 5084,  5010,  4938,  4866,  4794,  4724,  4654,  4585,
 4516,  4448,  4381,  4314,  4249,  4183,  4119,  4055,
 3992,  3930,  3868,  3807,  3746,  3687,  3628,  3569,
 3511,  3454,  3398,  3342,  3287,  3232,  3178,  3125,
 3072,  3020,  2969,  2918,  2868,  2819,  2770,  2721,
 2674,  2627,  2580,  2534,  2489,  2444,  2400,  2357,
 2314,  2271,  2229,  2188,  2147,  2107,  2068,  2029,
 1990,  1952,  1915,  1878,  1841,  1805,  1770,  1735,
 1701,  1667,  1634,  1601,  1569,  1537,  1506,  1475,
 1444,  1414,  1385,  1356,  1327,  1299,  1272,  1245,
 1218,  1192,  1166,  1140,  1115,  1091,  1066,  1043,
 1019,   996,   974,   952,   930,   908,   887,   867,
  846,   827,   807,   788,   769,   750,   732,   714,
  697,   680,   663,   646,   630,   614,   599,   584,
  569,   554,   540,   526,   512,   498,   485,   472,
  459,   447,   435,   423,   411,   400,   389,   378,
  367,   357,   347,   337,   327,   317,   308,   299,
  290,   281,   273,   265,   256,   249,   241,   233,
  226,   219,   212,   205,   198,   192,   186,   179,
  173,   168,   162,   156,   151,   146,   141,   136,
  131,   126,   122,   117,   113,   109,   104,   100,
   97,    93,    89,    86,    82,    79,    76,    73,
   70,    67,    64,    61,    58,    56,    53,    51,
   48,    46,    44,    42,    40,    38,    36,    34,
   32,    31,    29,    27,    26,    24,    23,    22,
   20,    19,    18,    17,    16,    15,    14,    13,
   12,    11,    10,     9,     8,     8,     7,     7,
    6,     5,     5,     5,     4,     4,     3,     3,
    3,     3,     2,     2,     2,     2,     2,     2,
} };

void WidebandSpectrum::execute(buffer_c8_t buffer) {
	sample_count += buffer.count;
	if( sample_count > 400000 ) {
		sample_count -= 400000;

		if( channel_spectrum_request_update == false ) {
			channel_spectrum_request_update = true;

      constexpr int32_t k = 128 * 4 * 8;
			for(size_t i=0; i<channel_spectrum.size(); i++) {
				int32_t real = 0;
				int32_t imag = 0;
				real += buffer.p[i +   0].real() * window_blackmanharris_1024[i +   0];
				imag += buffer.p[i +   0].imag() * window_blackmanharris_1024[i +   0];
				real += buffer.p[i + 256].real() * window_blackmanharris_1024[i + 256];
				imag += buffer.p[i + 256].imag() * window_blackmanharris_1024[i + 256];
				real += buffer.p[i + 512].real() * window_blackmanharris_1024[i + 512];
				imag += buffer.p[i + 512].imag() * window_blackmanharris_1024[i + 512];
				real += buffer.p[i + 768].real() * window_blackmanharris_1024[i + 768];
				imag += buffer.p[i + 768].imag() * window_blackmanharris_1024[i + 768];
				channel_spectrum[i].real(real / k);
				channel_spectrum[i].imag(imag / k);
			}

			channel_spectrum_sampling_rate = buffer.sampling_rate;
			channel_filter_pass_frequency = 0;
			channel_filter_stop_frequency = 0;
			events_flag(EVT_MASK_SPECTRUM);
		}
	}
		
	i2s::i2s0::tx_mute();
}