ref: 22c28f1c0de3a76cac067309abfd77f8d508c2bb
parent: 4e1aaeb982ef59dc209047651ef578f96963f03b
author: Olav Sørensen <olav.sorensen@live.no>
date: Fri Jun 12 12:32:01 EDT 2020
Pushed v1.25 code - Instrument envelopes now show x/y coords in the top right corner in Instr. Ed. - The song tempo (BPM) is now *slightly* more accurate for certain BPM values - Fixed a bug with the XFade function on 16-bit pingpong samples
--- a/src/ft2_audio.c
+++ b/src/ft2_audio.c
@@ -24,9 +24,8 @@
chSyncData_t *chSyncEntry;
chSync_t chSync;
pattSync_t pattSync;
-volatile bool pattQueueReading, pattQueueClearing, chQueueReading, chQueueClearing;
+volatile bool pattQueueClearing, chQueueClearing;
-
static int8_t pmpCountDiv, pmpChannels = 2;
static uint16_t smpBuffSize;
static int32_t masterVol, oldAudioFreq, pmpLeft, randSeed = INITIAL_DITHER_SEED;
@@ -153,33 +152,22 @@
void setSpeed(uint16_t bpm)
{
- double dInt, dFrac;
-
if (bpm == 0)
return;
- audio.speedVal = ((audio.freq + audio.freq) + (audio.freq >> 1)) / bpm; // (audio.freq * 2.5) / BPM
- if (audio.speedVal > 0) // calculate tick time length for audio/video sync timestamp
- {
- // number of samples per tick -> tick length for performance counter
- dFrac = modf(audio.speedVal * audio.dSpeedValMul, &dInt);
+ // non-FT2 check for security
+ if (bpm > MAX_BPM)
+ return;
- /* - integer part -
- ** Cast to int32_t so that the compiler will use fast SSE2 float->int instructions.
- ** This result won't be above 2^31, so this is safe.
- */
- tickTimeLen = (int32_t)dInt;
+ audio.speedVal = audio.speedValTab[bpm];
- // - fractional part (scaled to 0..2^32-1) -
- dFrac *= UINT32_MAX;
- dFrac += 0.5;
- if (dFrac > UINT32_MAX)
- dFrac = UINT32_MAX;
+ // get tick time length for audio/video sync timestamp
+ const uint64_t tickTimeLen64 = audio.tickTimeLengthTab[bpm];
+ tickTimeLen = tickTimeLen64 >> 32;
+ tickTimeLenFrac = tickTimeLen64 & 0xFFFFFFFF;
- tickTimeLenFrac = (uint32_t)dFrac;
-
- audio.rampSpeedValMul = 0xFFFFFFFF / audio.speedVal;
- }
+ // used for calculating volume ramp length for "ticks" ramps
+ audio.rampSpeedValMul = audio.rampSpeedValMulTab[bpm];
}
void audioSetVolRamp(bool volRamp)
@@ -651,8 +639,8 @@
** read/write are two different threads, but because of timestamp validation it
** shouldn't be that dangerous.
** It will also create a small visual stutter while the buffer is getting filled,
- ** though that is barely noticable on normal buffer sizes, and it takes several
- ** minutes between each time (when queue size is default, 16384) */
+ ** though that is barely noticable on normal buffer sizes, and it takes a minute
+ ** or two at max BPM between each time (when queue size is default, 4095) */
pattSync.data[0].timestamp = 0;
pattSync.readPos = 0;
pattSync.writePos = 0;
@@ -878,16 +866,69 @@
audioPaused = false;
}
-static void SDLCALL mixCallback(void *userdata, Uint8 *stream, int len)
+static void fillVisualsSyncBuffer(void)
{
- int32_t a, b;
pattSyncData_t pattSyncData;
chSyncData_t chSyncData;
syncedChannel_t *c;
stmTyp *s;
- (void)userdata;
+ if (audio.resetSyncTickTimeFlag)
+ {
+ audio.resetSyncTickTimeFlag = false;
+ audio.tickTime64 = SDL_GetPerformanceCounter() + audio.audLatencyPerfValInt;
+ audio.tickTime64Frac = audio.audLatencyPerfValFrac;
+ }
+
+ if (songPlaying)
+ {
+ // push pattern variables to sync queue
+ pattSyncData.timer = song.curReplayerTimer;
+ pattSyncData.patternPos = song.curReplayerPattPos;
+ pattSyncData.pattern = song.curReplayerPattNr;
+ pattSyncData.songPos = song.curReplayerSongPos;
+ pattSyncData.speed = song.speed;
+ pattSyncData.tempo = (uint8_t)song.tempo;
+ pattSyncData.globalVol = (uint8_t)song.globVol;
+ pattSyncData.timestamp = audio.tickTime64;
+ pattQueuePush(pattSyncData);
+ }
+
+ // push channel variables to sync queue
+
+ c = chSyncData.channels;
+ s = stm;
+
+ for (int32_t i = 0; i < song.antChn; i++, c++, s++)
+ {
+ c->finalPeriod = s->finalPeriod;
+ c->fineTune = s->fineTune;
+ c->relTonNr = s->relTonNr;
+ c->instrNr = s->instrNr;
+ c->sampleNr = s->sampleNr;
+ c->envSustainActive = s->envSustainActive;
+ c->status = s->tmpStatus;
+ c->finalVol = s->finalVol;
+ c->smpStartPos = s->smpStartPos;
+ }
+
+ chSyncData.timestamp = audio.tickTime64;
+ chQueuePush(chSyncData);
+
+ audio.tickTime64 += tickTimeLen;
+ audio.tickTime64Frac += tickTimeLenFrac;
+ if (audio.tickTime64Frac > 0xFFFFFFFF)
+ {
+ audio.tickTime64Frac &= 0xFFFFFFFF;
+ audio.tickTime64++;
+ }
+}
+
+static void SDLCALL audioCallback(void *userdata, Uint8 *stream, int len)
+{
+ int32_t a, b;
+
assert(len < 65536); // limitation in mixer
assert(pmpCountDiv > 0);
@@ -899,7 +940,7 @@
{
if (pmpLeft == 0)
{
- // replayer tick
+ // new replayer tick
replayerBusy = true;
@@ -908,61 +949,10 @@
mainPlayer();
mix_UpdateChannelVolPanFrq();
+ fillVisualsSyncBuffer();
- // AUDIO/VIDEO SYNC
-
- if (audio.resetSyncTickTimeFlag)
- {
- audio.resetSyncTickTimeFlag = false;
-
- audio.tickTime64 = SDL_GetPerformanceCounter() + audio.audLatencyPerfValInt;
- audio.tickTime64Frac = audio.audLatencyPerfValFrac;
- }
-
- if (songPlaying)
- {
- // push pattern variables to sync queue
- pattSyncData.timer = song.curReplayerTimer;
- pattSyncData.patternPos = song.curReplayerPattPos;
- pattSyncData.pattern = song.curReplayerPattNr;
- pattSyncData.songPos = song.curReplayerSongPos;
- pattSyncData.speed = song.speed;
- pattSyncData.tempo = (uint8_t)song.tempo;
- pattSyncData.globalVol = (uint8_t)song.globVol;
- pattSyncData.timestamp = audio.tickTime64;
- pattQueuePush(pattSyncData);
- }
-
- // push channel variables to sync queue
-
- c = chSyncData.channels;
- s = stm;
-
- for (int32_t i = 0; i < song.antChn; i++, c++, s++)
- {
- c->finalPeriod = s->finalPeriod;
- c->fineTune = s->fineTune;
- c->relTonNr = s->relTonNr;
- c->instrNr = s->instrNr;
- c->sampleNr = s->sampleNr;
- c->envSustainActive = s->envSustainActive;
- c->status = s->tmpStatus;
- c->finalVol = s->finalVol;
- c->smpStartPos = s->smpStartPos;
- }
-
- chSyncData.timestamp = audio.tickTime64;
- chQueuePush(chSyncData);
-
- audio.tickTime64 += tickTimeLen;
- audio.tickTime64Frac += tickTimeLenFrac;
- if (audio.tickTime64Frac > 0xFFFFFFFF)
- {
- audio.tickTime64Frac &= 0xFFFFFFFF;
- audio.tickTime64++;
- }
-
pmpLeft = audio.speedVal;
+
replayerBusy = false;
}
@@ -976,6 +966,8 @@
a -= b;
pmpLeft -= b;
}
+
+ (void)userdata;
}
static bool setupAudioBuffers(void)
@@ -1054,15 +1046,14 @@
unlockMixerCallback();
}
-static void calcAudioLatencyVars(uint16_t haveSamples, int32_t haveFreq)
+static void calcAudioLatencyVars(int32_t audioBufferSize, int32_t audioFreq)
{
- double dHaveFreq, dAudioLatencySecs, dInt, dFrac;
+ double dInt, dFrac;
- dHaveFreq = haveFreq;
- if (dHaveFreq == 0.0)
- return; // panic!
+ if (audioFreq == 0)
+ return;
- dAudioLatencySecs = haveSamples / dHaveFreq;
+ const double dAudioLatencySecs = audioBufferSize / (double)audioFreq;
dFrac = modf(dAudioLatencySecs * editor.dPerfFreq, &dInt);
@@ -1134,7 +1125,7 @@
want.format = (config.specialFlags & BITDEPTH_32) ? AUDIO_F32 : AUDIO_S16;
want.channels = 2;
// -------------------------------------------------------------------------------
- want.callback = mixCallback;
+ want.callback = audioCallback;
want.samples = configAudioBufSize;
audio.dev = SDL_OpenAudioDevice(audio.currOutputDevice, 0, &want, &have, SDL_AUDIO_ALLOW_ANY_CHANGE); // prevent SDL2 from resampling
--- a/src/ft2_audio.h
+++ b/src/ft2_audio.h
@@ -11,7 +11,7 @@
FREQ_TABLE_AMIGA = 1,
};
-/* Use 16 on non-x86_64 platforms so that we can avoid a
+/* Use 16 on non-x86_64 platforms so that we can avoid a
** 64-bit division in the outside mixer loop. x86_64 users
** are lucky and will get double the fractional delta precision.
** This is beneficial in 96kHz/192kHz mode, where deltas are
@@ -50,10 +50,10 @@
bool linearFreqTable, rescanAudioDevicesSupported;
int32_t inputDeviceNum, outputDeviceNum, lastWorkingAudioFreq, lastWorkingAudioBits;
int32_t quickVolSizeVal, *mixBufferL, *mixBufferR, *mixBufferLUnaligned, *mixBufferRUnaligned;
- int32_t rampQuickVolMul, rampSpeedValMul;
+ int32_t rampQuickVolMul, rampSpeedValMul, speedValTab[MAX_BPM+1], rampSpeedValMulTab[MAX_BPM+1];
uint32_t freq;
uint32_t audLatencyPerfValInt, audLatencyPerfValFrac, speedVal, musicTimeSpeedVal;
- uint64_t tickTime64, tickTime64Frac;
+ uint64_t tickTime64, tickTime64Frac, tickTimeLengthTab[MAX_BPM+1];
double dAudioLatencyMs, dSpeedValMul, dPianoDeltaMul;
SDL_AudioDeviceID dev;
uint32_t wantFreq, haveFreq, wantSamples, haveSamples, wantChannels, haveChannels;
@@ -111,7 +111,7 @@
extern chSync_t chSync;
extern pattSync_t pattSync;
-extern volatile bool pattQueueReading, pattQueueClearing, chQueueReading, chQueueClearing;
+extern volatile bool pattQueueClearing, chQueueClearing;
#if !defined __amd64__ && !defined _WIN64
void resetCachedMixerVars(void);
--- a/src/ft2_inst_ed.c
+++ b/src/ft2_inst_ed.c
@@ -22,6 +22,7 @@
#include "ft2_tables.h"
#include "ft2_bmp.h"
#include "ft2_structs.h"
+#include "ft2_bmp.h"
#ifdef _MSC_VER
#pragma pack(push)
@@ -2008,12 +2009,87 @@
}
}
+static void textOutTiny(int32_t xPos, int32_t yPos, char *str, uint32_t color)
+{
+ uint32_t *dstPtr = &video.frameBuffer[(yPos * SCREEN_W) + xPos];
+
+ while (*str != '\0')
+ {
+ const char chr = *str++;
+ if (chr < '0' || chr > '9')
+ {
+ dstPtr += FONT3_CHAR_W;
+ continue;
+ }
+
+ const uint8_t *srcPtr = &bmp.font3[(chr - '0') * FONT3_CHAR_W];
+ for (int32_t y = 0; y < FONT3_CHAR_H; y++)
+ {
+ for (int32_t x = 0; x < FONT3_CHAR_W; x++)
+ {
+ if (srcPtr[x])
+ dstPtr[x] = color;
+ }
+
+ srcPtr += FONT3_WIDTH;
+ dstPtr += SCREEN_W;
+ }
+
+ dstPtr -= (SCREEN_W * FONT3_CHAR_H) - FONT3_CHAR_W;
+ }
+}
+
+static void drawVolEnvCoords(int16_t tick, int16_t val)
+{
+ char str[8];
+
+ tick = CLAMP(tick, 0, 324);
+ val = CLAMP(val, 0, 64);
+
+ sprintf(str, "%03d %02d", tick, val);
+
+ textOutTiny(312, 190, str, video.palette[PAL_BCKGRND]);
+ textOutTiny(313, 189, str, video.palette[PAL_BCKGRND]);
+ textOutTiny(314, 190, str, video.palette[PAL_BCKGRND]);
+ textOutTiny(313, 191, str, video.palette[PAL_BCKGRND]);
+ textOutTiny(313, 190, str, video.palette[PAL_FORGRND]);
+
+}
+
+static void drawPanEnvCoords(int16_t tick, int16_t val)
+{
+ char str[8];
+
+ tick = CLAMP(tick, 0, 324);
+ val = CLAMP(val, 0, 63);
+
+ sprintf(str, "%03d %02d", tick, val);
+
+ textOutTiny(312, 276, str, video.palette[PAL_BCKGRND]);
+ textOutTiny(313, 275, str, video.palette[PAL_BCKGRND]);
+ textOutTiny(314, 276, str, video.palette[PAL_BCKGRND]);
+ textOutTiny(313, 277, str, video.palette[PAL_BCKGRND]);
+ textOutTiny(313, 276, str, video.palette[PAL_FORGRND]);
+}
+
void handleInstEditorRedrawing(void)
{
+ instrTyp *ins = instr[editor.curInstr];
+
+ int16_t tick, val;
if (updateVolEnv)
{
updateVolEnv = false;
writeEnvelope(0);
+
+ tick = val = 0;
+ if (ins != NULL)
+ {
+ tick = ins->envVP[editor.currVolEnvPoint][0];
+ val = ins->envVP[editor.currVolEnvPoint][1];
+ }
+
+ drawVolEnvCoords(tick, val);
}
if (updatePanEnv)
@@ -2020,6 +2096,15 @@
{
updatePanEnv = false;
writeEnvelope(1);
+
+ tick = val = 0;
+ if (ins != NULL)
+ {
+ tick = ins->envPP[editor.currPanEnvPoint][0];
+ val = ins->envPP[editor.currPanEnvPoint][1];
+ }
+
+ drawPanEnvCoords(tick, val);
}
}
--- a/src/ft2_intrp_table.c
+++ b/src/ft2_intrp_table.c
@@ -2061,138 +2061,266 @@
#else
-// for non-x86_64 CPUs: 15-bit precision, 512 phases
+// for non-x86_64 CPUs: 15-bit precision, 1024 phases
const int16_t cubicSplineTable[CUBIC_WIDTH * CUBIC_PHASES] =
{
- 0, 32767, 0, 0, -32, 32767, 32, 0, -64, 32767, 65, 0, -95, 32766, 98, -1,
- -126, 32763, 132, -1, -157, 32761, 166, -2, -188, 32757, 201, -2, -218, 32753, 236, -3,
- -248, 32748, 272, -4, -278, 32743, 308, -5, -308, 32737, 345, -6, -337, 32730, 382, -7,
- -366, 32724, 419, -9, -395, 32716, 457, -10, -424, 32708, 496, -12, -452, 32699, 535, -14,
- -481, 32690, 575, -16, -508, 32679, 614, -17, -536, 32669, 655, -20, -564, 32658, 696, -22,
- -591, 32646, 737, -24, -618, 32633, 779, -26, -645, 32621, 821, -29, -671, 32607, 864, -32,
- -698, 32593, 907, -34, -724, 32578, 951, -37, -750, 32563, 995, -40, -775, 32547, 1039, -43,
- -801, 32531, 1084, -46, -826, 32515, 1129, -50, -851, 32497, 1175, -53, -876, 32479, 1221, -56,
- -900, 32460, 1268, -60, -924, 32441, 1315, -64, -948, 32420, 1363, -67, -972, 32400, 1411, -71,
- -996, 32380, 1459, -75, -1019, 32358, 1508, -79, -1042, 32337, 1557, -84, -1065, 32314, 1607, -88,
- -1088, 32291, 1657, -92, -1110, 32268, 1707, -97, -1133, 32244, 1758, -101, -1155, 32220, 1809, -106,
- -1176, 32194, 1861, -111, -1198, 32168, 1913, -115, -1219, 32142, 1965, -120, -1241, 32116, 2018, -125,
- -1262, 32089, 2072, -131, -1282, 32061, 2125, -136, -1303, 32033, 2179, -141, -1323, 32003, 2234, -146,
- -1343, 31974, 2289, -152, -1363, 31944, 2344, -157, -1383, 31915, 2399, -163, -1402, 31884, 2455, -169,
- -1421, 31852, 2512, -175, -1440, 31820, 2568, -180, -1459, 31787, 2626, -186, -1478, 31755, 2683, -192,
- -1496, 31722, 2741, -199, -1515, 31689, 2799, -205, -1533, 31654, 2858, -211, -1550, 31619, 2917, -218,
- -1568, 31584, 2976, -224, -1585, 31548, 3036, -231, -1603, 31512, 3096, -237, -1620, 31476, 3156, -244,
- -1636, 31438, 3217, -251, -1653, 31400, 3278, -257, -1669, 31362, 3339, -264, -1686, 31324, 3401, -271,
- -1702, 31285, 3463, -278, -1717, 31245, 3526, -286, -1733, 31205, 3589, -293, -1748, 31164, 3652, -300,
- -1764, 31124, 3715, -307, -1779, 31083, 3779, -315, -1793, 31040, 3843, -322, -1808, 30998, 3908, -330,
- -1823, 30956, 3973, -338, -1837, 30912, 4038, -345, -1851, 30869, 4103, -353, -1865, 30825, 4169, -361,
- -1878, 30780, 4235, -369, -1892, 30736, 4301, -377, -1905, 30690, 4368, -385, -1918, 30644, 4435, -393,
- -1931, 30598, 4502, -401, -1944, 30551, 4570, -409, -1956, 30503, 4638, -417, -1969, 30457, 4706, -426,
- -1981, 30408, 4775, -434, -1993, 30359, 4844, -442, -2005, 30311, 4913, -451, -2017, 30262, 4982, -459,
- -2028, 30212, 5052, -468, -2039, 30162, 5122, -477, -2050, 30111, 5192, -485, -2061, 30060, 5263, -494,
- -2072, 30009, 5334, -503, -2083, 29958, 5405, -512, -2093, 29906, 5476, -521, -2103, 29853, 5548, -530,
- -2113, 29800, 5620, -539, -2123, 29747, 5692, -548, -2133, 29693, 5765, -557, -2142, 29638, 5838, -566,
- -2152, 29584, 5911, -575, -2161, 29529, 5984, -584, -2170, 29474, 6058, -594, -2179, 29419, 6131, -603,
- -2188, 29363, 6206, -613, -2196, 29306, 6280, -622, -2204, 29249, 6354, -631, -2213, 29193, 6429, -641,
- -2221, 29135, 6504, -650, -2228, 29076, 6580, -660, -2236, 29019, 6655, -670, -2244, 28960, 6731, -679,
- -2251, 28901, 6807, -689, -2258, 28842, 6883, -699, -2265, 28782, 6960, -709, -2272, 28721, 7037, -718,
- -2279, 28661, 7114, -728, -2285, 28600, 7191, -738, -2292, 28540, 7268, -748, -2298, 28478, 7346, -758,
- -2304, 28416, 7424, -768, -2310, 28354, 7502, -778, -2316, 28292, 7580, -788, -2321, 28228, 7659, -798,
- -2327, 28165, 7738, -808, -2332, 28101, 7817, -818, -2337, 28038, 7896, -829, -2342, 27974, 7975, -839,
- -2347, 27909, 8055, -849, -2352, 27844, 8135, -859, -2356, 27778, 8215, -869, -2361, 27714, 8295, -880,
- -2365, 27648, 8375, -890, -2369, 27581, 8456, -900, -2373, 27516, 8536, -911, -2377, 27449, 8617, -921,
- -2381, 27382, 8699, -932, -2384, 27314, 8780, -942, -2387, 27246, 8861, -952, -2391, 27179, 8943, -963,
- -2394, 27110, 9025, -973, -2397, 27042, 9107, -984, -2399, 26972, 9189, -994, -2402, 26904, 9271, -1005,
- -2405, 26834, 9354, -1015, -2407, 26764, 9437, -1026, -2409, 26693, 9520, -1036, -2411, 26623, 9603, -1047,
- -2413, 26553, 9686, -1058, -2415, 26482, 9769, -1068, -2417, 26411, 9853, -1079, -2419, 26340, 9936, -1089,
- -2420, 26268, 10020, -1100, -2421, 26196, 10104, -1111, -2422, 26123, 10188, -1121, -2424, 26052, 10272, -1132,
- -2424, 25978, 10357, -1143, -2425, 25905, 10441, -1153, -2426, 25832, 10526, -1164, -2426, 25758, 10611, -1175,
- -2427, 25684, 10696, -1185, -2427, 25610, 10781, -1196, -2427, 25536, 10866, -1207, -2427, 25461, 10951, -1217,
- -2427, 25386, 11037, -1228, -2427, 25312, 11122, -1239, -2427, 25236, 11208, -1249, -2426, 25160, 11294, -1260,
- -2426, 25085, 11380, -1271, -2425, 25008, 11466, -1281, -2424, 24932, 11552, -1292, -2423, 24855, 11638, -1302,
- -2422, 24779, 11724, -1313, -2421, 24702, 11811, -1324, -2419, 24624, 11897, -1334, -2418, 24547, 11984, -1345,
- -2416, 24469, 12071, -1356, -2415, 24391, 12158, -1366, -2413, 24314, 12244, -1377, -2411, 24234, 12332, -1387,
- -2409, 24156, 12419, -1398, -2407, 24077, 12506, -1408, -2405, 23999, 12593, -1419, -2402, 23918, 12681, -1429,
- -2400, 23840, 12768, -1440, -2397, 23759, 12856, -1450, -2395, 23681, 12943, -1461, -2392, 23600, 13031, -1471,
- -2389, 23520, 13119, -1482, -2386, 23440, 13206, -1492, -2383, 23360, 13294, -1503, -2380, 23279, 13382, -1513,
- -2377, 23198, 13470, -1523, -2373, 23117, 13558, -1534, -2370, 23035, 13647, -1544, -2366, 22953, 13735, -1554,
- -2362, 22872, 13823, -1565, -2359, 22791, 13911, -1575, -2355, 22708, 14000, -1585, -2351, 22626, 14088, -1595,
- -2347, 22544, 14177, -1606, -2342, 22461, 14265, -1616, -2338, 22378, 14354, -1626, -2334, 22296, 14442, -1636,
- -2329, 22212, 14531, -1646, -2325, 22130, 14619, -1656, -2320, 22046, 14708, -1666, -2315, 21962, 14797, -1676,
- -2310, 21879, 14885, -1686, -2305, 21795, 14974, -1696, -2300, 21711, 15063, -1706, -2295, 21626, 15152, -1715,
- -2290, 21542, 15241, -1725, -2284, 21458, 15329, -1735, -2279, 21374, 15418, -1745, -2274, 21289, 15507, -1754,
- -2268, 21204, 15596, -1764, -2262, 21119, 15685, -1774, -2257, 21034, 15774, -1783, -2251, 20949, 15863, -1793,
- -2245, 20863, 15952, -1802, -2239, 20779, 16040, -1812, -2233, 20693, 16129, -1821, -2227, 20607, 16218, -1830,
- -2220, 20521, 16307, -1840, -2214, 20435, 16396, -1849, -2208, 20349, 16485, -1858, -2201, 20262, 16574, -1867,
- -2195, 20177, 16662, -1876, -2188, 20091, 16751, -1886, -2181, 20004, 16840, -1895, -2174, 19917, 16929, -1904,
- -2168, 19831, 17018, -1913, -2161, 19744, 17106, -1921, -2154, 19657, 17195, -1930, -2146, 19569, 17284, -1939,
- -2139, 19483, 17372, -1948, -2132, 19395, 17461, -1956, -2125, 19309, 17549, -1965, -2117, 19221, 17638, -1974,
- -2110, 19134, 17726, -1982, -2102, 19046, 17815, -1991, -2095, 18959, 17903, -1999, -2087, 18871, 17991, -2007,
- -2079, 18783, 18080, -2016, -2072, 18696, 18168, -2024, -2064, 18608, 18256, -2032, -2056, 18520, 18344, -2040,
- -2048, 18432, 18432, -2048, -2040, 18344, 18520, -2056, -2032, 18256, 18608, -2064, -2024, 18168, 18696, -2072,
- -2016, 18080, 18783, -2079, -2007, 17991, 18871, -2087, -1999, 17903, 18959, -2095, -1991, 17815, 19046, -2102,
- -1982, 17726, 19134, -2110, -1974, 17638, 19221, -2117, -1965, 17549, 19309, -2125, -1956, 17461, 19395, -2132,
- -1948, 17372, 19483, -2139, -1939, 17284, 19569, -2146, -1930, 17195, 19657, -2154, -1921, 17106, 19744, -2161,
- -1913, 17018, 19831, -2168, -1904, 16929, 19917, -2174, -1895, 16840, 20004, -2181, -1886, 16751, 20091, -2188,
- -1876, 16662, 20177, -2195, -1867, 16574, 20262, -2201, -1858, 16485, 20349, -2208, -1849, 16396, 20435, -2214,
- -1840, 16307, 20521, -2220, -1830, 16218, 20607, -2227, -1821, 16129, 20693, -2233, -1812, 16040, 20779, -2239,
- -1802, 15952, 20863, -2245, -1793, 15863, 20949, -2251, -1783, 15774, 21034, -2257, -1774, 15685, 21119, -2262,
- -1764, 15596, 21204, -2268, -1754, 15507, 21289, -2274, -1745, 15418, 21374, -2279, -1735, 15329, 21458, -2284,
- -1725, 15241, 21542, -2290, -1715, 15152, 21626, -2295, -1706, 15063, 21711, -2300, -1696, 14974, 21795, -2305,
- -1686, 14885, 21879, -2310, -1676, 14797, 21962, -2315, -1666, 14708, 22046, -2320, -1656, 14619, 22130, -2325,
- -1646, 14531, 22212, -2329, -1636, 14442, 22296, -2334, -1626, 14354, 22378, -2338, -1616, 14265, 22461, -2342,
- -1606, 14177, 22544, -2347, -1595, 14088, 22626, -2351, -1585, 14000, 22708, -2355, -1575, 13911, 22791, -2359,
- -1565, 13823, 22872, -2362, -1554, 13735, 22953, -2366, -1544, 13647, 23035, -2370, -1534, 13558, 23117, -2373,
- -1523, 13470, 23198, -2377, -1513, 13382, 23279, -2380, -1503, 13294, 23360, -2383, -1492, 13206, 23440, -2386,
- -1482, 13119, 23520, -2389, -1471, 13031, 23600, -2392, -1461, 12943, 23681, -2395, -1450, 12856, 23759, -2397,
- -1440, 12768, 23840, -2400, -1429, 12681, 23918, -2402, -1419, 12593, 23999, -2405, -1408, 12506, 24077, -2407,
- -1398, 12419, 24156, -2409, -1387, 12332, 24234, -2411, -1377, 12244, 24314, -2413, -1366, 12158, 24391, -2415,
- -1356, 12071, 24469, -2416, -1345, 11984, 24547, -2418, -1334, 11897, 24624, -2419, -1324, 11811, 24702, -2421,
- -1313, 11724, 24779, -2422, -1302, 11638, 24855, -2423, -1292, 11552, 24932, -2424, -1281, 11466, 25008, -2425,
- -1271, 11380, 25085, -2426, -1260, 11294, 25160, -2426, -1249, 11208, 25236, -2427, -1239, 11122, 25312, -2427,
- -1228, 11037, 25386, -2427, -1217, 10951, 25461, -2427, -1207, 10866, 25536, -2427, -1196, 10781, 25610, -2427,
- -1185, 10696, 25684, -2427, -1175, 10611, 25758, -2426, -1164, 10526, 25832, -2426, -1153, 10441, 25905, -2425,
- -1143, 10357, 25978, -2424, -1132, 10272, 26052, -2424, -1121, 10188, 26123, -2422, -1111, 10104, 26196, -2421,
- -1100, 10020, 26268, -2420, -1089, 9936, 26340, -2419, -1079, 9853, 26411, -2417, -1068, 9769, 26482, -2415,
- -1058, 9686, 26553, -2413, -1047, 9603, 26623, -2411, -1036, 9520, 26693, -2409, -1026, 9437, 26764, -2407,
- -1015, 9354, 26834, -2405, -1005, 9271, 26904, -2402, -994, 9189, 26972, -2399, -984, 9107, 27042, -2397,
- -973, 9025, 27110, -2394, -963, 8943, 27179, -2391, -952, 8861, 27246, -2387, -942, 8780, 27314, -2384,
- -932, 8699, 27382, -2381, -921, 8617, 27449, -2377, -911, 8536, 27516, -2373, -900, 8456, 27581, -2369,
- -890, 8375, 27648, -2365, -880, 8295, 27714, -2361, -869, 8215, 27778, -2356, -859, 8135, 27844, -2352,
- -849, 8055, 27909, -2347, -839, 7975, 27974, -2342, -829, 7896, 28038, -2337, -818, 7817, 28101, -2332,
- -808, 7738, 28165, -2327, -798, 7659, 28228, -2321, -788, 7580, 28292, -2316, -778, 7502, 28354, -2310,
- -768, 7424, 28416, -2304, -758, 7346, 28478, -2298, -748, 7268, 28540, -2292, -738, 7191, 28600, -2285,
- -728, 7114, 28661, -2279, -718, 7037, 28721, -2272, -709, 6960, 28782, -2265, -699, 6883, 28842, -2258,
- -689, 6807, 28901, -2251, -679, 6731, 28960, -2244, -670, 6655, 29019, -2236, -660, 6580, 29076, -2228,
- -650, 6504, 29135, -2221, -641, 6429, 29193, -2213, -631, 6354, 29249, -2204, -622, 6280, 29306, -2196,
- -613, 6206, 29363, -2188, -603, 6131, 29419, -2179, -594, 6058, 29474, -2170, -584, 5984, 29529, -2161,
- -575, 5911, 29584, -2152, -566, 5838, 29638, -2142, -557, 5765, 29693, -2133, -548, 5692, 29747, -2123,
- -539, 5620, 29800, -2113, -530, 5548, 29853, -2103, -521, 5476, 29906, -2093, -512, 5405, 29958, -2083,
- -503, 5334, 30009, -2072, -494, 5263, 30060, -2061, -485, 5192, 30111, -2050, -477, 5122, 30162, -2039,
- -468, 5052, 30212, -2028, -459, 4982, 30262, -2017, -451, 4913, 30311, -2005, -442, 4844, 30359, -1993,
- -434, 4775, 30408, -1981, -426, 4706, 30457, -1969, -417, 4638, 30503, -1956, -409, 4570, 30551, -1944,
- -401, 4502, 30598, -1931, -393, 4435, 30644, -1918, -385, 4368, 30690, -1905, -377, 4301, 30736, -1892,
- -369, 4235, 30780, -1878, -361, 4169, 30825, -1865, -353, 4103, 30869, -1851, -345, 4038, 30912, -1837,
- -338, 3973, 30956, -1823, -330, 3908, 30998, -1808, -322, 3843, 31040, -1793, -315, 3779, 31083, -1779,
- -307, 3715, 31124, -1764, -300, 3652, 31164, -1748, -293, 3589, 31205, -1733, -286, 3526, 31245, -1717,
- -278, 3463, 31285, -1702, -271, 3401, 31324, -1686, -264, 3339, 31362, -1669, -257, 3278, 31400, -1653,
- -251, 3217, 31438, -1636, -244, 3156, 31476, -1620, -237, 3096, 31512, -1603, -231, 3036, 31548, -1585,
- -224, 2976, 31584, -1568, -218, 2917, 31619, -1550, -211, 2858, 31654, -1533, -205, 2799, 31689, -1515,
- -199, 2741, 31722, -1496, -192, 2683, 31755, -1478, -186, 2626, 31787, -1459, -180, 2568, 31820, -1440,
- -175, 2512, 31852, -1421, -169, 2455, 31884, -1402, -163, 2399, 31915, -1383, -157, 2344, 31944, -1363,
- -152, 2289, 31974, -1343, -146, 2234, 32003, -1323, -141, 2179, 32033, -1303, -136, 2125, 32061, -1282,
- -131, 2072, 32089, -1262, -125, 2018, 32116, -1241, -120, 1965, 32142, -1219, -115, 1913, 32168, -1198,
- -111, 1861, 32194, -1176, -106, 1809, 32220, -1155, -101, 1758, 32244, -1133, -97, 1707, 32268, -1110,
- -92, 1657, 32291, -1088, -88, 1607, 32314, -1065, -84, 1557, 32337, -1042, -79, 1508, 32358, -1019,
- -75, 1459, 32380, -996, -71, 1411, 32400, -972, -67, 1363, 32420, -948, -64, 1315, 32441, -924,
- -60, 1268, 32460, -900, -56, 1221, 32479, -876, -53, 1175, 32497, -851, -50, 1129, 32515, -826,
- -46, 1084, 32531, -801, -43, 1039, 32547, -775, -40, 995, 32563, -750, -37, 951, 32578, -724,
- -34, 907, 32593, -698, -32, 864, 32607, -671, -29, 821, 32621, -645, -26, 779, 32633, -618,
- -24, 737, 32646, -591, -22, 696, 32658, -564, -20, 655, 32669, -536, -17, 614, 32679, -508,
- -16, 575, 32690, -481, -14, 535, 32699, -452, -12, 496, 32708, -424, -10, 457, 32716, -395,
- -9, 419, 32724, -366, -7, 382, 32730, -337, -6, 345, 32737, -308, -5, 308, 32743, -278,
- -4, 272, 32748, -248, -3, 236, 32753, -218, -2, 201, 32757, -188, -2, 166, 32761, -157,
- -1, 132, 32763, -126, -1, 98, 32766, -95, 0, 65, 32767, -64, 0, 32, 32767, -32
+ 0, 32767, 0, 0, -16, 32767, 16, 0, -32, 32767, 32, 0, -48, 32767, 49, 0,
+ -64, 32767, 65, 0, -79, 32765, 82, 0, -95, 32766, 98, -1, -110, 32764, 115, -1,
+ -126, 32763, 132, -1, -141, 32761, 149, -1, -157, 32761, 166, -2, -172, 32758, 184, -2,
+ -188, 32757, 201, -2, -203, 32756, 218, -3, -218, 32753, 236, -3, -233, 32750, 254, -3,
+ -248, 32748, 272, -4, -263, 32745, 290, -4, -278, 32743, 308, -5, -293, 32741, 326, -6,
+ -308, 32737, 345, -6, -322, 32734, 363, -7, -337, 32730, 382, -7, -352, 32727, 401, -8,
+ -366, 32724, 419, -9, -381, 32721, 438, -10, -395, 32716, 457, -10, -410, 32712, 477, -11,
+ -424, 32708, 496, -12, -438, 32704, 515, -13, -452, 32699, 535, -14, -466, 32694, 555, -15,
+ -481, 32690, 575, -16, -495, 32685, 594, -16, -508, 32679, 614, -17, -522, 32673, 635, -18,
+ -536, 32669, 655, -20, -550, 32664, 675, -21, -564, 32658, 696, -22, -577, 32652, 716, -23,
+ -591, 32646, 737, -24, -605, 32640, 758, -25, -618, 32633, 779, -26, -631, 32627, 800, -28,
+ -645, 32621, 821, -29, -658, 32614, 842, -30, -671, 32607, 864, -32, -685, 32601, 885, -33,
+ -698, 32593, 907, -34, -711, 32586, 929, -36, -724, 32578, 951, -37, -737, 32572, 972, -39,
+ -750, 32563, 995, -40, -762, 32555, 1017, -42, -775, 32547, 1039, -43, -788, 32540, 1061, -45,
+ -801, 32531, 1084, -46, -813, 32522, 1107, -48, -826, 32515, 1129, -50, -838, 32505, 1152, -51,
+ -851, 32497, 1175, -53, -863, 32488, 1198, -55, -876, 32479, 1221, -56, -888, 32469, 1245, -58,
+ -900, 32460, 1268, -60, -912, 32451, 1291, -62, -924, 32441, 1315, -64, -936, 32431, 1339, -66,
+ -948, 32420, 1363, -67, -960, 32410, 1387, -69, -972, 32400, 1411, -71, -984, 32390, 1435, -73,
+ -996, 32380, 1459, -75, -1007, 32369, 1483, -77, -1019, 32358, 1508, -79, -1031, 32348, 1532, -81,
+ -1042, 32337, 1557, -84, -1054, 32326, 1582, -86, -1065, 32314, 1607, -88, -1076, 32303, 1631, -90,
+ -1088, 32291, 1657, -92, -1099, 32279, 1682, -94, -1110, 32268, 1707, -97, -1121, 32256, 1732, -99,
+ -1133, 32244, 1758, -101, -1144, 32233, 1783, -104, -1155, 32220, 1809, -106, -1166, 32207, 1835, -108,
+ -1176, 32194, 1861, -111, -1187, 32181, 1887, -113, -1198, 32168, 1913, -115, -1209, 32156, 1939, -118,
+ -1219, 32142, 1965, -120, -1230, 32129, 1992, -123, -1241, 32116, 2018, -125, -1251, 32102, 2045, -128,
+ -1262, 32089, 2072, -131, -1272, 32075, 2098, -133, -1282, 32061, 2125, -136, -1293, 32047, 2152, -138,
+ -1303, 32033, 2179, -141, -1313, 32019, 2206, -144, -1323, 32003, 2234, -146, -1333, 31989, 2261, -149,
+ -1343, 31974, 2289, -152, -1353, 31960, 2316, -155, -1363, 31944, 2344, -157, -1373, 31930, 2371, -160,
+ -1383, 31915, 2399, -163, -1392, 31899, 2427, -166, -1402, 31884, 2455, -169, -1412, 31869, 2483, -172,
+ -1421, 31852, 2512, -175, -1431, 31836, 2540, -177, -1440, 31820, 2568, -180, -1450, 31804, 2597, -183,
+ -1459, 31787, 2626, -186, -1469, 31772, 2654, -189, -1478, 31755, 2683, -192, -1487, 31739, 2712, -196,
+ -1496, 31722, 2741, -199, -1506, 31706, 2770, -202, -1515, 31689, 2799, -205, -1524, 31672, 2828, -208,
+ -1533, 31654, 2858, -211, -1542, 31637, 2887, -214, -1550, 31619, 2917, -218, -1559, 31602, 2946, -221,
+ -1568, 31584, 2976, -224, -1577, 31566, 3006, -227, -1585, 31548, 3036, -231, -1594, 31530, 3066, -234,
+ -1603, 31512, 3096, -237, -1611, 31493, 3126, -240, -1620, 31476, 3156, -244, -1628, 31457, 3186, -247,
+ -1636, 31438, 3217, -251, -1645, 31420, 3247, -254, -1653, 31400, 3278, -257, -1661, 31381, 3309, -261,
+ -1669, 31362, 3339, -264, -1677, 31343, 3370, -268, -1686, 31324, 3401, -271, -1694, 31305, 3432, -275,
+ -1702, 31285, 3463, -278, -1709, 31264, 3495, -282, -1717, 31245, 3526, -286, -1725, 31225, 3557, -289,
+ -1733, 31205, 3589, -293, -1741, 31185, 3620, -296, -1748, 31164, 3652, -300, -1756, 31145, 3683, -304,
+ -1764, 31124, 3715, -307, -1771, 31103, 3747, -311, -1779, 31083, 3779, -315, -1786, 31062, 3811, -319,
+ -1793, 31040, 3843, -322, -1801, 31020, 3875, -326, -1808, 30998, 3908, -330, -1815, 30977, 3940, -334,
+ -1823, 30956, 3973, -338, -1830, 30934, 4005, -341, -1837, 30912, 4038, -345, -1844, 30891, 4070, -349,
+ -1851, 30869, 4103, -353, -1858, 30847, 4136, -357, -1865, 30825, 4169, -361, -1872, 30803, 4202, -365,
+ -1878, 30780, 4235, -369, -1885, 30758, 4268, -373, -1892, 30736, 4301, -377, -1899, 30713, 4335, -381,
+ -1905, 30690, 4368, -385, -1912, 30667, 4402, -389, -1918, 30644, 4435, -393, -1925, 30621, 4469, -397,
+ -1931, 30598, 4502, -401, -1938, 30575, 4536, -405, -1944, 30551, 4570, -409, -1950, 30527, 4604, -413,
+ -1956, 30503, 4638, -417, -1963, 30480, 4672, -421, -1969, 30457, 4706, -426, -1975, 30432, 4741, -430,
+ -1981, 30408, 4775, -434, -1987, 30384, 4809, -438, -1993, 30359, 4844, -442, -1999, 30336, 4878, -447,
+ -2005, 30311, 4913, -451, -2011, 30286, 4948, -455, -2017, 30262, 4982, -459, -2022, 30237, 5017, -464,
+ -2028, 30212, 5052, -468, -2034, 30187, 5087, -472, -2039, 30162, 5122, -477, -2045, 30137, 5157, -481,
+ -2050, 30111, 5192, -485, -2056, 30086, 5228, -490, -2061, 30060, 5263, -494, -2067, 30036, 5298, -499,
+ -2072, 30009, 5334, -503, -2077, 29983, 5369, -507, -2083, 29958, 5405, -512, -2088, 29931, 5441, -516,
+ -2093, 29906, 5476, -521, -2098, 29879, 5512, -525, -2103, 29853, 5548, -530, -2108, 29826, 5584, -534,
+ -2113, 29800, 5620, -539, -2118, 29773, 5656, -543, -2123, 29747, 5692, -548, -2128, 29719, 5729, -552,
+ -2133, 29693, 5765, -557, -2138, 29666, 5801, -561, -2142, 29638, 5838, -566, -2147, 29612, 5874, -571,
+ -2152, 29584, 5911, -575, -2156, 29557, 5947, -580, -2161, 29529, 5984, -584, -2165, 29501, 6021, -589,
+ -2170, 29474, 6058, -594, -2174, 29446, 6094, -598, -2179, 29419, 6131, -603, -2183, 29391, 6168, -608,
+ -2188, 29363, 6206, -613, -2192, 29334, 6243, -617, -2196, 29306, 6280, -622, -2200, 29278, 6317, -627,
+ -2204, 29249, 6354, -631, -2208, 29220, 6392, -636, -2213, 29193, 6429, -641, -2217, 29164, 6467, -646,
+ -2221, 29135, 6504, -650, -2224, 29105, 6542, -655, -2228, 29076, 6580, -660, -2232, 29048, 6617, -665,
+ -2236, 29019, 6655, -670, -2240, 28990, 6693, -675, -2244, 28960, 6731, -679, -2247, 28930, 6769, -684,
+ -2251, 28901, 6807, -689, -2255, 28872, 6845, -694, -2258, 28842, 6883, -699, -2262, 28812, 6922, -704,
+ -2265, 28782, 6960, -709, -2269, 28752, 6998, -713, -2272, 28721, 7037, -718, -2275, 28691, 7075, -723,
+ -2279, 28661, 7114, -728, -2282, 28631, 7152, -733, -2285, 28600, 7191, -738, -2289, 28570, 7230, -743,
+ -2292, 28540, 7268, -748, -2295, 28509, 7307, -753, -2298, 28478, 7346, -758, -2301, 28447, 7385, -763,
+ -2304, 28416, 7424, -768, -2307, 28385, 7463, -773, -2310, 28354, 7502, -778, -2313, 28323, 7541, -783,
+ -2316, 28292, 7580, -788, -2319, 28260, 7620, -793, -2321, 28228, 7659, -798, -2324, 28197, 7698, -803,
+ -2327, 28165, 7738, -808, -2329, 28133, 7777, -813, -2332, 28101, 7817, -818, -2335, 28070, 7856, -823,
+ -2337, 28038, 7896, -829, -2340, 28006, 7936, -834, -2342, 27974, 7975, -839, -2345, 27942, 8015, -844,
+ -2347, 27909, 8055, -849, -2349, 27876, 8095, -854, -2352, 27844, 8135, -859, -2354, 27811, 8175, -864,
+ -2356, 27778, 8215, -869, -2359, 27747, 8255, -875, -2361, 27714, 8295, -880, -2363, 27681, 8335, -885,
+ -2365, 27648, 8375, -890, -2367, 27615, 8415, -895, -2369, 27581, 8456, -900, -2371, 27549, 8496, -906,
+ -2373, 27516, 8536, -911, -2375, 27482, 8577, -916, -2377, 27449, 8617, -921, -2379, 27415, 8658, -926,
+ -2381, 27382, 8699, -932, -2382, 27348, 8739, -937, -2384, 27314, 8780, -942, -2386, 27280, 8821, -947,
+ -2387, 27246, 8861, -952, -2389, 27213, 8902, -958, -2391, 27179, 8943, -963, -2392, 27144, 8984, -968,
+ -2394, 27110, 9025, -973, -2395, 27076, 9066, -979, -2397, 27042, 9107, -984, -2398, 27007, 9148, -989,
+ -2399, 26972, 9189, -994, -2401, 26939, 9230, -1000, -2402, 26904, 9271, -1005, -2403, 26868, 9313, -1010,
+ -2405, 26834, 9354, -1015, -2406, 26800, 9395, -1021, -2407, 26764, 9437, -1026, -2408, 26729, 9478, -1031,
+ -2409, 26693, 9520, -1036, -2410, 26659, 9561, -1042, -2411, 26623, 9603, -1047, -2412, 26588, 9644, -1052,
+ -2413, 26553, 9686, -1058, -2414, 26518, 9727, -1063, -2415, 26482, 9769, -1068, -2416, 26446, 9811, -1073,
+ -2417, 26411, 9853, -1079, -2418, 26376, 9894, -1084, -2419, 26340, 9936, -1089, -2419, 26304, 9978, -1095,
+ -2420, 26268, 10020, -1100, -2421, 26232, 10062, -1105, -2421, 26196, 10104, -1111, -2422, 26160, 10146, -1116,
+ -2422, 26123, 10188, -1121, -2423, 26088, 10230, -1127, -2424, 26052, 10272, -1132, -2424, 26015, 10314, -1137,
+ -2424, 25978, 10357, -1143, -2425, 25942, 10399, -1148, -2425, 25905, 10441, -1153, -2426, 25870, 10483, -1159,
+ -2426, 25832, 10526, -1164, -2426, 25795, 10568, -1169, -2426, 25758, 10611, -1175, -2427, 25722, 10653, -1180,
+ -2427, 25684, 10696, -1185, -2427, 25648, 10738, -1191, -2427, 25610, 10781, -1196, -2427, 25573, 10823, -1201,
+ -2427, 25536, 10866, -1207, -2427, 25499, 10908, -1212, -2427, 25461, 10951, -1217, -2427, 25424, 10994, -1223,
+ -2427, 25386, 11037, -1228, -2427, 25349, 11079, -1233, -2427, 25312, 11122, -1239, -2427, 25274, 11165, -1244,
+ -2427, 25236, 11208, -1249, -2426, 25198, 11251, -1255, -2426, 25160, 11294, -1260, -2426, 25122, 11337, -1265,
+ -2426, 25085, 11380, -1271, -2425, 25047, 11422, -1276, -2425, 25008, 11466, -1281, -2424, 24969, 11509, -1286,
+ -2424, 24932, 11552, -1292, -2423, 24893, 11595, -1297, -2423, 24855, 11638, -1302, -2422, 24817, 11681, -1308,
+ -2422, 24779, 11724, -1313, -2421, 24740, 11767, -1318, -2421, 24702, 11811, -1324, -2420, 24663, 11854, -1329,
+ -2419, 24624, 11897, -1334, -2419, 24586, 11941, -1340, -2418, 24547, 11984, -1345, -2417, 24508, 12027, -1350,
+ -2416, 24469, 12071, -1356, -2416, 24431, 12114, -1361, -2415, 24391, 12158, -1366, -2414, 24352, 12201, -1371,
+ -2413, 24314, 12244, -1377, -2412, 24274, 12288, -1382, -2411, 24234, 12332, -1387, -2410, 24196, 12375, -1393,
+ -2409, 24156, 12419, -1398, -2408, 24117, 12462, -1403, -2407, 24077, 12506, -1408, -2406, 24039, 12549, -1414,
+ -2405, 23999, 12593, -1419, -2404, 23959, 12637, -1424, -2402, 23918, 12681, -1429, -2401, 23880, 12724, -1435,
+ -2400, 23840, 12768, -1440, -2399, 23800, 12812, -1445, -2397, 23759, 12856, -1450, -2396, 23721, 12899, -1456,
+ -2395, 23681, 12943, -1461, -2393, 23640, 12987, -1466, -2392, 23600, 13031, -1471, -2391, 23561, 13075, -1477,
+ -2389, 23520, 13119, -1482, -2388, 23480, 13163, -1487, -2386, 23440, 13206, -1492, -2385, 23400, 13250, -1497,
+ -2383, 23360, 13294, -1503, -2381, 23319, 13338, -1508, -2380, 23279, 13382, -1513, -2378, 23238, 13426, -1518,
+ -2377, 23198, 13470, -1523, -2375, 23158, 13514, -1529, -2373, 23117, 13558, -1534, -2371, 23076, 13602, -1539,
+ -2370, 23035, 13647, -1544, -2368, 22994, 13691, -1549, -2366, 22953, 13735, -1554, -2364, 22913, 13779, -1560,
+ -2362, 22872, 13823, -1565, -2360, 22831, 13867, -1570, -2359, 22791, 13911, -1575, -2357, 22750, 13955, -1580,
+ -2355, 22708, 14000, -1585, -2353, 22667, 14044, -1590, -2351, 22626, 14088, -1595, -2349, 22585, 14132, -1600,
+ -2347, 22544, 14177, -1606, -2344, 22502, 14221, -1611, -2342, 22461, 14265, -1616, -2340, 22420, 14309, -1621,
+ -2338, 22378, 14354, -1626, -2336, 22337, 14398, -1631, -2334, 22296, 14442, -1636, -2331, 22254, 14486, -1641,
+ -2329, 22212, 14531, -1646, -2327, 22171, 14575, -1651, -2325, 22130, 14619, -1656, -2322, 22087, 14664, -1661,
+ -2320, 22046, 14708, -1666, -2317, 22004, 14752, -1671, -2315, 21962, 14797, -1676, -2313, 21921, 14841, -1681,
+ -2310, 21879, 14885, -1686, -2308, 21837, 14930, -1691, -2305, 21795, 14974, -1696, -2303, 21753, 15019, -1701,
+ -2300, 21711, 15063, -1706, -2298, 21669, 15107, -1710, -2295, 21626, 15152, -1715, -2292, 21584, 15196, -1720,
+ -2290, 21542, 15241, -1725, -2287, 21500, 15285, -1730, -2284, 21458, 15329, -1735, -2282, 21416, 15374, -1740,
+ -2279, 21374, 15418, -1745, -2276, 21331, 15463, -1750, -2274, 21289, 15507, -1754, -2271, 21246, 15552, -1759,
+ -2268, 21204, 15596, -1764, -2265, 21162, 15640, -1769, -2262, 21119, 15685, -1774, -2259, 21076, 15729, -1778,
+ -2257, 21034, 15774, -1783, -2254, 20992, 15818, -1788, -2251, 20949, 15863, -1793, -2248, 20906, 15907, -1797,
+ -2245, 20863, 15952, -1802, -2242, 20821, 15996, -1807, -2239, 20779, 16040, -1812, -2236, 20735, 16085, -1816,
+ -2233, 20693, 16129, -1821, -2230, 20650, 16174, -1826, -2227, 20607, 16218, -1830, -2223, 20563, 16263, -1835,
+ -2220, 20521, 16307, -1840, -2217, 20478, 16351, -1844, -2214, 20435, 16396, -1849, -2211, 20393, 16440, -1854,
+ -2208, 20349, 16485, -1858, -2204, 20306, 16529, -1863, -2201, 20262, 16574, -1867, -2198, 20220, 16618, -1872,
+ -2195, 20177, 16662, -1876, -2191, 20133, 16707, -1881, -2188, 20091, 16751, -1886, -2185, 20047, 16796, -1890,
+ -2181, 20004, 16840, -1895, -2178, 19961, 16884, -1899, -2174, 19917, 16929, -1904, -2171, 19874, 16973, -1908,
+ -2168, 19831, 17018, -1913, -2164, 19787, 17062, -1917, -2161, 19744, 17106, -1921, -2157, 19700, 17151, -1926,
+ -2154, 19657, 17195, -1930, -2150, 19614, 17239, -1935, -2146, 19569, 17284, -1939, -2143, 19526, 17328, -1943,
+ -2139, 19483, 17372, -1948, -2136, 19440, 17416, -1952, -2132, 19395, 17461, -1956, -2128, 19352, 17505, -1961,
+ -2125, 19309, 17549, -1965, -2121, 19265, 17593, -1969, -2117, 19221, 17638, -1974, -2114, 19178, 17682, -1978,
+ -2110, 19134, 17726, -1982, -2106, 19090, 17770, -1986, -2102, 19046, 17815, -1991, -2099, 19003, 17859, -1995,
+ -2095, 18959, 17903, -1999, -2091, 18915, 17947, -2003, -2087, 18871, 17991, -2007, -2083, 18827, 18035, -2011,
+ -2079, 18783, 18080, -2016, -2076, 18740, 18124, -2020, -2072, 18696, 18168, -2024, -2068, 18652, 18212, -2028,
+ -2064, 18608, 18256, -2032, -2060, 18564, 18300, -2036, -2056, 18520, 18344, -2040, -2052, 18476, 18388, -2044,
+ -2048, 18432, 18432, -2048, -2044, 18388, 18476, -2052, -2040, 18344, 18520, -2056, -2036, 18300, 18564, -2060,
+ -2032, 18256, 18608, -2064, -2028, 18212, 18652, -2068, -2024, 18168, 18696, -2072, -2020, 18124, 18740, -2076,
+ -2016, 18080, 18783, -2079, -2011, 18035, 18827, -2083, -2007, 17991, 18871, -2087, -2003, 17947, 18915, -2091,
+ -1999, 17903, 18959, -2095, -1995, 17859, 19003, -2099, -1991, 17815, 19046, -2102, -1986, 17770, 19090, -2106,
+ -1982, 17726, 19134, -2110, -1978, 17682, 19178, -2114, -1974, 17638, 19221, -2117, -1969, 17593, 19265, -2121,
+ -1965, 17549, 19309, -2125, -1961, 17505, 19352, -2128, -1956, 17461, 19395, -2132, -1952, 17416, 19440, -2136,
+ -1948, 17372, 19483, -2139, -1943, 17328, 19526, -2143, -1939, 17284, 19569, -2146, -1935, 17239, 19614, -2150,
+ -1930, 17195, 19657, -2154, -1926, 17151, 19700, -2157, -1921, 17106, 19744, -2161, -1917, 17062, 19787, -2164,
+ -1913, 17018, 19831, -2168, -1908, 16973, 19874, -2171, -1904, 16929, 19917, -2174, -1899, 16884, 19961, -2178,
+ -1895, 16840, 20004, -2181, -1890, 16796, 20047, -2185, -1886, 16751, 20091, -2188, -1881, 16707, 20133, -2191,
+ -1876, 16662, 20177, -2195, -1872, 16618, 20220, -2198, -1867, 16574, 20262, -2201, -1863, 16529, 20306, -2204,
+ -1858, 16485, 20349, -2208, -1854, 16440, 20393, -2211, -1849, 16396, 20435, -2214, -1844, 16351, 20478, -2217,
+ -1840, 16307, 20521, -2220, -1835, 16263, 20563, -2223, -1830, 16218, 20607, -2227, -1826, 16174, 20650, -2230,
+ -1821, 16129, 20693, -2233, -1816, 16085, 20735, -2236, -1812, 16040, 20779, -2239, -1807, 15996, 20821, -2242,
+ -1802, 15952, 20863, -2245, -1797, 15907, 20906, -2248, -1793, 15863, 20949, -2251, -1788, 15818, 20992, -2254,
+ -1783, 15774, 21034, -2257, -1778, 15729, 21076, -2259, -1774, 15685, 21119, -2262, -1769, 15640, 21162, -2265,
+ -1764, 15596, 21204, -2268, -1759, 15552, 21246, -2271, -1754, 15507, 21289, -2274, -1750, 15463, 21331, -2276,
+ -1745, 15418, 21374, -2279, -1740, 15374, 21416, -2282, -1735, 15329, 21458, -2284, -1730, 15285, 21500, -2287,
+ -1725, 15241, 21542, -2290, -1720, 15196, 21584, -2292, -1715, 15152, 21626, -2295, -1710, 15107, 21669, -2298,
+ -1706, 15063, 21711, -2300, -1701, 15019, 21753, -2303, -1696, 14974, 21795, -2305, -1691, 14930, 21837, -2308,
+ -1686, 14885, 21879, -2310, -1681, 14841, 21921, -2313, -1676, 14797, 21962, -2315, -1671, 14752, 22004, -2317,
+ -1666, 14708, 22046, -2320, -1661, 14664, 22087, -2322, -1656, 14619, 22130, -2325, -1651, 14575, 22171, -2327,
+ -1646, 14531, 22212, -2329, -1641, 14486, 22254, -2331, -1636, 14442, 22296, -2334, -1631, 14398, 22337, -2336,
+ -1626, 14354, 22378, -2338, -1621, 14309, 22420, -2340, -1616, 14265, 22461, -2342, -1611, 14221, 22502, -2344,
+ -1606, 14177, 22544, -2347, -1600, 14132, 22585, -2349, -1595, 14088, 22626, -2351, -1590, 14044, 22667, -2353,
+ -1585, 14000, 22708, -2355, -1580, 13955, 22750, -2357, -1575, 13911, 22791, -2359, -1570, 13867, 22831, -2360,
+ -1565, 13823, 22872, -2362, -1560, 13779, 22913, -2364, -1554, 13735, 22953, -2366, -1549, 13691, 22994, -2368,
+ -1544, 13647, 23035, -2370, -1539, 13602, 23076, -2371, -1534, 13558, 23117, -2373, -1529, 13514, 23158, -2375,
+ -1523, 13470, 23198, -2377, -1518, 13426, 23238, -2378, -1513, 13382, 23279, -2380, -1508, 13338, 23319, -2381,
+ -1503, 13294, 23360, -2383, -1497, 13250, 23400, -2385, -1492, 13206, 23440, -2386, -1487, 13163, 23480, -2388,
+ -1482, 13119, 23520, -2389, -1477, 13075, 23561, -2391, -1471, 13031, 23600, -2392, -1466, 12987, 23640, -2393,
+ -1461, 12943, 23681, -2395, -1456, 12899, 23721, -2396, -1450, 12856, 23759, -2397, -1445, 12812, 23800, -2399,
+ -1440, 12768, 23840, -2400, -1435, 12724, 23880, -2401, -1429, 12681, 23918, -2402, -1424, 12637, 23959, -2404,
+ -1419, 12593, 23999, -2405, -1414, 12549, 24039, -2406, -1408, 12506, 24077, -2407, -1403, 12462, 24117, -2408,
+ -1398, 12419, 24156, -2409, -1393, 12375, 24196, -2410, -1387, 12332, 24234, -2411, -1382, 12288, 24274, -2412,
+ -1377, 12244, 24314, -2413, -1371, 12201, 24352, -2414, -1366, 12158, 24391, -2415, -1361, 12114, 24431, -2416,
+ -1356, 12071, 24469, -2416, -1350, 12027, 24508, -2417, -1345, 11984, 24547, -2418, -1340, 11941, 24586, -2419,
+ -1334, 11897, 24624, -2419, -1329, 11854, 24663, -2420, -1324, 11811, 24702, -2421, -1318, 11767, 24740, -2421,
+ -1313, 11724, 24779, -2422, -1308, 11681, 24817, -2422, -1302, 11638, 24855, -2423, -1297, 11595, 24893, -2423,
+ -1292, 11552, 24932, -2424, -1286, 11509, 24969, -2424, -1281, 11466, 25008, -2425, -1276, 11422, 25047, -2425,
+ -1271, 11380, 25085, -2426, -1265, 11337, 25122, -2426, -1260, 11294, 25160, -2426, -1255, 11251, 25198, -2426,
+ -1249, 11208, 25236, -2427, -1244, 11165, 25274, -2427, -1239, 11122, 25312, -2427, -1233, 11079, 25349, -2427,
+ -1228, 11037, 25386, -2427, -1223, 10994, 25424, -2427, -1217, 10951, 25461, -2427, -1212, 10908, 25499, -2427,
+ -1207, 10866, 25536, -2427, -1201, 10823, 25573, -2427, -1196, 10781, 25610, -2427, -1191, 10738, 25648, -2427,
+ -1185, 10696, 25684, -2427, -1180, 10653, 25722, -2427, -1175, 10611, 25758, -2426, -1169, 10568, 25795, -2426,
+ -1164, 10526, 25832, -2426, -1159, 10483, 25870, -2426, -1153, 10441, 25905, -2425, -1148, 10399, 25942, -2425,
+ -1143, 10357, 25978, -2424, -1137, 10314, 26015, -2424, -1132, 10272, 26052, -2424, -1127, 10230, 26088, -2423,
+ -1121, 10188, 26123, -2422, -1116, 10146, 26160, -2422, -1111, 10104, 26196, -2421, -1105, 10062, 26232, -2421,
+ -1100, 10020, 26268, -2420, -1095, 9978, 26304, -2419, -1089, 9936, 26340, -2419, -1084, 9894, 26376, -2418,
+ -1079, 9853, 26411, -2417, -1073, 9811, 26446, -2416, -1068, 9769, 26482, -2415, -1063, 9727, 26518, -2414,
+ -1058, 9686, 26553, -2413, -1052, 9644, 26588, -2412, -1047, 9603, 26623, -2411, -1042, 9561, 26659, -2410,
+ -1036, 9520, 26693, -2409, -1031, 9478, 26729, -2408, -1026, 9437, 26764, -2407, -1021, 9395, 26800, -2406,
+ -1015, 9354, 26834, -2405, -1010, 9313, 26868, -2403, -1005, 9271, 26904, -2402, -1000, 9230, 26939, -2401,
+ -994, 9189, 26972, -2399, -989, 9148, 27007, -2398, -984, 9107, 27042, -2397, -979, 9066, 27076, -2395,
+ -973, 9025, 27110, -2394, -968, 8984, 27144, -2392, -963, 8943, 27179, -2391, -958, 8902, 27213, -2389,
+ -952, 8861, 27246, -2387, -947, 8821, 27280, -2386, -942, 8780, 27314, -2384, -937, 8739, 27348, -2382,
+ -932, 8699, 27382, -2381, -926, 8658, 27415, -2379, -921, 8617, 27449, -2377, -916, 8577, 27482, -2375,
+ -911, 8536, 27516, -2373, -906, 8496, 27549, -2371, -900, 8456, 27581, -2369, -895, 8415, 27615, -2367,
+ -890, 8375, 27648, -2365, -885, 8335, 27681, -2363, -880, 8295, 27714, -2361, -875, 8255, 27747, -2359,
+ -869, 8215, 27778, -2356, -864, 8175, 27811, -2354, -859, 8135, 27844, -2352, -854, 8095, 27876, -2349,
+ -849, 8055, 27909, -2347, -844, 8015, 27942, -2345, -839, 7975, 27974, -2342, -834, 7936, 28006, -2340,
+ -829, 7896, 28038, -2337, -823, 7856, 28070, -2335, -818, 7817, 28101, -2332, -813, 7777, 28133, -2329,
+ -808, 7738, 28165, -2327, -803, 7698, 28197, -2324, -798, 7659, 28228, -2321, -793, 7620, 28260, -2319,
+ -788, 7580, 28292, -2316, -783, 7541, 28323, -2313, -778, 7502, 28354, -2310, -773, 7463, 28385, -2307,
+ -768, 7424, 28416, -2304, -763, 7385, 28447, -2301, -758, 7346, 28478, -2298, -753, 7307, 28509, -2295,
+ -748, 7268, 28540, -2292, -743, 7230, 28570, -2289, -738, 7191, 28600, -2285, -733, 7152, 28631, -2282,
+ -728, 7114, 28661, -2279, -723, 7075, 28691, -2275, -718, 7037, 28721, -2272, -713, 6998, 28752, -2269,
+ -709, 6960, 28782, -2265, -704, 6922, 28812, -2262, -699, 6883, 28842, -2258, -694, 6845, 28872, -2255,
+ -689, 6807, 28901, -2251, -684, 6769, 28930, -2247, -679, 6731, 28960, -2244, -675, 6693, 28990, -2240,
+ -670, 6655, 29019, -2236, -665, 6617, 29048, -2232, -660, 6580, 29076, -2228, -655, 6542, 29105, -2224,
+ -650, 6504, 29135, -2221, -646, 6467, 29164, -2217, -641, 6429, 29193, -2213, -636, 6392, 29220, -2208,
+ -631, 6354, 29249, -2204, -627, 6317, 29278, -2200, -622, 6280, 29306, -2196, -617, 6243, 29334, -2192,
+ -613, 6206, 29363, -2188, -608, 6168, 29391, -2183, -603, 6131, 29419, -2179, -598, 6094, 29446, -2174,
+ -594, 6058, 29474, -2170, -589, 6021, 29501, -2165, -584, 5984, 29529, -2161, -580, 5947, 29557, -2156,
+ -575, 5911, 29584, -2152, -571, 5874, 29612, -2147, -566, 5838, 29638, -2142, -561, 5801, 29666, -2138,
+ -557, 5765, 29693, -2133, -552, 5729, 29719, -2128, -548, 5692, 29747, -2123, -543, 5656, 29773, -2118,
+ -539, 5620, 29800, -2113, -534, 5584, 29826, -2108, -530, 5548, 29853, -2103, -525, 5512, 29879, -2098,
+ -521, 5476, 29906, -2093, -516, 5441, 29931, -2088, -512, 5405, 29958, -2083, -507, 5369, 29983, -2077,
+ -503, 5334, 30009, -2072, -499, 5298, 30036, -2067, -494, 5263, 30060, -2061, -490, 5228, 30086, -2056,
+ -485, 5192, 30111, -2050, -481, 5157, 30137, -2045, -477, 5122, 30162, -2039, -472, 5087, 30187, -2034,
+ -468, 5052, 30212, -2028, -464, 5017, 30237, -2022, -459, 4982, 30262, -2017, -455, 4948, 30286, -2011,
+ -451, 4913, 30311, -2005, -447, 4878, 30336, -1999, -442, 4844, 30359, -1993, -438, 4809, 30384, -1987,
+ -434, 4775, 30408, -1981, -430, 4741, 30432, -1975, -426, 4706, 30457, -1969, -421, 4672, 30480, -1963,
+ -417, 4638, 30503, -1956, -413, 4604, 30527, -1950, -409, 4570, 30551, -1944, -405, 4536, 30575, -1938,
+ -401, 4502, 30598, -1931, -397, 4469, 30621, -1925, -393, 4435, 30644, -1918, -389, 4402, 30667, -1912,
+ -385, 4368, 30690, -1905, -381, 4335, 30713, -1899, -377, 4301, 30736, -1892, -373, 4268, 30758, -1885,
+ -369, 4235, 30780, -1878, -365, 4202, 30803, -1872, -361, 4169, 30825, -1865, -357, 4136, 30847, -1858,
+ -353, 4103, 30869, -1851, -349, 4070, 30891, -1844, -345, 4038, 30912, -1837, -341, 4005, 30934, -1830,
+ -338, 3973, 30956, -1823, -334, 3940, 30977, -1815, -330, 3908, 30998, -1808, -326, 3875, 31020, -1801,
+ -322, 3843, 31040, -1793, -319, 3811, 31062, -1786, -315, 3779, 31083, -1779, -311, 3747, 31103, -1771,
+ -307, 3715, 31124, -1764, -304, 3683, 31145, -1756, -300, 3652, 31164, -1748, -296, 3620, 31185, -1741,
+ -293, 3589, 31205, -1733, -289, 3557, 31225, -1725, -286, 3526, 31245, -1717, -282, 3495, 31264, -1709,
+ -278, 3463, 31285, -1702, -275, 3432, 31305, -1694, -271, 3401, 31324, -1686, -268, 3370, 31343, -1677,
+ -264, 3339, 31362, -1669, -261, 3309, 31381, -1661, -257, 3278, 31400, -1653, -254, 3247, 31420, -1645,
+ -251, 3217, 31438, -1636, -247, 3186, 31457, -1628, -244, 3156, 31476, -1620, -240, 3126, 31493, -1611,
+ -237, 3096, 31512, -1603, -234, 3066, 31530, -1594, -231, 3036, 31548, -1585, -227, 3006, 31566, -1577,
+ -224, 2976, 31584, -1568, -221, 2946, 31602, -1559, -218, 2917, 31619, -1550, -214, 2887, 31637, -1542,
+ -211, 2858, 31654, -1533, -208, 2828, 31672, -1524, -205, 2799, 31689, -1515, -202, 2770, 31706, -1506,
+ -199, 2741, 31722, -1496, -196, 2712, 31739, -1487, -192, 2683, 31755, -1478, -189, 2654, 31772, -1469,
+ -186, 2626, 31787, -1459, -183, 2597, 31804, -1450, -180, 2568, 31820, -1440, -177, 2540, 31836, -1431,
+ -175, 2512, 31852, -1421, -172, 2483, 31869, -1412, -169, 2455, 31884, -1402, -166, 2427, 31899, -1392,
+ -163, 2399, 31915, -1383, -160, 2371, 31930, -1373, -157, 2344, 31944, -1363, -155, 2316, 31960, -1353,
+ -152, 2289, 31974, -1343, -149, 2261, 31989, -1333, -146, 2234, 32003, -1323, -144, 2206, 32019, -1313,
+ -141, 2179, 32033, -1303, -138, 2152, 32047, -1293, -136, 2125, 32061, -1282, -133, 2098, 32075, -1272,
+ -131, 2072, 32089, -1262, -128, 2045, 32102, -1251, -125, 2018, 32116, -1241, -123, 1992, 32129, -1230,
+ -120, 1965, 32142, -1219, -118, 1939, 32156, -1209, -115, 1913, 32168, -1198, -113, 1887, 32181, -1187,
+ -111, 1861, 32194, -1176, -108, 1835, 32207, -1166, -106, 1809, 32220, -1155, -104, 1783, 32233, -1144,
+ -101, 1758, 32244, -1133, -99, 1732, 32256, -1121, -97, 1707, 32268, -1110, -94, 1682, 32279, -1099,
+ -92, 1657, 32291, -1088, -90, 1631, 32303, -1076, -88, 1607, 32314, -1065, -86, 1582, 32326, -1054,
+ -84, 1557, 32337, -1042, -81, 1532, 32348, -1031, -79, 1508, 32358, -1019, -77, 1483, 32369, -1007,
+ -75, 1459, 32380, -996, -73, 1435, 32390, -984, -71, 1411, 32400, -972, -69, 1387, 32410, -960,
+ -67, 1363, 32420, -948, -66, 1339, 32431, -936, -64, 1315, 32441, -924, -62, 1291, 32451, -912,
+ -60, 1268, 32460, -900, -58, 1245, 32469, -888, -56, 1221, 32479, -876, -55, 1198, 32488, -863,
+ -53, 1175, 32497, -851, -51, 1152, 32505, -838, -50, 1129, 32515, -826, -48, 1107, 32522, -813,
+ -46, 1084, 32531, -801, -45, 1061, 32540, -788, -43, 1039, 32547, -775, -42, 1017, 32555, -762,
+ -40, 995, 32563, -750, -39, 972, 32572, -737, -37, 951, 32578, -724, -36, 929, 32586, -711,
+ -34, 907, 32593, -698, -33, 885, 32601, -685, -32, 864, 32607, -671, -30, 842, 32614, -658,
+ -29, 821, 32621, -645, -28, 800, 32627, -631, -26, 779, 32633, -618, -25, 758, 32640, -605,
+ -24, 737, 32646, -591, -23, 716, 32652, -577, -22, 696, 32658, -564, -21, 675, 32664, -550,
+ -20, 655, 32669, -536, -18, 635, 32673, -522, -17, 614, 32679, -508, -16, 594, 32685, -495,
+ -16, 575, 32690, -481, -15, 555, 32694, -466, -14, 535, 32699, -452, -13, 515, 32704, -438,
+ -12, 496, 32708, -424, -11, 477, 32712, -410, -10, 457, 32716, -395, -10, 438, 32721, -381,
+ -9, 419, 32724, -366, -8, 401, 32727, -352, -7, 382, 32730, -337, -7, 363, 32734, -322,
+ -6, 345, 32737, -308, -6, 326, 32741, -293, -5, 308, 32743, -278, -4, 290, 32745, -263,
+ -4, 272, 32748, -248, -3, 254, 32750, -233, -3, 236, 32753, -218, -3, 218, 32756, -203,
+ -2, 201, 32757, -188, -2, 184, 32758, -172, -2, 166, 32761, -157, -1, 149, 32761, -141,
+ -1, 132, 32763, -126, -1, 115, 32764, -110, -1, 98, 32766, -95, 0, 82, 32765, -79,
+ 0, 65, 32767, -64, 0, 49, 32767, -48, 0, 32, 32767, -32, 0, 16, 32767, -16
};
#endif
--- a/src/ft2_intrp_table.h
+++ b/src/ft2_intrp_table.h
@@ -13,8 +13,8 @@
#else
-#define CUBIC_PHASES 512
-#define CUBIC_PHASES_BITS 9
+#define CUBIC_PHASES 1024
+#define CUBIC_PHASES_BITS 10
#endif
--- a/src/ft2_mix_macros.h
+++ b/src/ft2_mix_macros.h
@@ -124,7 +124,7 @@
*audioMixL++ += sample; \
*audioMixR++ += sample; \
-// 4-tap cubic spline interpolation (default - slower than linear, but better quality)
+// 4-tap cubic spline interpolation
// in: int32_t s0,s1,s2,s3 = -128..127 | f = 0..65535 (frac) | out: 16-bit s0 (will exceed 16-bits because of overshoot)
#define INTERPOLATE8(s0, s1, s2, s3, f) \
--- a/src/ft2_palette.c
+++ b/src/ft2_palette.c
@@ -27,7 +27,7 @@
void setPal16(pal16 *p, bool redrawScreen)
{
-#define LOOP_PIN_COL_SUB 75
+#define LOOP_PIN_COL_SUB 96
#define TEXT_MARK_COLOR 0x0078D7
#define BOX_SELECT_COLOR 0x7F7F7F
--- a/src/ft2_pattern_ed.c
+++ b/src/ft2_pattern_ed.c
@@ -2155,9 +2155,10 @@
}
else
{
- if (val > 999)
- val = 999;
+ if (val > MAX_BPM)
+ val = MAX_BPM;
+ assert(MAX_BPM == 999);
str[0] = '0' + (char)(val / 100);
str[1] = '0' + ((val / 10) % 10);
str[2] = '0' + (val % 10);
--- a/src/ft2_replayer.c
+++ b/src/ft2_replayer.c
@@ -30,7 +30,7 @@
** FT2 obviously didn't have such big tables.
*/
-static uint32_t musicTimeTab[1000];
+static uint32_t musicTimeTab[MAX_BPM+1];
static uint64_t period2ScopeDeltaTab[65536];
static double dLogTab[768], dLogTabMul[32], dAudioRateFactor;
@@ -392,27 +392,47 @@
dLogTabMul[i] = exp2(-i);
}
-void calcReplayRate(int32_t rate)
+void calcReplayRate(int32_t audioFreq)
{
int32_t i;
- if (rate == 0)
+ if (audioFreq == 0)
return;
-
- dAudioRateFactor = (double)MIXER_FRAC_SCALE / rate;
- audio.quickVolSizeVal = rate / 200; // FT2 truncates here
+ dAudioRateFactor = (double)MIXER_FRAC_SCALE / audioFreq;
+
+ audio.quickVolSizeVal = audioFreq / 200; // FT2 truncates here
audio.rampQuickVolMul = (int32_t)(((UINT32_MAX + 1.0) / audio.quickVolSizeVal) + 0.5);
- audio.dSpeedValMul = editor.dPerfFreq / rate; // for audio/video sync
+ audio.dSpeedValMul = editor.dPerfFreq / audioFreq; // for audio/video sync
+ /* Calculate tables to prevent floating point operations on systems that
+ ** might have a slow FPU. This is quite hackish and not really needed,
+ ** but it doesn't take up THAT much RAM anyway.
+ */
+
// calculate table used to count replayer time (displayed as hours/minutes/seconds)
- const double dMul = (UINT32_MAX + 1.0) / rate;
+ const double dMul = (UINT32_MAX + 1.0) / audioFreq;
+
+ audio.speedValTab[0] = 0;
musicTimeTab[0] = UINT32_MAX;
- for (i = 1; i < 1000; i++)
+ audio.rampSpeedValMulTab[0] = UINT32_MAX;
+ audio.tickTimeLengthTab[0] = (uint64_t)UINT32_MAX << 32;
+
+ const double dTickTimeLenMul = audio.dSpeedValMul * (UINT32_MAX + 1.0);
+ for (i = 1; i <= MAX_BPM; i++)
{
- uint32_t samplesPerTick = ((rate + rate) + (rate >> 1)) / i; // exactly how setSpeed() calculates it
- const double dVal = samplesPerTick * dMul;
- musicTimeTab[i] = (uint32_t)(dVal + 0.5);
+ int32_t samplesPerTick = (int32_t)(((audioFreq * 2.5) / i) + 0.5); // rounded
+
+ audio.speedValTab[i] = samplesPerTick;
+
+ // used for song playback counter (hh:mm:ss)
+ musicTimeTab[i] = (uint32_t)((samplesPerTick * dMul) + 0.5);
+
+ // number of samples per tick -> tick length for performance counter (syncing visuals to audio)
+ audio.tickTimeLengthTab[i] = (uint64_t)(samplesPerTick * dTickTimeLenMul);
+
+ // for calculating volume ramp length for "tick" ramps
+ audio.rampSpeedValMulTab[i] = (int32_t)(((UINT32_MAX + 1.0) / samplesPerTick) + 0.5);
}
calcPeriod2DeltaTables();
@@ -2063,7 +2083,8 @@
if (song.pattDelTime2 > 0)
{
- if (--song.pattDelTime2 > 0)
+ song.pattDelTime2--;
+ if (song.pattDelTime2 > 0)
song.pattPos--;
}
@@ -2086,13 +2107,10 @@
song.songPos = 0;
bxxOverflow = false;
}
- else
+ else if (++song.songPos >= song.len)
{
- if (++song.songPos >= song.len)
- {
- editor.wavReachedEndFlag = true;
- song.songPos = song.repS;
- }
+ editor.wavReachedEndFlag = true;
+ song.songPos = song.repS;
}
assert(song.songPos <= 255);
@@ -2135,11 +2153,13 @@
return;
}
- assert(song.speed >= 1 && song.speed <= 999);
- song.musicTime64 += musicTimeTab[song.speed]; // for playback counter
+ assert(song.speed >= MIN_BPM && song.speed <= MAX_BPM);
+ song.musicTime64 += musicTimeTab[song.speed]; // for song playback counter (hh:mm:ss)
readNewNote = false;
- if (--song.timer == 0)
+
+ song.timer--;
+ if (song.timer == 0)
{
song.timer = song.tempo;
readNewNote = true;
@@ -3240,8 +3260,6 @@
// handle channel sync queue
while (chQueueClearing);
-
- chQueueReading = true;
while (chQueueReadSize() > 0)
{
if (frameTime64 < getChQueueTimestamp())
@@ -3257,10 +3275,10 @@
if (!chQueuePop())
break;
}
- chQueueReading = false;
- /* extra validation because of possible issues when the buffer is full
- ** and positions are being reset, which is not entirely thread safe. */
+ /* Extra validation because of possible issues when the buffer is full
+ ** and positions are being reset, which is not entirely thread safe.
+ */
if (chSyncEntry != NULL && chSyncEntry->timestamp == 0)
chSyncEntry = NULL;
@@ -3267,8 +3285,6 @@
// handle pattern sync queue
while (pattQueueClearing);
-
- pattQueueReading = true;
while (pattQueueReadSize() > 0)
{
if (frameTime64 < getPattQueueTimestamp())
@@ -3281,10 +3297,10 @@
if (!pattQueuePop())
break;
}
- pattQueueReading = false;
- /* extra validation because of possible issues when the buffer is full
- ** and positions are being reset, which is not entirely thread safe. */
+ /* Extra validation because of possible issues when the buffer is full
+ ** and positions are being reset, which is not entirely thread safe.
+ */
if (pattSyncEntry != NULL && pattSyncEntry->timestamp == 0)
pattSyncEntry = NULL;
--- a/src/ft2_replayer.h
+++ b/src/ft2_replayer.h
@@ -33,7 +33,8 @@
};
// DO NOT TOUCH!
-#define MIN_BPM 32
+#define MIN_BPM 1
+#define MAX_BPM 999
#define MAX_VOICES 32
#define TRACK_WIDTH (5 * MAX_VOICES)
#define MAX_NOTES ((12 * 10 * 16) + 16)
--- a/src/ft2_sample_loader.c
+++ b/src/ft2_sample_loader.c
@@ -845,7 +845,7 @@
bodyLen = filesize - bodyPtr;
fseek(f, vhdrPtr, SEEK_SET);
- fread(&sampleLoopStart, 4, 1, f); sampleLoopStart = SWAP32(sampleLoopStart);
+ fread(&sampleLoopStart, 4, 1, f); sampleLoopStart = SWAP32(sampleLoopStart);
fread(&sampleLoopLength, 4, 1, f); sampleLoopLength = SWAP32(sampleLoopLength);
fseek(f, 4, SEEK_CUR);
fread(&sampleRate, 2, 1, f); sampleRate = SWAP16(sampleRate);
--- a/src/ft2_wav_renderer.c
+++ b/src/ft2_wav_renderer.c
@@ -168,7 +168,7 @@
{
uint32_t maxSamplesPerTick, sampleSize;
- maxSamplesPerTick = ((frq * 5) / 2) / MIN_BPM; // absolute max samples per tidck
+ maxSamplesPerTick = (int32_t)ceil((frq * 2.5) / MIN_BPM); // absolute max samples per tick
sampleSize = (WDBitDepth / 8) * 2; // 2 channels
// *2 for stereo