1062 lines
34 KiB
C++
1062 lines
34 KiB
C++
/*
|
|
* This file is part of libsidplayfp, a SID player engine.
|
|
*
|
|
* Copyright 2013-2016 Leandro Nini <drfiemost@users.sourceforge.net>
|
|
* Copyright 2007-2010 Antti Lankila
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <cassert>
|
|
#include <ctime>
|
|
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <limits>
|
|
#include <random>
|
|
|
|
#include "parameters.h"
|
|
|
|
|
|
static const float EPSILON = 1e-3;
|
|
|
|
#ifdef __MINGW32__
|
|
// MinGW's std::random_device is a PRNG seeded with a constant value
|
|
// so we use system time as a random seed.
|
|
#include <chrono>
|
|
inline long getSeed()
|
|
{
|
|
using namespace std::chrono;
|
|
const auto now_ms = time_point_cast<std::chrono::milliseconds>(system_clock::now());
|
|
return now_ms.time_since_epoch().count();
|
|
}
|
|
#else
|
|
inline long getSeed()
|
|
{
|
|
return std::random_device{}();
|
|
}
|
|
#endif
|
|
|
|
static std::default_random_engine prng(getSeed());
|
|
static std::normal_distribution<> normal_dist(1.0, 0.001);
|
|
static std::normal_distribution<> normal_dist2(0.5, 0.2);
|
|
|
|
static double GetRandomValue()
|
|
{
|
|
return normal_dist(prng);
|
|
}
|
|
|
|
static float GetNewRandomValue()
|
|
{
|
|
return static_cast<float>(normal_dist2(prng));
|
|
}
|
|
|
|
static void Optimize(const ref_vector_t &reference, int wave, char chip)
|
|
{
|
|
Parameters bestparams;
|
|
|
|
/*
|
|
* The score here reported is the acoustic error.
|
|
* In parentheses the number of mispredicted bits
|
|
* on a total of 32768.
|
|
*/
|
|
switch (chip)
|
|
{
|
|
// 6581 R2
|
|
case 'B':
|
|
switch (wave)
|
|
{
|
|
case 3: // ST
|
|
// current score 152 (57)
|
|
bestparams.threshold = 0.988547385f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 5.58014059f;
|
|
bestparams.distance2 = 5.4269886f;
|
|
bestparams.stmix = 0.806023061f;
|
|
break;
|
|
case 5: // PT
|
|
// current score 2872 (154)
|
|
bestparams.threshold = 0.984531879f;
|
|
bestparams.pulsestrength = 3.03670526f;
|
|
bestparams.distance1 = 0.99342072f;
|
|
bestparams.distance2 = 1.11435139f;
|
|
break;
|
|
case 6: // PS
|
|
// current score 0
|
|
bestparams.threshold = 0.906437993f;
|
|
bestparams.pulsestrength = 2.11317873f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.130663797f;
|
|
bestparams.distance2 = 0.0835102722f;
|
|
break;
|
|
case 7: // PST
|
|
// current score 0
|
|
bestparams.threshold = 0.924151242f;
|
|
bestparams.pulsestrength = 1.16428149f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.920196056f;
|
|
bestparams.distance2 = 1.07491302f;
|
|
bestparams.stmix = 0.793505609f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2 (odd)
|
|
case 'C':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 2948 (446)
|
|
bestparams.threshold = 0.881458f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.93176f;
|
|
bestparams.stmix = 0.596385f;
|
|
break;
|
|
case 5:
|
|
// current score 10992 (367)
|
|
bestparams.threshold = 0.933451474f;
|
|
bestparams.pulsestrength = 3.04320669f;
|
|
bestparams.distance1 = 1.01660681f;
|
|
bestparams.distance2 = 1.19298482f;
|
|
break;
|
|
case 6:
|
|
// current score 5532 (298)
|
|
bestparams.threshold = 0.906489253f;
|
|
bestparams.pulsestrength = 3.24875951f;
|
|
bestparams.topbit = 1.57458532f; // ???
|
|
bestparams.distance1 = 0.101274647f;
|
|
bestparams.distance2 = 0.188963249f;
|
|
break;
|
|
case 7:
|
|
// current score 850 (60)
|
|
bestparams.threshold = 0.919113517f;
|
|
bestparams.pulsestrength = 1.62892509f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.21794045f;
|
|
bestparams.distance2 = 1.2279855f;
|
|
bestparams.stmix = 0.896797657f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2 (odd)
|
|
case 'D':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 1958 (302)
|
|
bestparams.threshold = 0.861116648f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.582165f;
|
|
bestparams.distance2 = 2.23844433f;
|
|
bestparams.stmix = 0.53945446f;
|
|
break;
|
|
case 5:
|
|
// current score 9924 (426)
|
|
bestparams.threshold = 0.927432716f;
|
|
bestparams.pulsestrength = 2.37539339f;
|
|
bestparams.distance1 = 1.00424087f;
|
|
bestparams.distance2 = 1.2061156f;
|
|
break;
|
|
case 6:
|
|
// current score 12332 (857)
|
|
bestparams.threshold = 0.883725405f;
|
|
bestparams.pulsestrength = 1.86024225f;
|
|
bestparams.topbit = 1.12501097f; // ???
|
|
bestparams.distance1 = 0.0956423283f;
|
|
bestparams.distance2 = 0.457357466f;
|
|
break;
|
|
case 7:
|
|
// current score 258 (64)
|
|
bestparams.threshold = 0.91076839f;
|
|
bestparams.pulsestrength = 1.2814858f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.17647922f;
|
|
bestparams.distance2 = 1.18998444f;
|
|
bestparams.stmix = 0.771969795f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'E':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 297 (98)
|
|
bestparams.threshold = 0.989183f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 5.75852f;
|
|
bestparams.stmix = 0.800831f;
|
|
break;
|
|
case 5:
|
|
// current score 3348 (146)
|
|
bestparams.threshold = 0.91292721f;
|
|
bestparams.pulsestrength = 1.83235359f;
|
|
bestparams.distance1 = 1.12143898f;
|
|
bestparams.distance2 = 1.12768865f;
|
|
break;
|
|
case 6:
|
|
// current score 8 (6)
|
|
bestparams.threshold = 0.91496712f;
|
|
bestparams.pulsestrength = 2.28155446f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.122848086f;
|
|
bestparams.distance2 = 0.0706237406f;
|
|
break;
|
|
case 7:
|
|
// current score 0
|
|
bestparams.threshold = 0.970328987f;
|
|
bestparams.pulsestrength = 1.75902855f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.21010804f;
|
|
bestparams.distance2 = 1.269436f;
|
|
bestparams.stmix = 0.983422756f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'F':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 240 (64)
|
|
bestparams.threshold = 0.99254179f;
|
|
bestparams.topbit = 0.001f;
|
|
bestparams.distance1 = 7.18324232f;
|
|
bestparams.distance2 = 6.00581455f;
|
|
bestparams.stmix = 0.841992021f;
|
|
break;
|
|
case 5:
|
|
// current score 3008 (57)
|
|
bestparams.threshold = 0.959230483f;
|
|
bestparams.pulsestrength = 2.74101543f;
|
|
bestparams.distance1 = 1.00775206f;
|
|
bestparams.distance2 = 1.11247838f;
|
|
break;
|
|
case 6:
|
|
// current score 432 (12)
|
|
bestparams.threshold = 0.902768612f;
|
|
bestparams.pulsestrength = 2.06190324f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.150018558f;
|
|
bestparams.distance2 = 0.102936305f;
|
|
break;
|
|
case 7:
|
|
// current score 2 (2)
|
|
bestparams.threshold = 0.896021485f;
|
|
bestparams.pulsestrength = 0.865568995f;
|
|
bestparams.topbit = 0.002f;
|
|
bestparams.distance1 = 0.98756659f;
|
|
bestparams.distance2 = 1.17235816f;
|
|
bestparams.stmix = 0.547210157f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2 (odd)
|
|
case 'G':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 1689 (280)
|
|
bestparams.threshold = 0.90251f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.9147f;
|
|
bestparams.distance2 = 1.6747f;
|
|
bestparams.stmix = 0.62376f;
|
|
break;
|
|
case 5:
|
|
// current score 6128 (130)
|
|
bestparams.threshold = 0.93088f;
|
|
bestparams.pulsestrength = 2.4843f;
|
|
bestparams.distance1 = 1.0353f;
|
|
bestparams.distance2 = 1.1484f;
|
|
break;
|
|
case 6:
|
|
// current score 10639 (569)
|
|
bestparams.threshold = 0.912298322f;
|
|
bestparams.pulsestrength = 2.32252741f;
|
|
bestparams.topbit = 1.10538983f; // ???
|
|
bestparams.distance1 = 0.0537932068f;
|
|
bestparams.distance2 = 0.252674758f;
|
|
break;
|
|
case 7:
|
|
// current score 64 (2)
|
|
bestparams.threshold = 0.91f;
|
|
bestparams.pulsestrength = 1.192f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.0169f;
|
|
bestparams.distance2 = 1.2f;
|
|
bestparams.stmix = 0.637f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'H':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 230 (78)
|
|
bestparams.threshold = 0.97577709f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 3.35368633f;
|
|
bestparams.distance2 = 2.60800719f;
|
|
bestparams.stmix = 0.670109689f;
|
|
break;
|
|
case 5:
|
|
// current score 2744 (91)
|
|
bestparams.threshold = 0.919414461f;
|
|
bestparams.pulsestrength = 1.49266505f;
|
|
bestparams.distance1 = 1.12526083f;
|
|
bestparams.distance2 = 1.15659571f;
|
|
break;
|
|
case 6:
|
|
// current score 360 (30)
|
|
bestparams.threshold = 0.941394627f;
|
|
bestparams.pulsestrength = 2.23991108f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.149554357f;
|
|
bestparams.distance2 = 0.150783867f;
|
|
break;
|
|
case 7:
|
|
// current score 0
|
|
bestparams.threshold = 0.98f;
|
|
bestparams.pulsestrength = 2.f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.1f;
|
|
bestparams.stmix = 0.91f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'I':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 184 (68)
|
|
bestparams.threshold = 0.982668161f;
|
|
bestparams.topbit = 0.001f;
|
|
bestparams.distance1 = 4.43093681f;
|
|
bestparams.distance2 = 4.43528938f;
|
|
bestparams.stmix = 0.775906205f;
|
|
break;
|
|
case 5:
|
|
// current score 6847 (171)
|
|
bestparams.threshold = 0.943752468f;
|
|
bestparams.pulsestrength = 2.28453493f;
|
|
bestparams.distance1 = 1.03244841f;
|
|
bestparams.distance2 = 1.17106056f;
|
|
break;
|
|
case 6:
|
|
// current score 422 (17)
|
|
bestparams.threshold = 0.894735754f;
|
|
bestparams.pulsestrength = 1.81871581f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.0912446976f;
|
|
bestparams.distance2 = 0.101162158f;
|
|
break;
|
|
case 7:
|
|
// current score 16 (6)
|
|
bestparams.threshold = 0.942962408f;
|
|
bestparams.pulsestrength = 1.57235372f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.1614747f;
|
|
bestparams.distance2 = 1.22249365f;
|
|
bestparams.stmix = 0.581929862f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'J':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 148 (61)
|
|
bestparams.threshold = 0.979544f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 3.98271f;
|
|
bestparams.stmix = 0.775023f;
|
|
break;
|
|
case 5:
|
|
// current score 1540 (102)
|
|
bestparams.threshold = 0.9079f;
|
|
bestparams.pulsestrength = 1.72749f;
|
|
bestparams.distance1 = 1.12017f;
|
|
bestparams.distance2 = 1.10793f;
|
|
break;
|
|
case 6:
|
|
// current score 0
|
|
bestparams.threshold = 0.905734479f;
|
|
bestparams.pulsestrength = 1.99118233f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.0996442288f;
|
|
bestparams.distance2 = 0.0730706826f;
|
|
break;
|
|
case 7:
|
|
// current score 0
|
|
bestparams.threshold = 0.95248f;
|
|
bestparams.pulsestrength = 1.51f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.07153f;
|
|
bestparams.distance2 = 1.09353f;
|
|
bestparams.stmix = 1.f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'K':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 1299 (150)
|
|
bestparams.threshold = 0.931232035f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.78504324f;
|
|
bestparams.distance2 = 2.21891737f;
|
|
bestparams.stmix = 0.692269444f;
|
|
break;
|
|
case 5:
|
|
// current score 8086 (386)
|
|
bestparams.threshold = 1.f;
|
|
bestparams.pulsestrength = 3.06605577f;
|
|
bestparams.distance1 = 0.981742382f;
|
|
bestparams.distance2 = 1.1532563f;
|
|
break;
|
|
case 6:
|
|
// current score 2608 (140)
|
|
bestparams.threshold = 0.898440778f;
|
|
bestparams.pulsestrength = 1.99839222f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.108322836f;
|
|
bestparams.distance2 = 0.096527569f;
|
|
break;
|
|
case 7:
|
|
// current score 102 (10)
|
|
bestparams.threshold = 0.931423545f;
|
|
bestparams.pulsestrength = 1.41654074f;
|
|
bestparams.topbit = 0.01f;
|
|
bestparams.distance1 = 1.14805245f;
|
|
bestparams.distance2 = 1.35858405f;
|
|
bestparams.stmix = 0.48002857f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'L':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 1356 (109)
|
|
bestparams.threshold = 0.983135f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 4.62089f;
|
|
bestparams.stmix = 0.778836f;
|
|
break;
|
|
case 5:
|
|
// current score 6098 (134)
|
|
bestparams.threshold = 0.924762011f;
|
|
bestparams.pulsestrength = 2.37176347f;
|
|
bestparams.distance1 = 1.04673755f;
|
|
bestparams.distance2 = 1.16099727f;
|
|
break;
|
|
case 6:
|
|
// current score 1534 (107)
|
|
bestparams.threshold = 0.927221477f;
|
|
bestparams.pulsestrength = 2.94884133f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.0910025164f;
|
|
bestparams.distance2 = 0.132933453f;
|
|
break;
|
|
case 7:
|
|
// current score 102 (16)
|
|
bestparams.threshold = 0.941179f;
|
|
bestparams.pulsestrength = 1.65307f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.22544f;
|
|
bestparams.stmix = 0.748047f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'M':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 352 (106)
|
|
bestparams.threshold = 0.938881f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 2.07118f;
|
|
bestparams.stmix = 0.579197f;
|
|
break;
|
|
case 5:
|
|
// current score 2434 (139)
|
|
bestparams.threshold = 0.906191885f;
|
|
bestparams.pulsestrength = 1.59146726f;
|
|
bestparams.distance1 = 1.127689f;
|
|
bestparams.distance2 = 1.1314106f;
|
|
break;
|
|
case 6:
|
|
// current score 0
|
|
bestparams.threshold = 0.893231869f;
|
|
bestparams.pulsestrength = 1.70082629f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.111504503f;
|
|
bestparams.distance2 = 0.0748674423f;
|
|
break;
|
|
case 7:
|
|
// current score 0
|
|
bestparams.threshold = 0.979779f;
|
|
bestparams.pulsestrength = 2.03635f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.30189f;
|
|
bestparams.stmix = 0.923735f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R2
|
|
case 'N':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 662 (104)
|
|
bestparams.threshold = 0.981390178f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 4.37947226f;
|
|
bestparams.distance2 = 4.3854661f;
|
|
bestparams.stmix = 0.772289276f;
|
|
break;
|
|
case 5:
|
|
// current score 4656 (74)
|
|
bestparams.threshold = 0.945089161f;
|
|
bestparams.pulsestrength = 2.48777676f;
|
|
bestparams.distance1 = 1.02335358f;
|
|
bestparams.distance2 = 1.14071643f;
|
|
break;
|
|
case 6:
|
|
// current score 584 (18)
|
|
bestparams.threshold = 0.90864867f;
|
|
bestparams.pulsestrength = 2.22691917f;
|
|
bestparams.topbit = -0.008f; // ???
|
|
bestparams.distance1 = 0.120167315f;
|
|
bestparams.distance2 = 0.119318768f;
|
|
break;
|
|
case 7:
|
|
// current score 2 (2)
|
|
bestparams.threshold = 0.911848485f;
|
|
bestparams.pulsestrength = 1.17097521f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.991214871f;
|
|
bestparams.distance2 = 1.10500252f;
|
|
bestparams.stmix = 0.591298461f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R3
|
|
case 'O':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 1100 (118)
|
|
bestparams.threshold = 0.967385352f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 3.22246957f;
|
|
bestparams.distance2 = 3.13088274f;
|
|
bestparams.stmix = 0.739427269f;
|
|
break;
|
|
case 5:
|
|
// current score 6052 (99)
|
|
bestparams.threshold = 0.929785728f;
|
|
bestparams.pulsestrength = 2.30605006f;
|
|
bestparams.distance1 = 1.03718281f;
|
|
bestparams.distance2 = 1.1534183f;
|
|
break;
|
|
case 6:
|
|
// current score 1012 (54)
|
|
bestparams.threshold = 0.919249177f;
|
|
bestparams.pulsestrength = 2.58188939f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.131623372f;
|
|
bestparams.distance2 = 0.158718824f;
|
|
break;
|
|
case 7:
|
|
// current score 2 (2)
|
|
bestparams.threshold = 0.901689231f;
|
|
bestparams.pulsestrength = 1.06335056f;
|
|
bestparams.topbit = 0.004f;
|
|
bestparams.distance1 = 1.04226708f;
|
|
bestparams.distance2 = 1.29957008f;
|
|
bestparams.stmix = 0.509225965f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R3
|
|
case 'P':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 1814 (121)
|
|
bestparams.threshold = 0.981729865f;
|
|
bestparams.topbit = 0.001f;
|
|
bestparams.distance1 = 4.67945051f;
|
|
bestparams.distance2 = 4.70896149f;
|
|
bestparams.stmix = 0.791615963f;
|
|
break;
|
|
case 5:
|
|
// current score 3748 (113)
|
|
bestparams.threshold = 0.915575624f;
|
|
bestparams.pulsestrength = 2.57049465f;
|
|
bestparams.distance1 = 1.03338766f;
|
|
bestparams.distance2 = 1.08230126f;
|
|
break;
|
|
case 6:
|
|
// current score 269 (74)
|
|
bestparams.threshold = 0.944703519f;
|
|
bestparams.pulsestrength = 4.04210186f;
|
|
bestparams.topbit = -0.001f; // ???
|
|
bestparams.distance1 = 0.0535937659f;
|
|
bestparams.distance2 = 0.0294511318f;
|
|
break;
|
|
case 7:
|
|
// current score 181 (17)
|
|
bestparams.threshold = 0.919196963f;
|
|
bestparams.pulsestrength = 1.21124005f;
|
|
bestparams.topbit = 0.002f;
|
|
bestparams.distance1 = 1.15129697f;
|
|
bestparams.distance2 = 1.22111976f;
|
|
bestparams.stmix = 0.672436357f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R3
|
|
case 'Q':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 488 (90)
|
|
bestparams.threshold = 0.982932f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 4.59079f;
|
|
bestparams.stmix = 0.778088f;
|
|
break;
|
|
case 5:
|
|
// current score 3740 (63)
|
|
bestparams.threshold = 1.f;
|
|
bestparams.pulsestrength = 3.62465143f;
|
|
bestparams.distance1 = 0.986276627f;
|
|
bestparams.distance2 = 1.09922075f;
|
|
break;
|
|
case 6:
|
|
// current score 748 (58)
|
|
bestparams.threshold = 0.912882149f;
|
|
bestparams.pulsestrength = 2.45562696f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.128567815f;
|
|
bestparams.distance2 = 0.148435056f;
|
|
break;
|
|
case 7:
|
|
// current score 38 (14)
|
|
bestparams.threshold = 0.901118755f;
|
|
bestparams.pulsestrength = 0.904124081f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.05176663f;
|
|
bestparams.distance2 = 1.10776162f;
|
|
bestparams.stmix = 0.618260384f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R4AR
|
|
case 'R':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 2070 (341)
|
|
bestparams.threshold = 0.888629317f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.94586849f;
|
|
bestparams.distance2 = 2.01927376f;
|
|
bestparams.stmix = 0.600944996f;
|
|
break;
|
|
case 5:
|
|
// current score 7211 (272)
|
|
bestparams.threshold = 0.928046405f;
|
|
bestparams.pulsestrength = 2.5883441f;
|
|
bestparams.distance1 = 1.01187634f;
|
|
bestparams.distance2 = 1.15885961f;
|
|
break;
|
|
case 6:
|
|
// current score 23276 (420)
|
|
bestparams.threshold = 0.872620344f;
|
|
bestparams.pulsestrength = 2.25908351f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.11984051f;
|
|
bestparams.distance2 = 0.0987310335f;
|
|
break;
|
|
case 7:
|
|
// current score 274 (30)
|
|
bestparams.threshold = 0.91457653f;
|
|
bestparams.pulsestrength = 1.32809377f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.11845613f;
|
|
bestparams.distance2 = 1.16926301f;
|
|
bestparams.stmix = 0.791111946f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R4AR
|
|
case 'S':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 1724 (124)
|
|
bestparams.threshold = 0.973066f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 3.57771f;
|
|
bestparams.stmix = 0.747192f;
|
|
break;
|
|
case 5:
|
|
// current score 6264 (226)
|
|
bestparams.threshold = 0.900257707f;
|
|
bestparams.pulsestrength = 1.89190149f;
|
|
bestparams.distance1 = 1.05784476f;
|
|
bestparams.distance2 = 1.1705128f;
|
|
break;
|
|
case 6:
|
|
// current score 2006 (131)
|
|
bestparams.threshold = 0.917820513f;
|
|
bestparams.pulsestrength = 2.8137641f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.133098751f;
|
|
bestparams.distance2 = 0.139843836f;
|
|
break;
|
|
case 7:
|
|
// current score 148 (14)
|
|
bestparams.threshold = 0.933473349f;
|
|
bestparams.pulsestrength = 1.51940262f;
|
|
bestparams.topbit = 0.0075f;
|
|
bestparams.distance1 = 1.15147519f;
|
|
bestparams.distance2 = 1.23372996f;
|
|
bestparams.stmix = 0.693227589f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R4AR
|
|
case 'T':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 290 (101)
|
|
bestparams.threshold = 0.965168953f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 3.04781175f;
|
|
bestparams.distance2 = 3.81387138f;
|
|
bestparams.stmix = 0.609185994f;
|
|
break;
|
|
case 5:
|
|
// current score 6138 (221)
|
|
bestparams.threshold = 0.991526306f;
|
|
bestparams.pulsestrength = 2.80080104f;
|
|
bestparams.distance1 = 0.993945718f;
|
|
bestparams.distance2 = 1.19684732f;
|
|
break;
|
|
case 6:
|
|
// current score 610 (15)
|
|
bestparams.threshold = 0.9087286f;
|
|
bestparams.pulsestrength = 2.26664352f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.158760354f;
|
|
bestparams.distance2 = 0.108530171f;
|
|
break;
|
|
case 7:
|
|
// current score 0
|
|
bestparams.threshold = 0.949945092f;
|
|
bestparams.pulsestrength = 1.60713959f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.01901114f;
|
|
bestparams.distance2 = 1.03737819f;
|
|
bestparams.stmix = 0.994224012f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6581 R4AR
|
|
case 'U':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 294 (94)
|
|
bestparams.threshold = 0.983248f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 4.63783f;
|
|
bestparams.stmix = 0.779401f;
|
|
break;
|
|
case 5:
|
|
// current score 6454 (259)
|
|
bestparams.threshold = 0.99398762f;
|
|
bestparams.pulsestrength = 3.14190888f;
|
|
bestparams.distance1 = 0.999676824f;
|
|
bestparams.distance2 = 1.16238594f;
|
|
break;
|
|
case 6:
|
|
// current score 840 (42)
|
|
bestparams.threshold = 0.903786302f;
|
|
bestparams.pulsestrength = 2.10020733f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 0.142474398f;
|
|
bestparams.distance2 = 0.139588535f;
|
|
break;
|
|
case 7:
|
|
// current score 6 (4)
|
|
bestparams.threshold = 0.925804496f;
|
|
bestparams.pulsestrength = 1.36537039f;
|
|
bestparams.topbit = 0.f;
|
|
bestparams.distance1 = 1.1688062f;
|
|
bestparams.distance2 = 1.32638979f;
|
|
bestparams.stmix = 0.509957671f;
|
|
break;
|
|
}
|
|
break;
|
|
// 8580
|
|
case 'V':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 1380 (169)
|
|
bestparams.threshold = 0.9632f;
|
|
bestparams.topbit = 0.975f;
|
|
bestparams.distance1 = 1.7467f;
|
|
bestparams.distance2 = 2.36132f;
|
|
bestparams.stmix = 0.975395f;
|
|
break;
|
|
case 5:
|
|
// current score 7981 (204)
|
|
bestparams.threshold = 0.93303f;
|
|
bestparams.pulsestrength = 1.7025f;
|
|
bestparams.distance1 = 1.0868f;
|
|
bestparams.distance2 = 1.43527f;
|
|
break;
|
|
case 6:
|
|
// current score 9596 (324)
|
|
bestparams.threshold = 0.958310068f;
|
|
bestparams.pulsestrength = 1.95269263f;
|
|
bestparams.topbit = 0.992986143f;
|
|
bestparams.distance1 = 0.00773835462f;
|
|
bestparams.distance2 = 0.184085369f;
|
|
break;
|
|
case 7:
|
|
// current score 2120 (55)
|
|
bestparams.threshold = 0.945680082f;
|
|
bestparams.pulsestrength = 1.08290601f;
|
|
bestparams.topbit = 0.996945083f;
|
|
bestparams.distance1 = 0.935811639f;
|
|
bestparams.distance2 = 2.05300689f;
|
|
bestparams.stmix = 0.558153927f;
|
|
break;
|
|
}
|
|
break;
|
|
// 6582
|
|
case 'W':
|
|
switch (wave)
|
|
{
|
|
case 3:
|
|
// current score 2201 (242)
|
|
bestparams.threshold = 0.948997259f;
|
|
bestparams.topbit = 0.982420206f;
|
|
bestparams.distance1 = 2.0006547f;
|
|
bestparams.distance2 = 2.03388166f;
|
|
bestparams.stmix = 0.992275f;
|
|
break;
|
|
case 5:
|
|
// current score 8646 (214)
|
|
bestparams.threshold = 0.936479628f;
|
|
bestparams.pulsestrength = 1.86489666f;
|
|
bestparams.distance1 = 1.08213437f;
|
|
bestparams.distance2 = 1.47512901f;
|
|
break;
|
|
case 6:
|
|
// current score 12409 (501)
|
|
bestparams.threshold = 0.921457112f;
|
|
bestparams.pulsestrength = 1.63515782f;
|
|
bestparams.topbit = 0.99865073f;
|
|
bestparams.distance1 = 0.0453318208f;
|
|
bestparams.distance2 = 0.294430673f;
|
|
break;
|
|
case 7:
|
|
// current score 2149 (110)
|
|
bestparams.threshold = 0.997233212f;
|
|
bestparams.pulsestrength = 1.69910455f;
|
|
bestparams.topbit = 0.995346427f;
|
|
bestparams.distance1 = 0.861709118f;
|
|
bestparams.distance2 = 1.48027956f;
|
|
bestparams.stmix = 0.730670393f;
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (bestparams.distance2 == 0.f)
|
|
bestparams.distance2 = bestparams.distance1;
|
|
|
|
const bool is8580 = chip >= 'V';
|
|
|
|
// Calculate current score
|
|
score_t bestscore = bestparams.Score(wave, is8580, reference, true, 4096 * 255);
|
|
std::cout << "# initial score " << bestscore << std::endl << bestparams.toString() << std::endl << std::endl;
|
|
if (bestscore.audible_error == 0)
|
|
exit(0);
|
|
|
|
/*
|
|
* Start the Monte Carlo loop: we randomly alter parameters
|
|
* and calculate the new score until we find the best fitting
|
|
* waveform compared to the sampled data.
|
|
*/
|
|
Parameters p = bestparams;
|
|
for (;;)
|
|
{
|
|
// loop until at least one parameter has changed
|
|
bool changed = false;
|
|
while (!changed)
|
|
{
|
|
for (Param_t i = Param_t::THRESHOLD; i <= Param_t::STMIX; i++)
|
|
{
|
|
// PULSESTRENGTH only affects pulse
|
|
if ((i==Param_t::PULSESTRENGTH) && ((wave & 0x04) != 0x04))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// STMIX only affects saw/triangle mix
|
|
if ((i==Param_t::STMIX) && ((wave & 0x03) != 0x03))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// TOPBIT only affects saw
|
|
if ((i==Param_t::TOPBIT) && ((wave & 0x02) != 0x02))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// change a parameter with 50% proability
|
|
if (GetRandomValue() > 1.)
|
|
{
|
|
const float oldValue = bestparams.GetValue(i);
|
|
|
|
//std::cout << newValue << " -> ";
|
|
float newValue = static_cast<float>(GetRandomValue()*oldValue);
|
|
//float newValue = oldValue + GetRandomValue();
|
|
//std::cout << newValue << std::endl;
|
|
|
|
// try to avoid too small values
|
|
if (newValue < EPSILON)
|
|
newValue += GetNewRandomValue();
|
|
|
|
// check for parameters limits
|
|
if ((i == Param_t::STMIX || i == Param_t::THRESHOLD) && (newValue > 1.f)
|
|
/*|| (i == Param_t::DISTANCE) && (newValue < 1.f)*/)
|
|
{
|
|
newValue = 1.f;
|
|
}
|
|
|
|
p.SetValue(i, newValue);
|
|
changed = changed || oldValue != newValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// check new score
|
|
const score_t score = p.Score(wave, is8580, reference, false, bestscore.audible_error);
|
|
if (bestscore.isBetter(score))
|
|
{
|
|
// accept if improvement
|
|
std::cout << "# current score " << score << std::endl << p.toString() << std::endl << std::endl;
|
|
if (score.audible_error == 0)
|
|
exit(0);
|
|
//p.reset();
|
|
bestparams = p;
|
|
bestscore = score;
|
|
}
|
|
else if (score.audible_error == bestscore.audible_error)
|
|
{
|
|
// print the rate of wrong bits
|
|
std::cout << score.wrongBitsRate() << std::endl;
|
|
|
|
// no improvement but use new parameters as base to increase the "entropy"
|
|
bestparams = p;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Split a file into lines.
|
|
*/
|
|
static std::vector<std::string> split(const std::string &s, char delim)
|
|
{
|
|
std::vector<std::string> elems;
|
|
std::istringstream ss(s);
|
|
std::string item;
|
|
while (std::getline(ss, item, delim))
|
|
{
|
|
elems.push_back(item);
|
|
}
|
|
return elems;
|
|
}
|
|
|
|
/**
|
|
* Read sampled values for specific waveform and chip.
|
|
*/
|
|
static ref_vector_t ReadChip(int wave, char chip)
|
|
{
|
|
std::cout << "Reading chip: " << chip << std::endl;
|
|
|
|
std::ostringstream fileName;
|
|
fileName << "sidwaves/WAVE" << wave << ".CSV";
|
|
std::ifstream ifs(fileName.str().c_str(), std::ifstream::in);
|
|
std::string line;
|
|
ref_vector_t result;
|
|
while (getline(ifs, line).good())
|
|
{
|
|
std::vector<std::string> values = split(line, ',');
|
|
result.push_back(atoi(values[chip - 'A'].c_str()));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int main(int argc, const char* argv[])
|
|
{
|
|
if (argc != 3)
|
|
{
|
|
std::cout << "Usage " << argv[0] << " <waveform> <chip>" << std::endl;
|
|
exit(-1);
|
|
}
|
|
|
|
const int wave = atoi(argv[1]);
|
|
assert(wave == 3 || wave == 5 || wave == 6 || wave == 7);
|
|
|
|
const char chip = argv[2][0];
|
|
assert(chip >= 'A' && chip <= 'Z');
|
|
|
|
ref_vector_t reference = ReadChip(wave, chip);
|
|
|
|
#ifndef NDEBUG
|
|
for (ref_vector_t::iterator it = reference.begin(); it != reference.end(); ++it)
|
|
std::cout << (*it) << std::endl;
|
|
#endif
|
|
|
|
srand(time(0));
|
|
|
|
Optimize(reference, wave, chip);
|
|
}
|