/* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2013-2016 Leandro Nini * 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 #include #include #include #include #include #include #include #include #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 inline long getSeed() { using namespace std::chrono; const auto now_ms = time_point_cast(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(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(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 split(const std::string &s, char delim) { std::vector 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 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] << " " << 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); }