Browse Source

Add apps missing source

Willy-JL 2 năm trước cách đây
mục cha
commit
0a40eca71b

+ 11 - 0
multi_dice/application.fam

@@ -0,0 +1,11 @@
+App(
+    appid="multi_dice",
+    name="Multi-Dice",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="dice_app",
+    cdefines=["APP_DICE"],
+    requires=["gui"],
+    stack_size=2 * 1024,
+    fap_icon="dice.png",
+    fap_category="Games",
+)

+ 558 - 0
multi_dice/dice.c

@@ -0,0 +1,558 @@
+#include <furi.h>
+#include <furi_hal.h>
+#include "furi_hal_random.h"
+#include <gui/elements.h>
+#include <gui/gui.h>
+#include <input/input.h>
+
+#define TAG "Dice Roller"
+
+typedef enum {
+    EventTypeTick,
+    EventTypeKey,
+} EventType;
+
+typedef struct {
+    EventType type;
+    InputEvent input;
+} PluginEvent;
+
+typedef struct {
+    FuriMutex* mutex;
+    FuriMessageQueue* event_queue;
+    FuriHalRtcDateTime datetime;
+    uint8_t diceSelect;
+    uint8_t diceQty;
+    uint8_t diceRoll;
+    uint8_t playerOneScore;
+    uint8_t playerTwoScore;
+    char rollTime[1][15];
+    char diceType[1][11];
+    char strings[5][45];
+    char theScores[1][45];
+    bool letsRoll;
+} DiceState;
+
+static void dice_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
+    furi_assert(event_queue);
+    PluginEvent event = {.type = EventTypeKey, .input = *input_event};
+    furi_message_queue_put(event_queue, &event, FuriWaitForever);
+}
+
+static void dice_render_callback(Canvas* const canvas, void* ctx) {
+    DiceState* state = ctx;
+    if(furi_mutex_acquire(state->mutex, 200) != FuriStatusOk) {
+        // Can't obtain mutex, requeue render
+        PluginEvent event = {.type = EventTypeTick};
+        furi_message_queue_put(state->event_queue, &event, 0);
+        return;
+    }
+
+    canvas_set_font(canvas, FontSecondary);
+    if(state->diceSelect < 220) {
+        if(state->diceQty == 1) {
+            elements_button_left(canvas, "x1");
+        } else if(state->diceQty == 2) {
+            elements_button_left(canvas, "x2");
+        } else if(state->diceQty == 3) {
+            elements_button_left(canvas, "x3");
+        } else if(state->diceQty == 4) {
+            elements_button_left(canvas, "x4");
+        } else if(state->diceQty == 5) {
+            elements_button_left(canvas, "x5");
+        } else if(state->diceQty == 6) {
+            elements_button_left(canvas, "x6");
+        }
+    }
+    if(state->letsRoll) {
+        furi_hal_rtc_get_datetime(&state->datetime);
+        uint8_t hour = state->datetime.hour;
+        char strAMPM[3];
+        snprintf(strAMPM, sizeof(strAMPM), "%s", "AM");
+        if(hour > 12) {
+            hour -= 12;
+            snprintf(strAMPM, sizeof(strAMPM), "%s", "PM");
+        }
+        snprintf(
+            state->rollTime[0],
+            sizeof(state->rollTime[0]),
+            "%.2d:%.2d:%.2d %s",
+            hour,
+            state->datetime.minute,
+            state->datetime.second,
+            strAMPM);
+        if(state->diceSelect == 229) {
+            const char* eightBall[] = {
+                "It is certain",
+                "Without a doubt",
+                "You may rely on it",
+                "Yes definitely",
+                "It is decidedly so",
+                "As I see it, yes",
+                "Most likely",
+                "Yes",
+                "Outlook good",
+                "Signs point to yes",
+                "Reply hazy try again",
+                "Better not tell you now",
+                "Ask again later",
+                "Cannot predict now",
+                "Concentrate and ask again",
+                "Don't count on it",
+                "Outlook not so good",
+                "My sources say no",
+                "Very doubtful",
+                "My reply is no"};
+            state->diceRoll =
+                ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG
+            snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "8BALL");
+            snprintf(
+                state->strings[0],
+                sizeof(state->strings[0]),
+                "%s at %s",
+                state->diceType[0],
+                state->rollTime[0]);
+            uint8_t d1_i = rand() % COUNT_OF(eightBall);
+            snprintf(state->strings[1], sizeof(state->strings[1]), "%s", eightBall[d1_i]);
+        } else if(state->diceSelect == 228) {
+            const char* eightBall[] = {
+                "I'd do it.",
+                "Hell, yeah!",
+                "You bet your life!",
+                "What are you waiting for?",
+                "You could do worse things.",
+                "Sure, I won't tell.",
+                "Yeah, you got this. Would I lie to you?",
+                "Looks like fun to me. ",
+                "Yeah, sure, why not?",
+                "DO IT!!!",
+                "Who's it gonna hurt?",
+                "Can you blame someone else?",
+                "Ask me again later.",
+                "Maybe, maybe not, I can't tell right now. ",
+                "Are you the betting type? ",
+                "Don't blame me if you get caught.",
+                "What have you got to lose?",
+                "I wouldn't if I were you.",
+                "My money's on the snowball.",
+                "Oh Hell no!"};
+            state->diceRoll =
+                ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG
+            snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "Devil Ball");
+            snprintf(
+                state->strings[0],
+                sizeof(state->strings[0]),
+                "%s at %s",
+                state->diceType[0],
+                state->rollTime[0]);
+            uint8_t d1_i = rand() % COUNT_OF(eightBall);
+            snprintf(state->strings[1], sizeof(state->strings[1]), "%s", eightBall[d1_i]);
+        } else if(state->diceSelect == 230) {
+            const char* diceOne[] = {
+                "Nibble",
+                "Massage",
+                "Touch",
+                "Caress",
+                "Pet",
+                "Fondle",
+                "Suck",
+                "Lick",
+                "Blow",
+                "Kiss",
+                "???"};
+            const char* diceTwo[] = {
+                "Navel",
+                "Ears",
+                "Lips",
+                "Neck",
+                "Hand",
+                "Thigh",
+                "Nipple",
+                "Breasts",
+                "???",
+                "Genitals"};
+            state->diceRoll =
+                ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG
+            snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "SEX?");
+            snprintf(
+                state->strings[0],
+                sizeof(state->strings[0]),
+                "%s at %s",
+                state->diceType[0],
+                state->rollTime[0]);
+            uint8_t d1_i = rand() % COUNT_OF(diceOne);
+            uint8_t d2_i = rand() % COUNT_OF(diceTwo);
+            snprintf(
+                state->strings[1],
+                sizeof(state->strings[1]),
+                "%s %s",
+                diceOne[d1_i],
+                diceTwo[d2_i]);
+        } else if(state->diceSelect == 231) {
+            const char* deckOne[] = {"2H", "2C", "2D", "2S", "3H", "3C",  "3D",  "3S",  "4H",
+                                     "4C", "4D", "4S", "5H", "5C", "5D",  "5S",  "6H",  "6C",
+                                     "6D", "6S", "7H", "7C", "7D", "7S",  "8H",  "8C",  "8D",
+                                     "8S", "9H", "9C", "9D", "9S", "10H", "10C", "10D", "10S",
+                                     "JH", "JC", "JD", "JS", "QH", "QC",  "QD",  "QS",  "KH",
+                                     "KC", "KD", "KS", "AH", "AC", "AD",  "AS"};
+            char* deckTwo[] = {"2H", "2C", "2D", "2S", "3H", "3C",  "3D",  "3S",  "4H",
+                               "4C", "4D", "4S", "5H", "5C", "5D",  "5S",  "6H",  "6C",
+                               "6D", "6S", "7H", "7C", "7D", "7S",  "8H",  "8C",  "8D",
+                               "8S", "9H", "9C", "9D", "9S", "10H", "10C", "10D", "10S",
+                               "JH", "JC", "JD", "JS", "QH", "QC",  "QD",  "QS",  "KH",
+                               "KC", "KD", "KS", "AH", "AC", "AD"}; // ONE LESS SINCE ONE WILL BE REMOVED
+            state->diceRoll =
+                ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG
+            snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "WAR!");
+            snprintf(
+                state->strings[0],
+                sizeof(state->strings[0]),
+                "%s at %s",
+                state->diceType[0],
+                state->rollTime[0]);
+            uint8_t d1_i = rand() % COUNT_OF(deckOne);
+            // INITIALIZE WITH PLACEHOLDERS TO AVOID MAYBE UNINITIALIZED ERROR
+            for(uint8_t i = 0; i < COUNT_OF(deckOne); i++) {
+                if(i < d1_i) {
+                    snprintf(deckTwo[i], 8, "%s", deckOne[i]);
+                } else if(i > d1_i) {
+                    snprintf(deckTwo[i - 1], 8, "%s", deckOne[i]);
+                }
+            }
+            uint8_t d2_i = rand() % COUNT_OF(deckTwo);
+            if(d1_i > d2_i) {
+                state->playerOneScore++;
+                snprintf(
+                    state->strings[1],
+                    sizeof(state->strings[1]),
+                    "%s > %s",
+                    deckOne[d1_i],
+                    deckTwo[d2_i]);
+            } else {
+                state->playerTwoScore++;
+                snprintf(
+                    state->strings[1],
+                    sizeof(state->strings[1]),
+                    "%s < %s",
+                    deckOne[d1_i],
+                    deckTwo[d2_i]);
+            }
+        } else if(state->diceSelect == 232) {
+            const char* diceOne[] = {
+                "You", "You choose", "Nobody", "Everyone", "Nose goes", "Player to your right"};
+            const char* diceTwo[] = {
+                "take a tiny toke",
+                "just chill",
+                "take 2 tokes",
+                "take a huge hit",
+                "bogart it",
+                "take a puff"};
+            const char* diceThree[] = {
+                "while humming a tune",
+                "with your eyes closed",
+                "on your knees",
+                "while holding your nose",
+                "while spinning in a circle",
+                "in slow motion"};
+            const char* diceFour[] = {
+                "twice",
+                "then tell a joke",
+                "then laugh as hard as you can",
+                "with the player to your left",
+                "then sing a song",
+                "then do a dance"};
+            state->diceRoll =
+                ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG
+            snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "WEED!");
+            snprintf(
+                state->strings[0],
+                sizeof(state->strings[0]),
+                "%s at %s",
+                state->diceType[0],
+                state->rollTime[0]);
+            uint8_t d1_i = rand() % COUNT_OF(diceOne);
+            uint8_t d2_i = rand() % COUNT_OF(diceTwo);
+            uint8_t d3_i = rand() % COUNT_OF(diceThree);
+            uint8_t d4_i = rand() % COUNT_OF(diceFour);
+            snprintf(state->strings[1], sizeof(state->strings[1]), "%s", diceOne[d1_i]);
+            snprintf(state->strings[2], sizeof(state->strings[2]), "%s", diceTwo[d2_i]);
+            snprintf(state->strings[3], sizeof(state->strings[3]), "%s", diceThree[d3_i]);
+            snprintf(state->strings[4], sizeof(state->strings[4]), "%s", diceFour[d4_i]);
+        } else {
+            state->diceRoll = ((rand() % state->diceSelect) + 1);
+            snprintf(
+                state->diceType[0], sizeof(state->diceType[0]), "%s%d", "d", state->diceSelect);
+            snprintf(
+                state->strings[0],
+                sizeof(state->strings[0]),
+                "%d%s at %s",
+                state->diceQty,
+                state->diceType[0],
+                state->rollTime[0]);
+            if(state->diceQty == 1) {
+                snprintf(state->strings[1], sizeof(state->strings[1]), "%d", state->diceRoll);
+            } else if(state->diceQty == 2) {
+                snprintf(
+                    state->strings[1],
+                    sizeof(state->strings[1]),
+                    "%d %d",
+                    state->diceRoll,
+                    ((rand() % state->diceSelect) + 1));
+            } else if(state->diceQty == 3) {
+                snprintf(
+                    state->strings[1],
+                    sizeof(state->strings[1]),
+                    "%d %d %d",
+                    state->diceRoll,
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1));
+            } else if(state->diceQty == 4) {
+                snprintf(
+                    state->strings[1],
+                    sizeof(state->strings[1]),
+                    "%d %d %d %d",
+                    state->diceRoll,
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1));
+            } else if(state->diceQty == 5) {
+                snprintf(
+                    state->strings[1],
+                    sizeof(state->strings[1]),
+                    "%d %d %d %d %d",
+                    state->diceRoll,
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1));
+            } else if(state->diceQty == 6) {
+                snprintf(
+                    state->strings[1],
+                    sizeof(state->strings[1]),
+                    "%d %d %d %d %d %d",
+                    state->diceRoll,
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1),
+                    ((rand() % state->diceSelect) + 1));
+            }
+        }
+        state->letsRoll = false;
+    }
+    furi_mutex_release(state->mutex);
+    if(state->diceRoll != 0) {
+        if(state->diceSelect == 232) {
+            canvas_set_font(canvas, FontSecondary);
+            canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]);
+            canvas_draw_str_aligned(canvas, 64, 18, AlignCenter, AlignCenter, state->strings[1]);
+            canvas_draw_str_aligned(canvas, 64, 26, AlignCenter, AlignCenter, state->strings[2]);
+            canvas_draw_str_aligned(canvas, 64, 34, AlignCenter, AlignCenter, state->strings[3]);
+            canvas_draw_str_aligned(canvas, 64, 42, AlignCenter, AlignCenter, state->strings[4]);
+        } else if(state->diceSelect == 228 || state->diceSelect == 229) {
+            canvas_set_font(canvas, FontBatteryPercent);
+            canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignCenter, state->strings[1]);
+            canvas_set_font(canvas, FontSecondary);
+            canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]);
+        } else {
+            canvas_set_font(canvas, FontPrimary);
+            canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignCenter, state->strings[1]);
+            canvas_set_font(canvas, FontSecondary);
+            canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]);
+        }
+        if(state->diceSelect == 231 &&
+           !(state->playerOneScore == 0 && state->playerTwoScore == 0)) {
+            canvas_set_font(canvas, FontSecondary);
+            snprintf(
+                state->theScores[0],
+                sizeof(state->theScores[0]),
+                "%d                                   %d",
+                state->playerOneScore,
+                state->playerTwoScore);
+            canvas_draw_str_aligned(canvas, 64, 34, AlignCenter, AlignCenter, state->theScores[0]);
+        }
+    }
+    if(state->diceSelect == 229 || state->diceSelect == 228) {
+        elements_button_center(canvas, "Shake");
+    } else if(state->diceSelect == 231) {
+        elements_button_center(canvas, "Draw");
+    } else {
+        elements_button_center(canvas, "Roll");
+    }
+    if(state->diceSelect == 2) {
+        elements_button_right(canvas, "d2");
+    } else if(state->diceSelect == 3) {
+        elements_button_right(canvas, "d3");
+    } else if(state->diceSelect == 4) {
+        elements_button_right(canvas, "d4");
+    } else if(state->diceSelect == 6) {
+        elements_button_right(canvas, "d6");
+    } else if(state->diceSelect == 8) {
+        elements_button_right(canvas, "d8");
+    } else if(state->diceSelect == 10) {
+        elements_button_right(canvas, "d10");
+    } else if(state->diceSelect == 12) {
+        elements_button_right(canvas, "d12");
+    } else if(state->diceSelect == 20) {
+        elements_button_right(canvas, "d20");
+    } else if(state->diceSelect == 59) {
+        elements_button_right(canvas, "d59");
+    } else if(state->diceSelect == 69) {
+        elements_button_right(canvas, "d69");
+    } else if(state->diceSelect == 100) {
+        elements_button_right(canvas, "d100");
+    } else if(state->diceSelect == 229) {
+        elements_button_right(canvas, "8BALL");
+    } else if(state->diceSelect == 228) {
+        elements_button_right(canvas, "DBALL");
+    } else if(state->diceSelect == 230) {
+        elements_button_right(canvas, "SEX");
+    } else if(state->diceSelect == 231) {
+        elements_button_right(canvas, "WAR");
+    } else if(state->diceSelect == 232) {
+        elements_button_right(canvas, "WEED");
+    }
+}
+
+static void dice_state_init(DiceState* const state) {
+    memset(state, 0, sizeof(DiceState));
+    furi_hal_rtc_get_datetime(&state->datetime);
+    state->diceSelect = 20;
+    state->diceQty = 1;
+    state->diceRoll = 0;
+    state->playerOneScore = 0;
+    state->playerTwoScore = 0;
+    state->letsRoll = false;
+}
+
+static void dice_tick(void* ctx) {
+    furi_assert(ctx);
+    FuriMessageQueue* event_queue = ctx;
+    PluginEvent event = {.type = EventTypeTick};
+    // It's OK to lose this event if system overloaded
+    furi_message_queue_put(event_queue, &event, 0);
+}
+
+int32_t dice_app(void* p) {
+    UNUSED(p);
+    DiceState* plugin_state = malloc(sizeof(DiceState));
+    dice_state_init(plugin_state);
+    plugin_state->event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
+    if(plugin_state->event_queue == NULL) {
+        FURI_LOG_E(TAG, "cannot create event queue\n");
+        free(plugin_state);
+        return 255;
+    }
+
+    plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
+    if(plugin_state->mutex == NULL) {
+        FURI_LOG_E(TAG, "cannot create mutex\n");
+        furi_message_queue_free(plugin_state->event_queue);
+        free(plugin_state);
+        return 255;
+    }
+
+    FuriTimer* timer =
+        furi_timer_alloc(dice_tick, FuriTimerTypePeriodic, plugin_state->event_queue);
+    if(timer == NULL) {
+        FURI_LOG_E(TAG, "cannot create timer\n");
+        furi_mutex_free(plugin_state->mutex);
+        furi_message_queue_free(plugin_state->event_queue);
+        free(plugin_state);
+        return 255;
+    }
+
+    ViewPort* view_port = view_port_alloc();
+    view_port_draw_callback_set(view_port, dice_render_callback, plugin_state);
+    view_port_input_callback_set(view_port, dice_input_callback, plugin_state->event_queue);
+
+    Gui* gui = furi_record_open(RECORD_GUI);
+    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+    furi_timer_start(timer, furi_kernel_get_tick_frequency());
+
+    // Main loop
+    PluginEvent event;
+    for(bool processing = true; processing;) {
+        FuriStatus event_status = furi_message_queue_get(plugin_state->event_queue, &event, 100);
+        if(event_status == FuriStatusOk) {
+            if(event.type == EventTypeKey) {
+                if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) {
+                    switch(event.input.key) {
+                    case InputKeyUp:
+                        break;
+                    case InputKeyDown:
+                        break;
+                    case InputKeyRight:
+                        if(plugin_state->diceSelect == 2) {
+                            plugin_state->diceSelect = 3;
+                        } else if(plugin_state->diceSelect == 3) {
+                            plugin_state->diceSelect = 4;
+                        } else if(plugin_state->diceSelect == 4) {
+                            plugin_state->diceSelect = 6;
+                        } else if(plugin_state->diceSelect == 6) {
+                            plugin_state->diceSelect = 8;
+                        } else if(plugin_state->diceSelect == 8) {
+                            plugin_state->diceSelect = 10;
+                        } else if(plugin_state->diceSelect == 10) {
+                            plugin_state->diceSelect = 12;
+                        } else if(plugin_state->diceSelect == 12) {
+                            plugin_state->diceSelect = 20;
+                        } else if(plugin_state->diceSelect == 20) {
+                            plugin_state->diceSelect = 100;
+                        } else if(plugin_state->diceSelect == 100) {
+                            plugin_state->diceSelect = 230;
+                        } else if(plugin_state->diceSelect == 230) {
+                            plugin_state->playerOneScore = 0;
+                            plugin_state->playerTwoScore = 0;
+                            plugin_state->diceSelect = 231;
+                        } else if(plugin_state->diceSelect == 231) {
+                            plugin_state->diceSelect = 229;
+                        } else if(plugin_state->diceSelect == 229) {
+                            plugin_state->diceSelect = 228;
+                        } else if(plugin_state->diceSelect == 228) {
+                            plugin_state->diceSelect = 232;
+                        } else if(plugin_state->diceSelect == 232) {
+                            plugin_state->diceSelect = 59;
+                        } else if(plugin_state->diceSelect == 59) {
+                            plugin_state->diceSelect = 69;
+                        } else {
+                            plugin_state->diceSelect = 2;
+                        }
+                        break;
+                    case InputKeyLeft:
+                        if(plugin_state->diceQty <= 5) {
+                            plugin_state->diceQty = plugin_state->diceQty + 1;
+                        } else {
+                            plugin_state->diceQty = 1;
+                        }
+                        break;
+                    case InputKeyOk:
+                        plugin_state->letsRoll = true;
+                        break;
+                    case InputKeyBack:
+                        processing = false;
+                        break;
+                    default:
+                        break;
+                    }
+                }
+            } else if(event.type == EventTypeTick) {
+                // furi_hal_rtc_get_datetime(&plugin_state->datetime);
+            }
+            view_port_update(view_port);
+            furi_mutex_release(plugin_state->mutex);
+        } else {
+            // FURI_LOG_D(TAG, "osMessageQueue: event timeout");
+        }
+    }
+    // Cleanup
+    furi_timer_free(timer);
+    view_port_enabled_set(view_port, false);
+    gui_remove_view_port(gui, view_port);
+    furi_record_close(RECORD_GUI);
+    view_port_free(view_port);
+    furi_message_queue_free(plugin_state->event_queue);
+    furi_mutex_free(plugin_state->mutex);
+    free(plugin_state);
+    return 0;
+}

BIN
multi_dice/dice.png


+ 11 - 0
orgasmotron/application.fam

@@ -0,0 +1,11 @@
+App(
+    appid="orgasmotron",
+    name="Orgasmotron",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="orgasmotron_app",
+    cdefines=["ORGASMOTRON"],
+    requires=["gui"],
+    stack_size=1 * 1024,
+    fap_icon="orgasmotron_10px.png",
+    fap_category="Tools",
+)

+ 163 - 0
orgasmotron/orgasmotron.c

@@ -0,0 +1,163 @@
+#include <furi.h>
+#include <furi_hal.h>
+
+#include <gui/gui.h>
+#include <input/input.h>
+#include <notification/notification_messages.h>
+
+typedef struct {
+    FuriMutex* mutex;
+    int mode;
+} PluginState;
+
+void vibro_test_draw_callback(Canvas* canvas, void* ctx) {
+    UNUSED(ctx);
+    canvas_clear(canvas);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str(canvas, 2, 10, "Vibro Modes");
+    canvas_set_font(canvas, FontSecondary);
+    canvas_draw_str(canvas, 2, 22, "UP: Pulsed");
+    canvas_draw_str(canvas, 2, 34, "LEFT: strong / RIGHT: Soft");
+    canvas_draw_str(canvas, 2, 46, "DOWN: Pleasure combo");
+    canvas_draw_str(canvas, 2, 58, "OK: Pause");
+}
+
+void vibro_test_input_callback(InputEvent* input_event, void* ctx) {
+    furi_assert(ctx);
+    FuriMessageQueue* event_queue = ctx;
+    furi_message_queue_put(event_queue, input_event, FuriWaitForever);
+}
+
+void delay(int milliseconds) {
+    furi_thread_flags_wait(0, FuriFlagWaitAny, milliseconds);
+}
+
+int32_t orgasmotron_app(void* p) {
+    UNUSED(p);
+    FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
+
+    PluginState* plugin_state = malloc(sizeof(PluginState));
+    plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
+    if(!plugin_state->mutex) {
+        FURI_LOG_E("Orgasmatron", "cannot create mutex\r\n");
+        free(plugin_state);
+        return 255;
+    }
+
+    // Configure view port
+    ViewPort* view_port = view_port_alloc();
+    view_port_draw_callback_set(view_port, vibro_test_draw_callback, NULL);
+    view_port_input_callback_set(view_port, vibro_test_input_callback, event_queue);
+
+    // Register view port in GUI
+    Gui* gui = furi_record_open(RECORD_GUI);
+    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+
+    NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
+
+    InputEvent event;
+    bool processing = true;
+    size_t i = 0;
+    while(processing) {
+        FuriStatus event_status = furi_message_queue_get(event_queue, &event, 50);
+        furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
+        if(event_status == FuriStatusOk) {
+            if(event.key == InputKeyBack && event.type == InputTypeShort) {
+                //Exit Application
+                plugin_state->mode = 0;
+                processing = false;
+            }
+            if(event.key == InputKeyOk &&
+               (event.type == InputTypePress || event.type == InputTypeRelease)) {
+                plugin_state->mode = 0;
+            }
+            if(event.key == InputKeyLeft &&
+               (event.type == InputTypePress || event.type == InputTypeRelease)) {
+                notification_message(notification, &sequence_set_green_255);
+                plugin_state->mode = 1;
+            }
+            if(event.key == InputKeyRight &&
+               (event.type == InputTypePress || event.type == InputTypeRelease)) {
+                notification_message(notification, &sequence_set_green_255);
+                plugin_state->mode = 3;
+            }
+            if(event.key == InputKeyUp &&
+               (event.type == InputTypePress || event.type == InputTypeRelease)) {
+                notification_message(notification, &sequence_set_green_255);
+                plugin_state->mode = 2;
+            }
+            if(event.key == InputKeyDown &&
+               (event.type == InputTypePress || event.type == InputTypeRelease)) {
+                notification_message(notification, &sequence_set_green_255);
+                plugin_state->mode = 4;
+            }
+            i = 0;
+        }
+
+        if(plugin_state->mode == 0) {
+            //Stop Vibration
+            if(i == 0) {
+                notification_message(notification, &sequence_reset_vibro);
+                notification_message(notification, &sequence_reset_green);
+                i++;
+            }
+        } else if(plugin_state->mode == 1) {
+            //Full power
+            if(i == 0) {
+                notification_message(notification, &sequence_set_vibro_on);
+                i++;
+            }
+        } else if(plugin_state->mode == 2) {
+            //Pulsed Vibration
+            i++;
+            if(i == 1) {
+                notification_message(notification, &sequence_set_vibro_on);
+            }
+            if(i == 3) {
+                notification_message(notification, &sequence_reset_vibro);
+            }
+            if(i == 4) {
+                i = 0;
+            }
+        } else if(plugin_state->mode == 3) {
+            //Soft power
+            i++;
+            if(i == 1) {
+                notification_message(notification, &sequence_set_vibro_on);
+            }
+            if(i == 2) {
+                notification_message(notification, &sequence_reset_vibro);
+                i = 0;
+            }
+        } else if(plugin_state->mode == 4) {
+            //Special Sequence
+            i++;
+            if(i < 23) {
+                if(i % 2) {
+                    notification_message(notification, &sequence_set_vibro_on);
+                } else {
+                    notification_message(notification, &sequence_reset_vibro);
+                }
+            } else if(i < 40) {
+                if(i == 24 || i == 33) {
+                    notification_message(notification, &sequence_set_vibro_on);
+                } else if(i == 32) {
+                    notification_message(notification, &sequence_reset_vibro);
+                }
+            } else if(i == 41) {
+                notification_message(notification, &sequence_reset_vibro);
+                i = 0;
+            }
+        }
+        furi_mutex_release(plugin_state->mutex);
+    }
+    gui_remove_view_port(gui, view_port);
+    view_port_free(view_port);
+    furi_mutex_free(plugin_state->mutex);
+    furi_message_queue_free(event_queue);
+
+    furi_record_close(RECORD_NOTIFICATION);
+    furi_record_close(RECORD_GUI);
+
+    return 0;
+}

BIN
orgasmotron/orgasmotron_10px.png


+ 52 - 0
sam/application.fam

@@ -0,0 +1,52 @@
+App(
+    appid="sam",
+    name="SAM AYBABTU",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="sam_app",
+    requires=[
+        "gui",
+        "dialogs",
+    ],
+    stack_size=4 * 1024,
+    fap_icon="music_10px.png",
+    fap_category="Media",
+)
+App(
+    appid="sam_yes",
+    name="SAM YES",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="sam_app_yes",
+    requires=[
+        "gui",
+        "dialogs",
+    ],
+    stack_size=4 * 1024,
+    fap_icon="music_10px.png",
+    fap_category="Media",
+)
+App(
+    appid="sam_no",
+    name="SAM NO",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="sam_app_no",
+    requires=[
+        "gui",
+        "dialogs",
+    ],
+    stack_size=4 * 1024,
+    fap_icon="music_10px.png",
+    fap_category="Media",
+)
+App(
+    appid="sam_wtf",
+    name="SAM WTF",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="sam_app_wtf",
+    requires=[
+        "gui",
+        "dialogs",
+    ],
+    stack_size=4 * 1024,
+    fap_icon="music_10px.png",
+    fap_category="Media",
+)

BIN
sam/music_10px.png


+ 46 - 0
sam/sam_app.cpp

@@ -0,0 +1,46 @@
+#include <furi.h>
+#include <furi_hal.h>
+#include "stm32_sam.h"
+// WOULD BE COOL IF SOMEONE MADE A TEXT ENTRY SCREEN TO HAVE IT READ WHAT IS ENTERED TO TEXT
+STM32SAM voice;
+
+extern "C" int32_t sam_app(void* p) {
+    UNUSED(p);
+    if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) {
+        voice.begin();
+        voice.say(
+            "All your base are belong to us. You have no chance to survive make your time. ha. ha. ha. GOOD BYE. ");
+        furi_hal_speaker_release();
+    }
+    return 0;
+}
+
+extern "C" int32_t sam_app_yes(void* p) {
+    UNUSED(p);
+    if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) {
+        voice.begin();
+        voice.say("Yes");
+        furi_hal_speaker_release();
+    }
+    return 0;
+}
+
+extern "C" int32_t sam_app_no(void* p) {
+    UNUSED(p);
+    if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) {
+        voice.begin();
+        voice.say("No");
+        furi_hal_speaker_release();
+    }
+    return 0;
+}
+
+extern "C" int32_t sam_app_wtf(void* p) {
+    UNUSED(p);
+    if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) {
+        voice.begin();
+        voice.say("What The Fuck");
+        furi_hal_speaker_release();
+    }
+    return 0;
+}

+ 5704 - 0
sam/stm32_sam.cpp

@@ -0,0 +1,5704 @@
+
+#include "stm32_sam.h"
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           All
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+char input[256 + 1] = {0}; //tab39445
+//standard sam sound
+
+unsigned char wait1 = 7;
+unsigned char wait2 = 6;
+
+unsigned char A, X, Y;
+unsigned char mem44;
+unsigned char mem47;
+unsigned char mem49;
+unsigned char mem39;
+unsigned char mem50;
+unsigned char mem51;
+unsigned char mem53;
+unsigned char mem56;
+unsigned char mem59 = 0;
+
+unsigned char phonemeIndexOutput[60]; //tab47296
+unsigned char stressOutput[60]; //tab47365
+unsigned char phonemeLengthOutput[60]; //tab47416
+
+// contains the soundbuffer position
+int bufferpos;
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           Sam Tabs
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+//tab40672
+const unsigned char stressInputTable[] = {'*', '1', '2', '3', '4', '5', '6', '7', '8'};
+
+//tab40682
+const unsigned char signInputTable1[] = {
+    ' ', '.', '?', ',', '-', 'I', 'I', 'E', 'A', 'A', 'A', 'A', 'U', 'A', 'I', 'E', 'U',
+    'O', 'R', 'L', 'W', 'Y', 'W', 'R', 'L', 'W', 'Y', 'M', 'N', 'N', 'D', 'Q', 'S', 'S',
+    'F', 'T', '/', '/', 'Z', 'Z', 'V', 'D', 'C', '*', 'J', '*', '*', '*', 'E', 'A', 'O',
+    'A', 'O', 'U', 'B', '*', '*', 'D', '*', '*', 'G', '*', '*', 'G', '*', '*', 'P', '*',
+    '*', 'T', '*', '*', 'K', '*', '*', 'K', '*', '*', 'U', 'U', 'U'};
+
+//tab40763
+const unsigned char signInputTable2[] = {
+    '*', '*', '*', '*', '*', 'Y', 'H', 'H', 'E', 'A', 'H', 'O', 'H', 'X', 'X', 'R', 'X',
+    'H', 'X', 'X', 'X', 'X', 'H', '*', '*', '*', '*', '*', '*', 'X', 'X', '*', '*', 'H',
+    '*', 'H', 'H', 'X', '*', 'H', '*', 'H', 'H', '*', '*', '*', '*', '*', 'Y', 'Y', 'Y',
+    'W', 'W', 'W', '*', '*', '*', '*', '*', '*', '*', '*', '*', 'X', '*', '*', '*', '*',
+    '*', '*', '*', '*', '*', '*', '*', 'X', '*', '*', 'L', 'M', 'N'};
+
+//loc_9F8C
+const unsigned char flags[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x84, 0x84, 0xA4,
+    0xA4, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x4C,
+    0x4C, 0x4C, 0x48, 0x4C, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x44, 0x44,
+    0x48, 0x40, 0x4C, 0x44, 0x00, 0x00, 0xB4, 0xB4, 0xB4, 0x94, 0x94, 0x94, 0x4E, 0x4E,
+    0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4B, 0x4B, 0x4B, 0x4B,
+    0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x80, 0xC1, 0xC1
+
+};
+
+//??? flags overlap flags2
+//loc_9FDA
+const unsigned char flags2[] = {
+    0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0C, 0x08, 0x04, 0x40,
+    0x24, 0x20, 0x20, 0x24, 0x00, 0x00, 0x24, 0x20, 0x20, 0x24, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+//tab45616???
+const unsigned char phonemeStressedLengthTable[] = {
+    0x00, 0x12, 0x12, 0x12, 8,   0xB, 9,   0xB, 0xE, 0xF, 0xB, 0x10, 0xC, 6, 6, 0xE,
+    0xC,  0xE,  0xC,  0xB,  8,   8,   0xB, 0xA, 9,   8,   8,   8,    8,   8, 3, 5,
+    2,    2,    2,    2,    2,   2,   6,   6,   8,   6,   6,   2,    9,   4, 2, 1,
+    0xE,  0xF,  0xF,  0xF,  0xE, 0xE, 8,   2,   2,   7,   2,   1,    7,   2, 2, 7,
+    2,    2,    8,    2,    2,   6,   2,   2,   7,   2,   4,   7,    1,   4, 5, 5};
+
+//tab45536???
+const unsigned char phonemeLengthTable[] = {
+    0, 0x12, 0x12, 0x12, 8, 8, 8, 8,    8,   0xB, 6,   0xC, 0xA, 5, 5, 0xB, 0xA, 0xA, 0xA,  9,
+    8, 7,    9,    7,    6, 8, 6, 7,    7,   7,   2,   5,   2,   2, 2, 2,   2,   2,   6,    6,
+    7, 6,    6,    2,    8, 3, 1, 0x1E, 0xD, 0xC, 0xC, 0xC, 0xE, 9, 6, 1,   2,   5,   1,    1,
+    6, 1,    2,    6,    1, 2, 8, 2,    2,   4,   2,   2,   6,   1, 4, 6,   1,   4,   0xC7, 0xFF};
+
+/*
+
+  Ind  | phoneme |  flags   |
+  -----|---------|----------|
+  0    |   *     | 00000000 |
+  1    |  .*     | 00000000 |
+  2    |  ?*     | 00000000 |
+  3    |  ,*     | 00000000 |
+  4    |  -*     | 00000000 |
+
+  VOWELS
+  5    |  IY     | 10100100 |
+  6    |  IH     | 10100100 |
+  7    |  EH     | 10100100 |
+  8    |  AE     | 10100100 |
+  9    |  AA     | 10100100 |
+  10   |  AH     | 10100100 |
+  11   |  AO     | 10000100 |
+  17   |  OH     | 10000100 |
+  12   |  UH     | 10000100 |
+  16   |  UX     | 10000100 |
+  15   |  ER     | 10000100 |
+  13   |  AX     | 10100100 |
+  14   |  IX     | 10100100 |
+
+  DIPHTONGS
+  48   |  EY     | 10110100 |
+  49   |  AY     | 10110100 |
+  50   |  OY     | 10110100 |
+  51   |  AW     | 10010100 |
+  52   |  OW     | 10010100 |
+  53   |  UW     | 10010100 |
+
+
+  21   |  YX     | 10000100 |
+  20   |  WX     | 10000100 |
+  18   |  RX     | 10000100 |
+  19   |  LX     | 10000100 |
+  37   |  /X     | 01000000 |
+  30   |  DX     | 01001000 |
+
+
+  22   |  WH     | 01000100 |
+
+
+  VOICED CONSONANTS
+  23   |  R*     | 01000100 |
+  24   |  L*     | 01000100 |
+  25   |  W*     | 01000100 |
+  26   |  Y*     | 01000100 |
+  27   |  M*     | 01001100 |
+  28   |  N*     | 01001100 |
+  29   |  NX     | 01001100 |
+  54   |  B*     | 01001110 |
+  57   |  D*     | 01001110 |
+  60   |  G*     | 01001110 |
+  44   |  J*     | 01001100 |
+  38   |  Z*     | 01000100 |
+  39   |  ZH     | 01000100 |
+  40   |  V*     | 01000100 |
+  41   |  DH     | 01000100 |
+
+  unvoiced CONSONANTS
+  32   |  S*     | 01000000 |
+  33   |  SH     | 01000000 |
+  34   |  F*     | 01000000 |
+  35   |  TH     | 01000000 |
+  66   |  P*     | 01001011 |
+  69   |  T*     | 01001011 |
+  72   |  K*     | 01001011 |
+  42   |  CH     | 01001000 |
+  36   |  /H     | 01000000 |
+
+  43   |  **     | 01000000 |
+  45   |  **     | 01000100 |
+  46   |  **     | 00000000 |
+  47   |  **     | 00000000 |
+
+
+  55   |  **     | 01001110 |
+  56   |  **     | 01001110 |
+  58   |  **     | 01001110 |
+  59   |  **     | 01001110 |
+  61   |  **     | 01001110 |
+  62   |  **     | 01001110 |
+  63   |  GX     | 01001110 |
+  64   |  **     | 01001110 |
+  65   |  **     | 01001110 |
+  67   |  **     | 01001011 |
+  68   |  **     | 01001011 |
+  70   |  **     | 01001011 |
+  71   |  **     | 01001011 |
+  73   |  **     | 01001011 |
+  74   |  **     | 01001011 |
+  75   |  KX     | 01001011 |
+  76   |  **     | 01001011 |
+  77   |  **     | 01001011 |
+
+
+  SPECIAL
+  78   |  UL     | 10000000 |
+  79   |  UM     | 11000001 |
+  80   |  UN     | 11000001 |
+  31   |  Q*     | 01001100 |
+
+*/
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           RenderTabs
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+const unsigned char tab48426[5] = {0x18, 0x1A, 0x17, 0x17, 0x17};
+
+const unsigned char tab47492[] = {0, 0, 0xE0, 0xE6, 0xEC, 0xF3, 0xF9, 0, 6, 0xC, 6};
+
+const unsigned char amplitudeRescale[] = {
+    0,
+    1,
+    2,
+    2,
+    2,
+    3,
+    3,
+    4,
+    4,
+    5,
+    6,
+    8,
+    9,
+    0xB,
+    0xD,
+    0xF,
+    0 //17 elements?
+};
+
+// Used to decide which phoneme's blend lengths. The candidate with the lower score is selected.
+// tab45856
+const unsigned char blendRank[] = {0,    0x1F, 0x1F, 0x1F, 0x1F, 2,    2,    2,    2,    2,
+                                   2,    2,    2,    2,    5,    5,    2,    0xA,  2,    8,
+                                   5,    5,    0xB,  0xA,  9,    8,    8,    0xA0, 8,    8,
+                                   0x17, 0x1F, 0x12, 0x12, 0x12, 0x12, 0x1E, 0x1E, 0x14, 0x14,
+                                   0x14, 0x14, 0x17, 0x17, 0x1A, 0x1A, 0x1D, 0x1D, 2,    2,
+                                   2,    2,    2,    2,    0x1A, 0x1D, 0x1B, 0x1A, 0x1D, 0x1B,
+                                   0x1A, 0x1D, 0x1B, 0x1A, 0x1D, 0x1B, 0x17, 0x1D, 0x17, 0x17,
+                                   0x1D, 0x17, 0x17, 0x1D, 0x17, 0x17, 0x1D, 0x17, 0x17, 0x17};
+
+// Number of frames at the end of a phoneme devoted to interpolating to next phoneme's final value
+//tab45696
+const unsigned char outBlendLength[] = {0, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    4,
+                                        4, 4, 3, 2, 4, 4, 2, 2, 2, 2, 2, 1, 1, 1, 1,    1,
+                                        1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 0, 1, 0, 1, 0,    5,
+                                        5, 5, 5, 5, 4, 4, 2, 0, 1, 2, 0, 1, 2, 0, 1,    2,
+                                        0, 1, 2, 0, 2, 2, 0, 1, 3, 0, 2, 3, 0, 2, 0xA0, 0xA0};
+
+// Number of frames at beginning of a phoneme devoted to interpolating to phoneme's final value
+// tab45776
+const unsigned char inBlendLength[] = {0, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    4,
+                                       4, 4, 3, 3, 4, 4, 3, 3, 3, 3, 3, 1, 2, 3, 2,    1,
+                                       3, 3, 3, 3, 1, 1, 3, 3, 3, 2, 2, 3, 2, 3, 0,    0,
+                                       5, 5, 5, 5, 4, 4, 2, 0, 2, 2, 0, 3, 2, 0, 4,    2,
+                                       0, 3, 2, 0, 2, 2, 0, 2, 3, 0, 3, 3, 0, 3, 0xB0, 0xA0};
+
+// Looks like it's used as bit flags
+// High bits masked by 248 (11111000)
+//
+// 32: S*    241         11110001
+// 33: SH    226         11100010
+// 34: F*    211         11010011
+// 35: TH    187         10111011
+// 36: /H    124         01111100
+// 37: /X    149         10010101
+// 38: Z*    1           00000001
+// 39: ZH    2           00000010
+// 40: V*    3           00000011
+// 41: DH    3           00000011
+// 43: **    114         01110010
+// 45: **    2           00000010
+// 67: **    27          00011011
+// 70: **    25          00011001
+// tab45936
+const unsigned char sampledConsonantFlags[] = {
+    0, 0, 0, 0,    0, 0, 0, 0,    0, 0, 0,    0, 0,    0,    0,    0,    0,    0,    0, 0,
+    0, 0, 0, 0,    0, 0, 0, 0,    0, 0, 0,    0, 0xF1, 0xE2, 0xD3, 0xBB, 0x7C, 0x95, 1, 2,
+    3, 3, 0, 0x72, 0, 2, 0, 0,    0, 0, 0,    0, 0,    0,    0,    0,    0,    0,    0, 0,
+    0, 0, 0, 0,    0, 0, 0, 0x1B, 0, 0, 0x19, 0, 0,    0,    0,    0,    0,    0,    0, 0};
+
+//tab45056
+unsigned char freq1data[] = {
+    0x00, 0x13, 0x13, 0x13, 0x13, 0xA,  0xE, 0x12, 0x18, 0x1A, 0x16, 0x14, 0x10, 0x14, 0xE,  0x12,
+    0xE,  0x12, 0x12, 0x10, 0xC,  0xE,  0xA, 0x12, 0xE,  0xA,  8,    6,    6,    6,    6,    0x11,
+    6,    6,    6,    6,    0xE,  0x10, 9,   0xA,  8,    0xA,  6,    6,    6,    5,    6,    0,
+    0x12, 0x1A, 0x14, 0x1A, 0x12, 0xC,  6,   6,    6,    6,    6,    6,    6,    6,    6,    6,
+    6,    6,    6,    6,    6,    6,    6,   6,    6,    0xA,  0xA,  6,    6,    6,    0x2C, 0x13};
+
+//tab451356
+unsigned char freq2data[] = {0x00, 0x43, 0x43, 0x43, 0x43, 0x54, 0x48, 0x42, 0x3E, 0x28,
+                             0x2C, 0x1E, 0x24, 0x2C, 0x48, 0x30, 0x24, 0x1E, 0x32, 0x24,
+                             0x1C, 0x44, 0x18, 0x32, 0x1E, 0x18, 0x52, 0x2E, 0x36, 0x56,
+                             0x36, 0x43, 0x49, 0x4F, 0x1A, 0x42, 0x49, 0x25, 0x33, 0x42,
+                             0x28, 0x2F, 0x4F, 0x4F, 0x42, 0x4F, 0x6E, 0x00, 0x48, 0x26,
+                             0x1E, 0x2A, 0x1E, 0x22, 0x1A, 0x1A, 0x1A, 0x42, 0x42, 0x42,
+                             0x6E, 0x6E, 0x6E, 0x54, 0x54, 0x54, 0x1A, 0x1A, 0x1A, 0x42,
+                             0x42, 0x42, 0x6D, 0x56, 0x6D, 0x54, 0x54, 0x54, 0x7F, 0x7F};
+//tab45216
+unsigned char freq3data[] = {0x00, 0x5B, 0x5B, 0x5B, 0x5B, 0x6E, 0x5D, 0x5B, 0x58, 0x59,
+                             0x57, 0x58, 0x52, 0x59, 0x5D, 0x3E, 0x52, 0x58, 0x3E, 0x6E,
+                             0x50, 0x5D, 0x5A, 0x3C, 0x6E, 0x5A, 0x6E, 0x51, 0x79, 0x65,
+                             0x79, 0x5B, 0x63, 0x6A, 0x51, 0x79, 0x5D, 0x52, 0x5D, 0x67,
+                             0x4C, 0x5D, 0x65, 0x65, 0x79, 0x65, 0x79, 0x00, 0x5A, 0x58,
+                             0x58, 0x58, 0x58, 0x52, 0x51, 0x51, 0x51, 0x79, 0x79, 0x79,
+                             0x70, 0x6E, 0x6E, 0x5E, 0x5E, 0x5E, 0x51, 0x51, 0x51, 0x79,
+                             0x79, 0x79, 0x65, 0x65, 0x70, 0x5E, 0x5E, 0x5E, 0x08, 0x01};
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           Reciter
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+unsigned char inputtemp[256]; // secure copy of input tab36096
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           Render
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+//timetable for more accurate c64 simulation
+int timetable[5][5] = {
+    {162, 167, 167, 127, 128},
+    {226, 60, 60, 0, 0},
+    {225, 60, 59, 0, 0},
+    {200, 0, 0, 54, 55},
+    {199, 0, 0, 54, 54}};
+
+unsigned oldtimetableindex;
+
+const unsigned char ampl1data[] = {0,   0,   0,   0,   0,   0xD, 0xD, 0xE, 0xF, 0xF, 0xF, 0xF,
+                                   0xF, 0xC, 0xD, 0xC, 0xF, 0xF, 0xD, 0xD, 0xD, 0xE, 0xD, 0xC,
+                                   0xD, 0xD, 0xD, 0xC, 9,   9,   0,   0,   0,   0,   0,   0,
+                                   0,   0,   0xB, 0xB, 0xB, 0xB, 0,   0,   1,   0xB, 0,   2,
+                                   0xE, 0xF, 0xF, 0xF, 0xF, 0xD, 2,   4,   0,   2,   4,   0,
+                                   1,   4,   0,   1,   4,   0,   0,   0,   0,   0,   0,   0,
+                                   0,   0xC, 0,   0,   0,   0,   0xF, 0xF};
+
+const unsigned char ampl2data[] = {
+    0, 0,   0, 0,   0, 0xA, 0xB, 0xD, 0xE, 0xD, 0xC, 0xC, 0xB, 9,   0xB, 0xB, 0xC, 0xC, 0xC, 8,
+    8, 0xC, 8, 0xA, 8, 8,   0xA, 3,   9,   6,   0,   0,   0,   0,   0,   0,   0,   0,   3,   5,
+    3, 4,   0, 0,   0, 5,   0xA, 2,   0xE, 0xD, 0xC, 0xD, 0xC, 8,   0,   1,   0,   0,   1,   0,
+    0, 1,   0, 0,   1, 0,   0,   0,   0,   0,   0,   0,   0,   0xA, 0,   0,   0xA, 0,   0,   0};
+
+const unsigned char ampl3data[] = {0, 0, 0, 0, 0, 8, 7, 8, 8, 1, 1, 0, 1, 0, 7,    5,
+                                   1, 0, 6, 1, 0, 7, 0, 5, 1, 0, 8, 0, 0, 3, 0,    0,
+                                   0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0xE,  1,
+                                   9, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    0,
+                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 5, 0, 0x13, 0x10};
+
+//tab42240
+const signed char sinus[256] = {
+    0,    3,    6,    9,    12,   16,   19,   22,   25,   28,   31,   34,   37,   40,   43,   46,
+    49,   51,   54,   57,   60,   63,   65,   68,   71,   73,   76,   78,   81,   83,   85,   88,
+    90,   92,   94,   96,   98,   100,  102,  104,  106,  107,  109,  111,  112,  113,  115,  116,
+    117,  118,  120,  121,  122,  122,  123,  124,  125,  125,  126,  126,  126,  127,  127,  127,
+    127,  127,  127,  127,  126,  126,  126,  125,  125,  124,  123,  122,  122,  121,  120,  118,
+    117,  116,  115,  113,  112,  111,  109,  107,  106,  104,  102,  100,  98,   96,   94,   92,
+    90,   88,   85,   83,   81,   78,   76,   73,   71,   68,   65,   63,   60,   57,   54,   51,
+    49,   46,   43,   40,   37,   34,   31,   28,   25,   22,   19,   16,   12,   9,    6,    3,
+    0,    -3,   -6,   -9,   -12,  -16,  -19,  -22,  -25,  -28,  -31,  -34,  -37,  -40,  -43,  -46,
+    -49,  -51,  -54,  -57,  -60,  -63,  -65,  -68,  -71,  -73,  -76,  -78,  -81,  -83,  -85,  -88,
+    -90,  -92,  -94,  -96,  -98,  -100, -102, -104, -106, -107, -109, -111, -112, -113, -115, -116,
+    -117, -118, -120, -121, -122, -122, -123, -124, -125, -125, -126, -126, -126, -127, -127, -127,
+    -127, -127, -127, -127, -126, -126, -126, -125, -125, -124, -123, -122, -122, -121, -120, -118,
+    -117, -116, -115, -113, -112, -111, -109, -107, -106, -104, -102, -100, -98,  -96,  -94,  -92,
+    -90,  -88,  -85,  -83,  -81,  -78,  -76,  -73,  -71,  -68,  -65,  -63,  -60,  -57,  -54,  -51,
+    -49,  -46,  -43,  -40,  -37,  -34,  -31,  -28,  -25,  -22,  -19,  -16,  -12,  -9,   -6,   -3};
+
+//tab42496
+const unsigned char rectangle[] = {
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+    0x70};
+
+//random data ?
+const unsigned char sampleTable[0x500] = {
+    //00
+
+    0x38,
+    0x84,
+    0x6B,
+    0x19,
+    0xC6,
+    0x63,
+    0x18,
+    0x86,
+    0x73,
+    0x98,
+    0xC6,
+    0xB1,
+    0x1C,
+    0xCA,
+    0x31,
+    0x8C,
+    0xC7,
+    0x31,
+    0x88,
+    0xC2,
+    0x30,
+    0x98,
+    0x46,
+    0x31,
+    0x18,
+    0xC6,
+    0x35,
+    0xC,
+    0xCA,
+    0x31,
+    0xC,
+    0xC6
+    //20
+    ,
+    0x21,
+    0x10,
+    0x24,
+    0x69,
+    0x12,
+    0xC2,
+    0x31,
+    0x14,
+    0xC4,
+    0x71,
+    8,
+    0x4A,
+    0x22,
+    0x49,
+    0xAB,
+    0x6A,
+    0xA8,
+    0xAC,
+    0x49,
+    0x51,
+    0x32,
+    0xD5,
+    0x52,
+    0x88,
+    0x93,
+    0x6C,
+    0x94,
+    0x22,
+    0x15,
+    0x54,
+    0xD2,
+    0x25
+    //40
+    ,
+    0x96,
+    0xD4,
+    0x50,
+    0xA5,
+    0x46,
+    0x21,
+    8,
+    0x85,
+    0x6B,
+    0x18,
+    0xC4,
+    0x63,
+    0x10,
+    0xCE,
+    0x6B,
+    0x18,
+    0x8C,
+    0x71,
+    0x19,
+    0x8C,
+    0x63,
+    0x35,
+    0xC,
+    0xC6,
+    0x33,
+    0x99,
+    0xCC,
+    0x6C,
+    0xB5,
+    0x4E,
+    0xA2,
+    0x99
+    //60
+    ,
+    0x46,
+    0x21,
+    0x28,
+    0x82,
+    0x95,
+    0x2E,
+    0xE3,
+    0x30,
+    0x9C,
+    0xC5,
+    0x30,
+    0x9C,
+    0xA2,
+    0xB1,
+    0x9C,
+    0x67,
+    0x31,
+    0x88,
+    0x66,
+    0x59,
+    0x2C,
+    0x53,
+    0x18,
+    0x84,
+    0x67,
+    0x50,
+    0xCA,
+    0xE3,
+    0xA,
+    0xAC,
+    0xAB,
+    0x30
+    //80
+    ,
+    0xAC,
+    0x62,
+    0x30,
+    0x8C,
+    0x63,
+    0x10,
+    0x94,
+    0x62,
+    0xB1,
+    0x8C,
+    0x82,
+    0x28,
+    0x96,
+    0x33,
+    0x98,
+    0xD6,
+    0xB5,
+    0x4C,
+    0x62,
+    0x29,
+    0xA5,
+    0x4A,
+    0xB5,
+    0x9C,
+    0xC6,
+    0x31,
+    0x14,
+    0xD6,
+    0x38,
+    0x9C,
+    0x4B,
+    0xB4
+    //A0
+    ,
+    0x86,
+    0x65,
+    0x18,
+    0xAE,
+    0x67,
+    0x1C,
+    0xA6,
+    0x63,
+    0x19,
+    0x96,
+    0x23,
+    0x19,
+    0x84,
+    0x13,
+    8,
+    0xA6,
+    0x52,
+    0xAC,
+    0xCA,
+    0x22,
+    0x89,
+    0x6E,
+    0xAB,
+    0x19,
+    0x8C,
+    0x62,
+    0x34,
+    0xC4,
+    0x62,
+    0x19,
+    0x86,
+    0x63
+    //C0
+    ,
+    0x18,
+    0xC4,
+    0x23,
+    0x58,
+    0xD6,
+    0xA3,
+    0x50,
+    0x42,
+    0x54,
+    0x4A,
+    0xAD,
+    0x4A,
+    0x25,
+    0x11,
+    0x6B,
+    0x64,
+    0x89,
+    0x4A,
+    0x63,
+    0x39,
+    0x8A,
+    0x23,
+    0x31,
+    0x2A,
+    0xEA,
+    0xA2,
+    0xA9,
+    0x44,
+    0xC5,
+    0x12,
+    0xCD,
+    0x42
+    //E0
+    ,
+    0x34,
+    0x8C,
+    0x62,
+    0x18,
+    0x8C,
+    0x63,
+    0x11,
+    0x48,
+    0x66,
+    0x31,
+    0x9D,
+    0x44,
+    0x33,
+    0x1D,
+    0x46,
+    0x31,
+    0x9C,
+    0xC6,
+    0xB1,
+    0xC,
+    0xCD,
+    0x32,
+    0x88,
+    0xC4,
+    0x73,
+    0x18,
+    0x86,
+    0x73,
+    8,
+    0xD6,
+    0x63,
+    0x58
+    //100
+    ,
+    7,
+    0x81,
+    0xE0,
+    0xF0,
+    0x3C,
+    7,
+    0x87,
+    0x90,
+    0x3C,
+    0x7C,
+    0xF,
+    0xC7,
+    0xC0,
+    0xC0,
+    0xF0,
+    0x7C,
+    0x1E,
+    7,
+    0x80,
+    0x80,
+    0,
+    0x1C,
+    0x78,
+    0x70,
+    0xF1,
+    0xC7,
+    0x1F,
+    0xC0,
+    0xC,
+    0xFE,
+    0x1C,
+    0x1F
+    //120
+    ,
+    0x1F,
+    0xE,
+    0xA,
+    0x7A,
+    0xC0,
+    0x71,
+    0xF2,
+    0x83,
+    0x8F,
+    3,
+    0xF,
+    0xF,
+    0xC,
+    0,
+    0x79,
+    0xF8,
+    0x61,
+    0xE0,
+    0x43,
+    0xF,
+    0x83,
+    0xE7,
+    0x18,
+    0xF9,
+    0xC1,
+    0x13,
+    0xDA,
+    0xE9,
+    0x63,
+    0x8F,
+    0xF,
+    0x83
+    //140
+    ,
+    0x83,
+    0x87,
+    0xC3,
+    0x1F,
+    0x3C,
+    0x70,
+    0xF0,
+    0xE1,
+    0xE1,
+    0xE3,
+    0x87,
+    0xB8,
+    0x71,
+    0xE,
+    0x20,
+    0xE3,
+    0x8D,
+    0x48,
+    0x78,
+    0x1C,
+    0x93,
+    0x87,
+    0x30,
+    0xE1,
+    0xC1,
+    0xC1,
+    0xE4,
+    0x78,
+    0x21,
+    0x83,
+    0x83,
+    0xC3
+    //160
+    ,
+    0x87,
+    6,
+    0x39,
+    0xE5,
+    0xC3,
+    0x87,
+    7,
+    0xE,
+    0x1C,
+    0x1C,
+    0x70,
+    0xF4,
+    0x71,
+    0x9C,
+    0x60,
+    0x36,
+    0x32,
+    0xC3,
+    0x1E,
+    0x3C,
+    0xF3,
+    0x8F,
+    0xE,
+    0x3C,
+    0x70,
+    0xE3,
+    0xC7,
+    0x8F,
+    0xF,
+    0xF,
+    0xE,
+    0x3C
+    //180
+    ,
+    0x78,
+    0xF0,
+    0xE3,
+    0x87,
+    6,
+    0xF0,
+    0xE3,
+    7,
+    0xC1,
+    0x99,
+    0x87,
+    0xF,
+    0x18,
+    0x78,
+    0x70,
+    0x70,
+    0xFC,
+    0xF3,
+    0x10,
+    0xB1,
+    0x8C,
+    0x8C,
+    0x31,
+    0x7C,
+    0x70,
+    0xE1,
+    0x86,
+    0x3C,
+    0x64,
+    0x6C,
+    0xB0,
+    0xE1
+    //1A0
+    ,
+    0xE3,
+    0xF,
+    0x23,
+    0x8F,
+    0xF,
+    0x1E,
+    0x3E,
+    0x38,
+    0x3C,
+    0x38,
+    0x7B,
+    0x8F,
+    7,
+    0xE,
+    0x3C,
+    0xF4,
+    0x17,
+    0x1E,
+    0x3C,
+    0x78,
+    0xF2,
+    0x9E,
+    0x72,
+    0x49,
+    0xE3,
+    0x25,
+    0x36,
+    0x38,
+    0x58,
+    0x39,
+    0xE2,
+    0xDE
+    //1C0
+    ,
+    0x3C,
+    0x78,
+    0x78,
+    0xE1,
+    0xC7,
+    0x61,
+    0xE1,
+    0xE1,
+    0xB0,
+    0xF0,
+    0xF0,
+    0xC3,
+    0xC7,
+    0xE,
+    0x38,
+    0xC0,
+    0xF0,
+    0xCE,
+    0x73,
+    0x73,
+    0x18,
+    0x34,
+    0xB0,
+    0xE1,
+    0xC7,
+    0x8E,
+    0x1C,
+    0x3C,
+    0xF8,
+    0x38,
+    0xF0,
+    0xE1
+    //1E0
+    ,
+    0xC1,
+    0x8B,
+    0x86,
+    0x8F,
+    0x1C,
+    0x78,
+    0x70,
+    0xF0,
+    0x78,
+    0xAC,
+    0xB1,
+    0x8F,
+    0x39,
+    0x31,
+    0xDB,
+    0x38,
+    0x61,
+    0xC3,
+    0xE,
+    0xE,
+    0x38,
+    0x78,
+    0x73,
+    0x17,
+    0x1E,
+    0x39,
+    0x1E,
+    0x38,
+    0x64,
+    0xE1,
+    0xF1,
+    0xC1
+    //200
+    ,
+    0x4E,
+    0xF,
+    0x40,
+    0xA2,
+    2,
+    0xC5,
+    0x8F,
+    0x81,
+    0xA1,
+    0xFC,
+    0x12,
+    8,
+    0x64,
+    0xE0,
+    0x3C,
+    0x22,
+    0xE0,
+    0x45,
+    7,
+    0x8E,
+    0xC,
+    0x32,
+    0x90,
+    0xF0,
+    0x1F,
+    0x20,
+    0x49,
+    0xE0,
+    0xF8,
+    0xC,
+    0x60,
+    0xF0
+    //220
+    ,
+    0x17,
+    0x1A,
+    0x41,
+    0xAA,
+    0xA4,
+    0xD0,
+    0x8D,
+    0x12,
+    0x82,
+    0x1E,
+    0x1E,
+    3,
+    0xF8,
+    0x3E,
+    3,
+    0xC,
+    0x73,
+    0x80,
+    0x70,
+    0x44,
+    0x26,
+    3,
+    0x24,
+    0xE1,
+    0x3E,
+    4,
+    0x4E,
+    4,
+    0x1C,
+    0xC1,
+    9,
+    0xCC
+    //240
+    ,
+    0x9E,
+    0x90,
+    0x21,
+    7,
+    0x90,
+    0x43,
+    0x64,
+    0xC0,
+    0xF,
+    0xC6,
+    0x90,
+    0x9C,
+    0xC1,
+    0x5B,
+    3,
+    0xE2,
+    0x1D,
+    0x81,
+    0xE0,
+    0x5E,
+    0x1D,
+    3,
+    0x84,
+    0xB8,
+    0x2C,
+    0xF,
+    0x80,
+    0xB1,
+    0x83,
+    0xE0,
+    0x30,
+    0x41
+    //260
+    ,
+    0x1E,
+    0x43,
+    0x89,
+    0x83,
+    0x50,
+    0xFC,
+    0x24,
+    0x2E,
+    0x13,
+    0x83,
+    0xF1,
+    0x7C,
+    0x4C,
+    0x2C,
+    0xC9,
+    0xD,
+    0x83,
+    0xB0,
+    0xB5,
+    0x82,
+    0xE4,
+    0xE8,
+    6,
+    0x9C,
+    7,
+    0xA0,
+    0x99,
+    0x1D,
+    7,
+    0x3E,
+    0x82,
+    0x8F
+    //280
+    ,
+    0x70,
+    0x30,
+    0x74,
+    0x40,
+    0xCA,
+    0x10,
+    0xE4,
+    0xE8,
+    0xF,
+    0x92,
+    0x14,
+    0x3F,
+    6,
+    0xF8,
+    0x84,
+    0x88,
+    0x43,
+    0x81,
+    0xA,
+    0x34,
+    0x39,
+    0x41,
+    0xC6,
+    0xE3,
+    0x1C,
+    0x47,
+    3,
+    0xB0,
+    0xB8,
+    0x13,
+    0xA,
+    0xC2
+    //2A0
+    ,
+    0x64,
+    0xF8,
+    0x18,
+    0xF9,
+    0x60,
+    0xB3,
+    0xC0,
+    0x65,
+    0x20,
+    0x60,
+    0xA6,
+    0x8C,
+    0xC3,
+    0x81,
+    0x20,
+    0x30,
+    0x26,
+    0x1E,
+    0x1C,
+    0x38,
+    0xD3,
+    1,
+    0xB0,
+    0x26,
+    0x40,
+    0xF4,
+    0xB,
+    0xC3,
+    0x42,
+    0x1F,
+    0x85,
+    0x32
+    //2C0
+    ,
+    0x26,
+    0x60,
+    0x40,
+    0xC9,
+    0xCB,
+    1,
+    0xEC,
+    0x11,
+    0x28,
+    0x40,
+    0xFA,
+    4,
+    0x34,
+    0xE0,
+    0x70,
+    0x4C,
+    0x8C,
+    0x1D,
+    7,
+    0x69,
+    3,
+    0x16,
+    0xC8,
+    4,
+    0x23,
+    0xE8,
+    0xC6,
+    0x9A,
+    0xB,
+    0x1A,
+    3,
+    0xE0
+    //2E0
+    ,
+    0x76,
+    6,
+    5,
+    0xCF,
+    0x1E,
+    0xBC,
+    0x58,
+    0x31,
+    0x71,
+    0x66,
+    0,
+    0xF8,
+    0x3F,
+    4,
+    0xFC,
+    0xC,
+    0x74,
+    0x27,
+    0x8A,
+    0x80,
+    0x71,
+    0xC2,
+    0x3A,
+    0x26,
+    6,
+    0xC0,
+    0x1F,
+    5,
+    0xF,
+    0x98,
+    0x40,
+    0xAE
+    //300
+    ,
+    1,
+    0x7F,
+    0xC0,
+    7,
+    0xFF,
+    0,
+    0xE,
+    0xFE,
+    0,
+    3,
+    0xDF,
+    0x80,
+    3,
+    0xEF,
+    0x80,
+    0x1B,
+    0xF1,
+    0xC2,
+    0,
+    0xE7,
+    0xE0,
+    0x18,
+    0xFC,
+    0xE0,
+    0x21,
+    0xFC,
+    0x80,
+    0x3C,
+    0xFC,
+    0x40,
+    0xE,
+    0x7E
+    //320
+    ,
+    0,
+    0x3F,
+    0x3E,
+    0,
+    0xF,
+    0xFE,
+    0,
+    0x1F,
+    0xFF,
+    0,
+    0x3E,
+    0xF0,
+    7,
+    0xFC,
+    0,
+    0x7E,
+    0x10,
+    0x3F,
+    0xFF,
+    0,
+    0x3F,
+    0x38,
+    0xE,
+    0x7C,
+    1,
+    0x87,
+    0xC,
+    0xFC,
+    0xC7,
+    0,
+    0x3E,
+    4
+    //340
+    ,
+    0xF,
+    0x3E,
+    0x1F,
+    0xF,
+    0xF,
+    0x1F,
+    0xF,
+    2,
+    0x83,
+    0x87,
+    0xCF,
+    3,
+    0x87,
+    0xF,
+    0x3F,
+    0xC0,
+    7,
+    0x9E,
+    0x60,
+    0x3F,
+    0xC0,
+    3,
+    0xFE,
+    0,
+    0x3F,
+    0xE0,
+    0x77,
+    0xE1,
+    0xC0,
+    0xFE,
+    0xE0,
+    0xC3
+    //360
+    ,
+    0xE0,
+    1,
+    0xDF,
+    0xF8,
+    3,
+    7,
+    0,
+    0x7E,
+    0x70,
+    0,
+    0x7C,
+    0x38,
+    0x18,
+    0xFE,
+    0xC,
+    0x1E,
+    0x78,
+    0x1C,
+    0x7C,
+    0x3E,
+    0xE,
+    0x1F,
+    0x1E,
+    0x1E,
+    0x3E,
+    0,
+    0x7F,
+    0x83,
+    7,
+    0xDB,
+    0x87,
+    0x83
+    //380
+    ,
+    7,
+    0xC7,
+    7,
+    0x10,
+    0x71,
+    0xFF,
+    0,
+    0x3F,
+    0xE2,
+    1,
+    0xE0,
+    0xC1,
+    0xC3,
+    0xE1,
+    0,
+    0x7F,
+    0xC0,
+    5,
+    0xF0,
+    0x20,
+    0xF8,
+    0xF0,
+    0x70,
+    0xFE,
+    0x78,
+    0x79,
+    0xF8,
+    2,
+    0x3F,
+    0xC,
+    0x8F,
+    3
+    //3a0
+    ,
+    0xF,
+    0x9F,
+    0xE0,
+    0xC1,
+    0xC7,
+    0x87,
+    3,
+    0xC3,
+    0xC3,
+    0xB0,
+    0xE1,
+    0xE1,
+    0xC1,
+    0xE3,
+    0xE0,
+    0x71,
+    0xF0,
+    0,
+    0xFC,
+    0x70,
+    0x7C,
+    0xC,
+    0x3E,
+    0x38,
+    0xE,
+    0x1C,
+    0x70,
+    0xC3,
+    0xC7,
+    3,
+    0x81,
+    0xC1
+    //3c0
+    ,
+    0xC7,
+    0xE7,
+    0,
+    0xF,
+    0xC7,
+    0x87,
+    0x19,
+    9,
+    0xEF,
+    0xC4,
+    0x33,
+    0xE0,
+    0xC1,
+    0xFC,
+    0xF8,
+    0x70,
+    0xF0,
+    0x78,
+    0xF8,
+    0xF0,
+    0x61,
+    0xC7,
+    0,
+    0x1F,
+    0xF8,
+    1,
+    0x7C,
+    0xF8,
+    0xF0,
+    0x78,
+    0x70,
+    0x3C
+    //3e0
+    ,
+    0x7C,
+    0xCE,
+    0xE,
+    0x21,
+    0x83,
+    0xCF,
+    8,
+    7,
+    0x8F,
+    8,
+    0xC1,
+    0x87,
+    0x8F,
+    0x80,
+    0xC7,
+    0xE3,
+    0,
+    7,
+    0xF8,
+    0xE0,
+    0xEF,
+    0,
+    0x39,
+    0xF7,
+    0x80,
+    0xE,
+    0xF8,
+    0xE1,
+    0xE3,
+    0xF8,
+    0x21,
+    0x9F
+    //400
+    ,
+    0xC0,
+    0xFF,
+    3,
+    0xF8,
+    7,
+    0xC0,
+    0x1F,
+    0xF8,
+    0xC4,
+    4,
+    0xFC,
+    0xC4,
+    0xC1,
+    0xBC,
+    0x87,
+    0xF0,
+    0xF,
+    0xC0,
+    0x7F,
+    5,
+    0xE0,
+    0x25,
+    0xEC,
+    0xC0,
+    0x3E,
+    0x84,
+    0x47,
+    0xF0,
+    0x8E,
+    3,
+    0xF8,
+    3
+    //420
+    ,
+    0xFB,
+    0xC0,
+    0x19,
+    0xF8,
+    7,
+    0x9C,
+    0xC,
+    0x17,
+    0xF8,
+    7,
+    0xE0,
+    0x1F,
+    0xA1,
+    0xFC,
+    0xF,
+    0xFC,
+    1,
+    0xF0,
+    0x3F,
+    0,
+    0xFE,
+    3,
+    0xF0,
+    0x1F,
+    0,
+    0xFD,
+    0,
+    0xFF,
+    0x88,
+    0xD,
+    0xF9,
+    1
+    //440
+    ,
+    0xFF,
+    0,
+    0x70,
+    7,
+    0xC0,
+    0x3E,
+    0x42,
+    0xF3,
+    0xD,
+    0xC4,
+    0x7F,
+    0x80,
+    0xFC,
+    7,
+    0xF0,
+    0x5E,
+    0xC0,
+    0x3F,
+    0,
+    0x78,
+    0x3F,
+    0x81,
+    0xFF,
+    1,
+    0xF8,
+    1,
+    0xC3,
+    0xE8,
+    0xC,
+    0xE4,
+    0x64,
+    0x8F
+    ////460
+    ,
+    0xE4,
+    0xF,
+    0xF0,
+    7,
+    0xF0,
+    0xC2,
+    0x1F,
+    0,
+    0x7F,
+    0xC0,
+    0x6F,
+    0x80,
+    0x7E,
+    3,
+    0xF8,
+    7,
+    0xF0,
+    0x3F,
+    0xC0,
+    0x78,
+    0xF,
+    0x82,
+    7,
+    0xFE,
+    0x22,
+    0x77,
+    0x70,
+    2,
+    0x76,
+    3,
+    0xFE,
+    0
+    //480
+    ,
+    0xFE,
+    0x67,
+    0,
+    0x7C,
+    0xC7,
+    0xF1,
+    0x8E,
+    0xC6,
+    0x3B,
+    0xE0,
+    0x3F,
+    0x84,
+    0xF3,
+    0x19,
+    0xD8,
+    3,
+    0x99,
+    0xFC,
+    9,
+    0xB8,
+    0xF,
+    0xF8,
+    0,
+    0x9D,
+    0x24,
+    0x61,
+    0xF9,
+    0xD,
+    0,
+    0xFD,
+    3,
+    0xF0
+    //4a0
+    ,
+    0x1F,
+    0x90,
+    0x3F,
+    1,
+    0xF8,
+    0x1F,
+    0xD0,
+    0xF,
+    0xF8,
+    0x37,
+    1,
+    0xF8,
+    7,
+    0xF0,
+    0xF,
+    0xC0,
+    0x3F,
+    0,
+    0xFE,
+    3,
+    0xF8,
+    0xF,
+    0xC0,
+    0x3F,
+    0,
+    0xFA,
+    3,
+    0xF0,
+    0xF,
+    0x80,
+    0xFF,
+    1
+    //4c0
+    ,
+    0xB8,
+    7,
+    0xF0,
+    1,
+    0xFC,
+    1,
+    0xBC,
+    0x80,
+    0x13,
+    0x1E,
+    0,
+    0x7F,
+    0xE1,
+    0x40,
+    0x7F,
+    0xA0,
+    0x7F,
+    0xB0,
+    0,
+    0x3F,
+    0xC0,
+    0x1F,
+    0xC0,
+    0x38,
+    0xF,
+    0xF0,
+    0x1F,
+    0x80,
+    0xFF,
+    1,
+    0xFC,
+    3
+    //4e0
+    ,
+    0xF1,
+    0x7E,
+    1,
+    0xFE,
+    1,
+    0xF0,
+    0xFF,
+    0,
+    0x7F,
+    0xC0,
+    0x1D,
+    7,
+    0xF0,
+    0xF,
+    0xC0,
+    0x7E,
+    6,
+    0xE0,
+    7,
+    0xE0,
+    0xF,
+    0xF8,
+    6,
+    0xC1,
+    0xFE,
+    1,
+    0xFC,
+    3,
+    0xE0,
+    0xF,
+    0,
+    0xFC};
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           Render
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+unsigned char pitches[256]; // tab43008
+
+unsigned char frequency1[256];
+unsigned char frequency2[256];
+unsigned char frequency3[256];
+
+unsigned char amplitude1[256];
+unsigned char amplitude2[256];
+unsigned char amplitude3[256];
+
+unsigned char sampledConsonantFlag[256]; // tab44800
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           Sam
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+unsigned char stress[256]; //numbers from 0 to 8
+unsigned char phonemeLength[256]; //tab40160
+unsigned char phonemeindex[256];
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           ReciterTabs
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+//some flags
+const unsigned char tab36376[] = {
+    0,   0,   0,   0,   0,   0,   0,   0, // 0-7
+    0,   0,   0,   0,   0,   0,   0,   0, // 8-15
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   2,   2,   2,   2,   2,   2,   130, // ' ', '!'
+    0,   0,   2,   2,   2,   2,   2,   2,   3,   3,   3,   3,   3,   3,   3,   3,
+    3,   3,   2,   2,   2,   2,   2,   2,   2,   192, 168, 176, 172, 192, 160, 184, // '@', 'A'
+    160, 192, 188, 160, 172, 168, 172, 192, 160, 160, 172, 180, 164, 192, 168, 168,
+    176, 192, 188, 0,   0,   0,   2,   0, // 'X', 'Y', 'Z', '[',
+    32,  32,  155, 32,  192, 185, 32,  205, 163, 76,  138, 142};
+
+const unsigned char rules[] = {
+    ']',        'A' | 0x80, ' ',        '(',        'A',        '.',        ')',        '=',
+    'E',        'H',        '4',        'Y',        '.',        ' ' | 0x80, '(',        'A',
+    ')',        ' ',        '=',        'A',        'H' | 0x80, ' ',        '(',        'A',
+    'R',        'E',        ')',        ' ',        '=',        'A',        'A',        'R' | 0x80,
+    ' ',        '(',        'A',        'R',        ')',        'O',        '=',        'A',
+    'X',        'R' | 0x80, '(',        'A',        'R',        ')',        '#',        '=',
+    'E',        'H',        '4',        'R' | 0x80, ' ',        '^',        '(',        'A',
+    'S',        ')',        '#',        '=',        'E',        'Y',        '4',        'S' | 0x80,
+    '(',        'A',        ')',        'W',        'A',        '=',        'A',        'X' | 0x80,
+    '(',        'A',        'W',        ')',        '=',        'A',        'O',        '5' | 0x80,
+    ' ',        ':',        '(',        'A',        'N',        'Y',        ')',        '=',
+    'E',        'H',        '4',        'N',        'I',        'Y' | 0x80, '(',        'A',
+    ')',        '^',        '+',        '#',        '=',        'E',        'Y',        '5' | 0x80,
+    '#',        ':',        '(',        'A',        'L',        'L',        'Y',        ')',
+    '=',        'U',        'L',        'I',        'Y' | 0x80, ' ',        '(',        'A',
+    'L',        ')',        '#',        '=',        'U',        'L' | 0x80, '(',        'A',
+    'G',        'A',        'I',        'N',        ')',        '=',        'A',        'X',
+    'G',        'E',        'H',        '4',        'N' | 0x80, '#',        ':',        '(',
+    'A',        'G',        ')',        'E',        '=',        'I',        'H',        'J' | 0x80,
+    '(',        'A',        ')',        '^',        '%',        '=',        'E',        'Y' | 0x80,
+    '(',        'A',        ')',        '^',        '+',        ':',        '#',        '=',
+    'A',        'E' | 0x80, ' ',        ':',        '(',        'A',        ')',        '^',
+    '+',        ' ',        '=',        'E',        'Y',        '4' | 0x80, ' ',        '(',
+    'A',        'R',        'R',        ')',        '=',        'A',        'X',        'R' | 0x80,
+    '(',        'A',        'R',        'R',        ')',        '=',        'A',        'E',
+    '4',        'R' | 0x80, ' ',        '^',        '(',        'A',        'R',        ')',
+    ' ',        '=',        'A',        'A',        '5',        'R' | 0x80, '(',        'A',
+    'R',        ')',        '=',        'A',        'A',        '5',        'R' | 0x80, '(',
+    'A',        'I',        'R',        ')',        '=',        'E',        'H',        '4',
+    'R' | 0x80, '(',        'A',        'I',        ')',        '=',        'E',        'Y',
+    '4' | 0x80, '(',        'A',        'Y',        ')',        '=',        'E',        'Y',
+    '5' | 0x80, '(',        'A',        'U',        ')',        '=',        'A',        'O',
+    '4' | 0x80, '#',        ':',        '(',        'A',        'L',        ')',        ' ',
+    '=',        'U',        'L' | 0x80, '#',        ':',        '(',        'A',        'L',
+    'S',        ')',        ' ',        '=',        'U',        'L',        'Z' | 0x80, '(',
+    'A',        'L',        'K',        ')',        '=',        'A',        'O',        '4',
+    'K' | 0x80, '(',        'A',        'L',        ')',        '^',        '=',        'A',
+    'O',        'L' | 0x80, ' ',        ':',        '(',        'A',        'B',        'L',
+    'E',        ')',        '=',        'E',        'Y',        '4',        'B',        'U',
+    'L' | 0x80, '(',        'A',        'B',        'L',        'E',        ')',        '=',
+    'A',        'X',        'B',        'U',        'L' | 0x80, '(',        'A',        ')',
+    'V',        'O',        '=',        'E',        'Y',        '4' | 0x80, '(',        'A',
+    'N',        'G',        ')',        '+',        '=',        'E',        'Y',        '4',
+    'N',        'J' | 0x80, '(',        'A',        'T',        'A',        'R',        'I',
+    ')',        '=',        'A',        'H',        'T',        'A',        'A',        '4',
+    'R',        'I',        'Y' | 0x80, '(',        'A',        ')',        'T',        'O',
+    'M',        '=',        'A',        'E' | 0x80, '(',        'A',        ')',        'T',
+    'T',        'I',        '=',        'A',        'E' | 0x80, ' ',        '(',        'A',
+    'T',        ')',        ' ',        '=',        'A',        'E',        'T' | 0x80, ' ',
+    '(',        'A',        ')',        'T',        '=',        'A',        'H' | 0x80, '(',
+    'A',        ')',        '=',        'A',        'E' | 0x80,
+
+    ']',        'B' | 0x80, ' ',        '(',        'B',        ')',        ' ',        '=',
+    'B',        'I',        'Y',        '4' | 0x80, ' ',        '(',        'B',        'E',
+    ')',        '^',        '#',        '=',        'B',        'I',        'H' | 0x80, '(',
+    'B',        'E',        'I',        'N',        'G',        ')',        '=',        'B',
+    'I',        'Y',        '4',        'I',        'H',        'N',        'X' | 0x80, ' ',
+    '(',        'B',        'O',        'T',        'H',        ')',        ' ',        '=',
+    'B',        'O',        'W',        '4',        'T',        'H' | 0x80, ' ',        '(',
+    'B',        'U',        'S',        ')',        '#',        '=',        'B',        'I',
+    'H',        '4',        'Z' | 0x80, '(',        'B',        'R',        'E',        'A',
+    'K',        ')',        '=',        'B',        'R',        'E',        'Y',        '5',
+    'K' | 0x80, '(',        'B',        'U',        'I',        'L',        ')',        '=',
+    'B',        'I',        'H',        '4',        'L' | 0x80, '(',        'B',        ')',
+    '=',        'B' | 0x80,
+
+    ']',        'C' | 0x80, ' ',        '(',        'C',        ')',        ' ',        '=',
+    'S',        'I',        'Y',        '4' | 0x80, ' ',        '(',        'C',        'H',
+    ')',        '^',        '=',        'K' | 0x80, '^',        'E',        '(',        'C',
+    'H',        ')',        '=',        'K' | 0x80, '(',        'C',        'H',        'A',
+    ')',        'R',        '#',        '=',        'K',        'E',        'H',        '5' | 0x80,
+    '(',        'C',        'H',        ')',        '=',        'C',        'H' | 0x80, ' ',
+    'S',        '(',        'C',        'I',        ')',        '#',        '=',        'S',
+    'A',        'Y',        '4' | 0x80, '(',        'C',        'I',        ')',        'A',
+    '=',        'S',        'H' | 0x80, '(',        'C',        'I',        ')',        'O',
+    '=',        'S',        'H' | 0x80, '(',        'C',        'I',        ')',        'E',
+    'N',        '=',        'S',        'H' | 0x80, '(',        'C',        'I',        'T',
+    'Y',        ')',        '=',        'S',        'I',        'H',        'T',        'I',
+    'Y' | 0x80, '(',        'C',        ')',        '+',        '=',        'S' | 0x80, '(',
+    'C',        'K',        ')',        '=',        'K' | 0x80, '(',        'C',        'O',
+    'M',        'M',        'O',        'D',        'O',        'R',        'E',        ')',
+    '=',        'K',        'A',        'A',        '4',        'M',        'A',        'H',
+    'D',        'O',        'H',        'R' | 0x80, '(',        'C',        'O',        'M',
+    ')',        '=',        'K',        'A',        'H',        'M' | 0x80, '(',        'C',
+    'U',        'I',        'T',        ')',        '=',        'K',        'I',        'H',
+    'T' | 0x80, '(',        'C',        'R',        'E',        'A',        ')',        '=',
+    'K',        'R',        'I',        'Y',        'E',        'Y' | 0x80, '(',        'C',
+    ')',        '=',        'K' | 0x80,
+
+    ']',        'D' | 0x80, ' ',        '(',        'D',        ')',        ' ',        '=',
+    'D',        'I',        'Y',        '4' | 0x80, ' ',        '(',        'D',        'R',
+    '.',        ')',        ' ',        '=',        'D',        'A',        'A',        '4',
+    'K',        'T',        'E',        'R' | 0x80, '#',        ':',        '(',        'D',
+    'E',        'D',        ')',        ' ',        '=',        'D',        'I',        'H',
+    'D' | 0x80, '.',        'E',        '(',        'D',        ')',        ' ',        '=',
+    'D' | 0x80, '#',        ':',        '^',        'E',        '(',        'D',        ')',
+    ' ',        '=',        'T' | 0x80, ' ',        '(',        'D',        'E',        ')',
+    '^',        '#',        '=',        'D',        'I',        'H' | 0x80, ' ',        '(',
+    'D',        'O',        ')',        ' ',        '=',        'D',        'U',        'W' | 0x80,
+    ' ',        '(',        'D',        'O',        'E',        'S',        ')',        '=',
+    'D',        'A',        'H',        'Z' | 0x80, '(',        'D',        'O',        'N',
+    'E',        ')',        ' ',        '=',        'D',        'A',        'H',        '5',
+    'N' | 0x80, '(',        'D',        'O',        'I',        'N',        'G',        ')',
+    '=',        'D',        'U',        'W',        '4',        'I',        'H',        'N',
+    'X' | 0x80, ' ',        '(',        'D',        'O',        'W',        ')',        '=',
+    'D',        'A',        'W' | 0x80, '#',        '(',        'D',        'U',        ')',
+    'A',        '=',        'J',        'U',        'W' | 0x80, '#',        '(',        'D',
+    'U',        ')',        '^',        '#',        '=',        'J',        'A',        'X' | 0x80,
+    '(',        'D',        ')',        '=',        'D' | 0x80,
+
+    ']',        'E' | 0x80, ' ',        '(',        'E',        ')',        ' ',        '=',
+    'I',        'Y',        'I',        'Y',        '4' | 0x80, '#',        ':',        '(',
+    'E',        ')',        ' ',        '=' | 0x80, '\'',       ':',        '^',        '(',
+    'E',        ')',        ' ',        '=' | 0x80, ' ',        ':',        '(',        'E',
+    ')',        ' ',        '=',        'I',        'Y' | 0x80, '#',        '(',        'E',
+    'D',        ')',        ' ',        '=',        'D' | 0x80, '#',        ':',        '(',
+    'E',        ')',        'D',        ' ',        '=' | 0x80, '(',        'E',        'V',
+    ')',        'E',        'R',        '=',        'E',        'H',        '4',        'V' | 0x80,
+    '(',        'E',        ')',        '^',        '%',        '=',        'I',        'Y',
+    '4' | 0x80, '(',        'E',        'R',        'I',        ')',        '#',        '=',
+    'I',        'Y',        '4',        'R',        'I',        'Y' | 0x80, '(',        'E',
+    'R',        'I',        ')',        '=',        'E',        'H',        '4',        'R',
+    'I',        'H' | 0x80, '#',        ':',        '(',        'E',        'R',        ')',
+    '#',        '=',        'E',        'R' | 0x80, '(',        'E',        'R',        'R',
+    'O',        'R',        ')',        '=',        'E',        'H',        '4',        'R',
+    'O',        'H',        'R' | 0x80, '(',        'E',        'R',        'A',        'S',
+    'E',        ')',        '=',        'I',        'H',        'R',        'E',        'Y',
+    '5',        'S' | 0x80, '(',        'E',        'R',        ')',        '#',        '=',
+    'E',        'H',        'R' | 0x80, '(',        'E',        'R',        ')',        '=',
+    'E',        'R' | 0x80, ' ',        '(',        'E',        'V',        'E',        'N',
+    ')',        '=',        'I',        'Y',        'V',        'E',        'H',        'N' | 0x80,
+    '#',        ':',        '(',        'E',        ')',        'W',        '=' | 0x80, '@',
+    '(',        'E',        'W',        ')',        '=',        'U',        'W' | 0x80, '(',
+    'E',        'W',        ')',        '=',        'Y',        'U',        'W' | 0x80, '(',
+    'E',        ')',        'O',        '=',        'I',        'Y' | 0x80, '#',        ':',
+    '&',        '(',        'E',        'S',        ')',        ' ',        '=',        'I',
+    'H',        'Z' | 0x80, '#',        ':',        '(',        'E',        ')',        'S',
+    ' ',        '=' | 0x80, '#',        ':',        '(',        'E',        'L',        'Y',
+    ')',        ' ',        '=',        'L',        'I',        'Y' | 0x80, '#',        ':',
+    '(',        'E',        'M',        'E',        'N',        'T',        ')',        '=',
+    'M',        'E',        'H',        'N',        'T' | 0x80, '(',        'E',        'F',
+    'U',        'L',        ')',        '=',        'F',        'U',        'H',        'L' | 0x80,
+    '(',        'E',        'E',        ')',        '=',        'I',        'Y',        '4' | 0x80,
+    '(',        'E',        'A',        'R',        'N',        ')',        '=',        'E',
+    'R',        '5',        'N' | 0x80, ' ',        '(',        'E',        'A',        'R',
+    ')',        '^',        '=',        'E',        'R',        '5' | 0x80, '(',        'E',
+    'A',        'D',        ')',        '=',        'E',        'H',        'D' | 0x80, '#',
+    ':',        '(',        'E',        'A',        ')',        ' ',        '=',        'I',
+    'Y',        'A',        'X' | 0x80, '(',        'E',        'A',        ')',        'S',
+    'U',        '=',        'E',        'H',        '5' | 0x80, '(',        'E',        'A',
+    ')',        '=',        'I',        'Y',        '5' | 0x80, '(',        'E',        'I',
+    'G',        'H',        ')',        '=',        'E',        'Y',        '4' | 0x80, '(',
+    'E',        'I',        ')',        '=',        'I',        'Y',        '4' | 0x80, ' ',
+    '(',        'E',        'Y',        'E',        ')',        '=',        'A',        'Y',
+    '4' | 0x80, '(',        'E',        'Y',        ')',        '=',        'I',        'Y' | 0x80,
+    '(',        'E',        'U',        ')',        '=',        'Y',        'U',        'W',
+    '5' | 0x80, '(',        'E',        'Q',        'U',        'A',        'L',        ')',
+    '=',        'I',        'Y',        '4',        'K',        'W',        'U',        'L' | 0x80,
+    '(',        'E',        ')',        '=',        'E',        'H' | 0x80,
+
+    ']',        'F' | 0x80, ' ',        '(',        'F',        ')',        ' ',        '=',
+    'E',        'H',        '4',        'F' | 0x80, '(',        'F',        'U',        'L',
+    ')',        '=',        'F',        'U',        'H',        'L' | 0x80, '(',        'F',
+    'R',        'I',        'E',        'N',        'D',        ')',        '=',        'F',
+    'R',        'E',        'H',        '5',        'N',        'D' | 0x80, '(',        'F',
+    'A',        'T',        'H',        'E',        'R',        ')',        '=',        'F',
+    'A',        'A',        '4',        'D',        'H',        'E',        'R' | 0x80, '(',
+    'F',        ')',        'F',        '=' | 0x80, '(',        'F',        ')',        '=',
+    'F' | 0x80,
+
+    ']',        'G' | 0x80, ' ',        '(',        'G',        ')',        ' ',        '=',
+    'J',        'I',        'Y',        '4' | 0x80, '(',        'G',        'I',        'V',
+    ')',        '=',        'G',        'I',        'H',        '5',        'V' | 0x80, ' ',
+    '(',        'G',        ')',        'I',        '^',        '=',        'G' | 0x80, '(',
+    'G',        'E',        ')',        'T',        '=',        'G',        'E',        'H',
+    '5' | 0x80, 'S',        'U',        '(',        'G',        'G',        'E',        'S',
+    ')',        '=',        'G',        'J',        'E',        'H',        '4',        'S' | 0x80,
+    '(',        'G',        'G',        ')',        '=',        'G' | 0x80, ' ',        'B',
+    '#',        '(',        'G',        ')',        '=',        'G' | 0x80, '(',        'G',
+    ')',        '+',        '=',        'J' | 0x80, '(',        'G',        'R',        'E',
+    'A',        'T',        ')',        '=',        'G',        'R',        'E',        'Y',
+    '4',        'T' | 0x80, '(',        'G',        'O',        'N',        ')',        'E',
+    '=',        'G',        'A',        'O',        '5',        'N' | 0x80, '#',        '(',
+    'G',        'H',        ')',        '=' | 0x80, ' ',        '(',        'G',        'N',
+    ')',        '=',        'N' | 0x80, '(',        'G',        ')',        '=',        'G' | 0x80,
+
+    ']',        'H' | 0x80, ' ',        '(',        'H',        ')',        ' ',        '=',
+    'E',        'Y',        '4',        'C',        'H' | 0x80, ' ',        '(',        'H',
+    'A',        'V',        ')',        '=',        '/',        'H',        'A',        'E',
+    '6',        'V' | 0x80, ' ',        '(',        'H',        'E',        'R',        'E',
+    ')',        '=',        '/',        'H',        'I',        'Y',        'R' | 0x80, ' ',
+    '(',        'H',        'O',        'U',        'R',        ')',        '=',        'A',
+    'W',        '5',        'E',        'R' | 0x80, '(',        'H',        'O',        'W',
+    ')',        '=',        '/',        'H',        'A',        'W' | 0x80, '(',        'H',
+    ')',        '#',        '=',        '/',        'H' | 0x80, '(',        'H',        ')',
+    '=' | 0x80,
+
+    ']',        'I' | 0x80, ' ',        '(',        'I',        'N',        ')',        '=',
+    'I',        'H',        'N' | 0x80, ' ',        '(',        'I',        ')',        ' ',
+    '=',        'A',        'Y',        '4' | 0x80, '(',        'I',        ')',        ' ',
+    '=',        'A',        'Y' | 0x80, '(',        'I',        'N',        ')',        'D',
+    '=',        'A',        'Y',        '5',        'N' | 0x80, 'S',        'E',        'M',
+    '(',        'I',        ')',        '=',        'I',        'Y' | 0x80, ' ',        'A',
+    'N',        'T',        '(',        'I',        ')',        '=',        'A',        'Y' | 0x80,
+    '(',        'I',        'E',        'R',        ')',        '=',        'I',        'Y',
+    'E',        'R' | 0x80, '#',        ':',        'R',        '(',        'I',        'E',
+    'D',        ')',        ' ',        '=',        'I',        'Y',        'D' | 0x80, '(',
+    'I',        'E',        'D',        ')',        ' ',        '=',        'A',        'Y',
+    '5',        'D' | 0x80, '(',        'I',        'E',        'N',        ')',        '=',
+    'I',        'Y',        'E',        'H',        'N' | 0x80, '(',        'I',        'E',
+    ')',        'T',        '=',        'A',        'Y',        '4',        'E',        'H' | 0x80,
+    '(',        'I',        '\'',       ')',        '=',        'A',        'Y',        '5' | 0x80,
+    ' ',        ':',        '(',        'I',        ')',        '^',        '%',        '=',
+    'A',        'Y',        '5' | 0x80, ' ',        ':',        '(',        'I',        'E',
+    ')',        ' ',        '=',        'A',        'Y',        '4' | 0x80, '(',        'I',
+    ')',        '%',        '=',        'I',        'Y' | 0x80, '(',        'I',        'E',
+    ')',        '=',        'I',        'Y',        '4' | 0x80, ' ',        '(',        'I',
+    'D',        'E',        'A',        ')',        '=',        'A',        'Y',        'D',
+    'I',        'Y',        '5',        'A',        'H' | 0x80, '(',        'I',        ')',
+    '^',        '+',        ':',        '#',        '=',        'I',        'H' | 0x80, '(',
+    'I',        'R',        ')',        '#',        '=',        'A',        'Y',        'R' | 0x80,
+    '(',        'I',        'Z',        ')',        '%',        '=',        'A',        'Y',
+    'Z' | 0x80, '(',        'I',        'S',        ')',        '%',        '=',        'A',
+    'Y',        'Z' | 0x80, 'I',        '^',        '(',        'I',        ')',        '^',
+    '#',        '=',        'I',        'H' | 0x80, '+',        '^',        '(',        'I',
+    ')',        '^',        '+',        '=',        'A',        'Y' | 0x80, '#',        ':',
+    '^',        '(',        'I',        ')',        '^',        '+',        '=',        'I',
+    'H' | 0x80, '(',        'I',        ')',        '^',        '+',        '=',        'A',
+    'Y' | 0x80, '(',        'I',        'R',        ')',        '=',        'E',        'R' | 0x80,
+    '(',        'I',        'G',        'H',        ')',        '=',        'A',        'Y',
+    '4' | 0x80, '(',        'I',        'L',        'D',        ')',        '=',        'A',
+    'Y',        '5',        'L',        'D' | 0x80, ' ',        '(',        'I',        'G',
+    'N',        ')',        '=',        'I',        'H',        'G',        'N' | 0x80, '(',
+    'I',        'G',        'N',        ')',        ' ',        '=',        'A',        'Y',
+    '4',        'N' | 0x80, '(',        'I',        'G',        'N',        ')',        '^',
+    '=',        'A',        'Y',        '4',        'N' | 0x80, '(',        'I',        'G',
+    'N',        ')',        '%',        '=',        'A',        'Y',        '4',        'N' | 0x80,
+    '(',        'I',        'C',        'R',        'O',        ')',        '=',        'A',
+    'Y',        '4',        'K',        'R',        'O',        'H' | 0x80, '(',        'I',
+    'Q',        'U',        'E',        ')',        '=',        'I',        'Y',        '4',
+    'K' | 0x80, '(',        'I',        ')',        '=',        'I',        'H' | 0x80,
+
+    ']',        'J' | 0x80, ' ',        '(',        'J',        ')',        ' ',        '=',
+    'J',        'E',        'Y',        '4' | 0x80, '(',        'J',        ')',        '=',
+    'J' | 0x80,
+
+    ']',        'K' | 0x80, ' ',        '(',        'K',        ')',        ' ',        '=',
+    'K',        'E',        'Y',        '4' | 0x80, ' ',        '(',        'K',        ')',
+    'N',        '=' | 0x80, '(',        'K',        ')',        '=',        'K' | 0x80,
+
+    ']',        'L' | 0x80, ' ',        '(',        'L',        ')',        ' ',        '=',
+    'E',        'H',        '4',        'L' | 0x80, '(',        'L',        'O',        ')',
+    'C',        '#',        '=',        'L',        'O',        'W' | 0x80, 'L',        '(',
+    'L',        ')',        '=' | 0x80, '#',        ':',        '^',        '(',        'L',
+    ')',        '%',        '=',        'U',        'L' | 0x80, '(',        'L',        'E',
+    'A',        'D',        ')',        '=',        'L',        'I',        'Y',        'D' | 0x80,
+    ' ',        '(',        'L',        'A',        'U',        'G',        'H',        ')',
+    '=',        'L',        'A',        'E',        '4',        'F' | 0x80, '(',        'L',
+    ')',        '=',        'L' | 0x80,
+
+    ']',        'M' | 0x80, ' ',        '(',        'M',        ')',        ' ',        '=',
+    'E',        'H',        '4',        'M' | 0x80, ' ',        '(',        'M',        'R',
+    '.',        ')',        ' ',        '=',        'M',        'I',        'H',        '4',
+    'S',        'T',        'E',        'R' | 0x80, ' ',        '(',        'M',        'S',
+    '.',        ')',        '=',        'M',        'I',        'H',        '5',        'Z' | 0x80,
+    ' ',        '(',        'M',        'R',        'S',        '.',        ')',        ' ',
+    '=',        'M',        'I',        'H',        '4',        'S',        'I',        'X',
+    'Z' | 0x80, '(',        'M',        'O',        'V',        ')',        '=',        'M',
+    'U',        'W',        '4',        'V' | 0x80, '(',        'M',        'A',        'C',
+    'H',        'I',        'N',        ')',        '=',        'M',        'A',        'H',
+    'S',        'H',        'I',        'Y',        '5',        'N' | 0x80, 'M',        '(',
+    'M',        ')',        '=' | 0x80, '(',        'M',        ')',        '=',        'M' | 0x80,
+
+    ']',        'N' | 0x80, ' ',        '(',        'N',        ')',        ' ',        '=',
+    'E',        'H',        '4',        'N' | 0x80, 'E',        '(',        'N',        'G',
+    ')',        '+',        '=',        'N',        'J' | 0x80, '(',        'N',        'G',
+    ')',        'R',        '=',        'N',        'X',        'G' | 0x80, '(',        'N',
+    'G',        ')',        '#',        '=',        'N',        'X',        'G' | 0x80, '(',
+    'N',        'G',        'L',        ')',        '%',        '=',        'N',        'X',
+    'G',        'U',        'L' | 0x80, '(',        'N',        'G',        ')',        '=',
+    'N',        'X' | 0x80, '(',        'N',        'K',        ')',        '=',        'N',
+    'X',        'K' | 0x80, ' ',        '(',        'N',        'O',        'W',        ')',
+    ' ',        '=',        'N',        'A',        'W',        '4' | 0x80, 'N',        '(',
+    'N',        ')',        '=' | 0x80, '(',        'N',        'O',        'N',        ')',
+    'E',        '=',        'N',        'A',        'H',        '4',        'N' | 0x80, '(',
+    'N',        ')',        '=',        'N' | 0x80,
+
+    ']',        'O' | 0x80, ' ',        '(',        'O',        ')',        ' ',        '=',
+    'O',        'H',        '4',        'W' | 0x80, '(',        'O',        'F',        ')',
+    ' ',        '=',        'A',        'H',        'V' | 0x80, ' ',        '(',        'O',
+    'H',        ')',        ' ',        '=',        'O',        'W',        '5' | 0x80, '(',
+    'O',        'R',        'O',        'U',        'G',        'H',        ')',        '=',
+    'E',        'R',        '4',        'O',        'W' | 0x80, '#',        ':',        '(',
+    'O',        'R',        ')',        ' ',        '=',        'E',        'R' | 0x80, '#',
+    ':',        '(',        'O',        'R',        'S',        ')',        ' ',        '=',
+    'E',        'R',        'Z' | 0x80, '(',        'O',        'R',        ')',        '=',
+    'A',        'O',        'R' | 0x80, ' ',        '(',        'O',        'N',        'E',
+    ')',        '=',        'W',        'A',        'H',        'N' | 0x80, '#',        '(',
+    'O',        'N',        'E',        ')',        ' ',        '=',        'W',        'A',
+    'H',        'N' | 0x80, '(',        'O',        'W',        ')',        '=',        'O',
+    'W' | 0x80, ' ',        '(',        'O',        'V',        'E',        'R',        ')',
+    '=',        'O',        'W',        '5',        'V',        'E',        'R' | 0x80, 'P',
+    'R',        '(',        'O',        ')',        'V',        '=',        'U',        'W',
+    '4' | 0x80, '(',        'O',        'V',        ')',        '=',        'A',        'H',
+    '4',        'V' | 0x80, '(',        'O',        ')',        '^',        '%',        '=',
+    'O',        'W',        '5' | 0x80, '(',        'O',        ')',        '^',        'E',
+    'N',        '=',        'O',        'W' | 0x80, '(',        'O',        ')',        '^',
+    'I',        '#',        '=',        'O',        'W',        '5' | 0x80, '(',        'O',
+    'L',        ')',        'D',        '=',        'O',        'W',        '4',        'L' | 0x80,
+    '(',        'O',        'U',        'G',        'H',        'T',        ')',        '=',
+    'A',        'O',        '5',        'T' | 0x80, '(',        'O',        'U',        'G',
+    'H',        ')',        '=',        'A',        'H',        '5',        'F' | 0x80, ' ',
+    '(',        'O',        'U',        ')',        '=',        'A',        'W' | 0x80, 'H',
+    '(',        'O',        'U',        ')',        'S',        '#',        '=',        'A',
+    'W',        '4' | 0x80, '(',        'O',        'U',        'S',        ')',        '=',
+    'A',        'X',        'S' | 0x80, '(',        'O',        'U',        'R',        ')',
+    '=',        'O',        'H',        'R' | 0x80, '(',        'O',        'U',        'L',
+    'D',        ')',        '=',        'U',        'H',        '5',        'D' | 0x80, '(',
+    'O',        'U',        ')',        '^',        'L',        '=',        'A',        'H',
+    '5' | 0x80, '(',        'O',        'U',        'P',        ')',        '=',        'U',
+    'W',        '5',        'P' | 0x80, '(',        'O',        'U',        ')',        '=',
+    'A',        'W' | 0x80, '(',        'O',        'Y',        ')',        '=',        'O',
+    'Y' | 0x80, '(',        'O',        'I',        'N',        'G',        ')',        '=',
+    'O',        'W',        '4',        'I',        'H',        'N',        'X' | 0x80, '(',
+    'O',        'I',        ')',        '=',        'O',        'Y',        '5' | 0x80, '(',
+    'O',        'O',        'R',        ')',        '=',        'O',        'H',        '5',
+    'R' | 0x80, '(',        'O',        'O',        'K',        ')',        '=',        'U',
+    'H',        '5',        'K' | 0x80, 'F',        '(',        'O',        'O',        'D',
+    ')',        '=',        'U',        'W',        '5',        'D' | 0x80, 'L',        '(',
+    'O',        'O',        'D',        ')',        '=',        'A',        'H',        '5',
+    'D' | 0x80, 'M',        '(',        'O',        'O',        'D',        ')',        '=',
+    'U',        'W',        '5',        'D' | 0x80, '(',        'O',        'O',        'D',
+    ')',        '=',        'U',        'H',        '5',        'D' | 0x80, 'F',        '(',
+    'O',        'O',        'T',        ')',        '=',        'U',        'H',        '5',
+    'T' | 0x80, '(',        'O',        'O',        ')',        '=',        'U',        'W',
+    '5' | 0x80, '(',        'O',        '\'',       ')',        '=',        'O',        'H' | 0x80,
+    '(',        'O',        ')',        'E',        '=',        'O',        'W' | 0x80, '(',
+    'O',        ')',        ' ',        '=',        'O',        'W' | 0x80, '(',        'O',
+    'A',        ')',        '=',        'O',        'W',        '4' | 0x80, ' ',        '(',
+    'O',        'N',        'L',        'Y',        ')',        '=',        'O',        'W',
+    '4',        'N',        'L',        'I',        'Y' | 0x80, ' ',        '(',        'O',
+    'N',        'C',        'E',        ')',        '=',        'W',        'A',        'H',
+    '4',        'N',        'S' | 0x80, '(',        'O',        'N',        '\'',       'T',
+    ')',        '=',        'O',        'W',        '4',        'N',        'T' | 0x80, 'C',
+    '(',        'O',        ')',        'N',        '=',        'A',        'A' | 0x80, '(',
+    'O',        ')',        'N',        'G',        '=',        'A',        'O' | 0x80, ' ',
+    ':',        '^',        '(',        'O',        ')',        'N',        '=',        'A',
+    'H' | 0x80, 'I',        '(',        'O',        'N',        ')',        '=',        'U',
+    'N' | 0x80, '#',        ':',        '(',        'O',        'N',        ')',        '=',
+    'U',        'N' | 0x80, '#',        '^',        '(',        'O',        'N',        ')',
+    '=',        'U',        'N' | 0x80, '(',        'O',        ')',        'S',        'T',
+    '=',        'O',        'W' | 0x80, '(',        'O',        'F',        ')',        '^',
+    '=',        'A',        'O',        '4',        'F' | 0x80, '(',        'O',        'T',
+    'H',        'E',        'R',        ')',        '=',        'A',        'H',        '5',
+    'D',        'H',        'E',        'R' | 0x80, 'R',        '(',        'O',        ')',
+    'B',        '=',        'R',        'A',        'A' | 0x80, '^',        'R',        '(',
+    'O',        ')',        ':',        '#',        '=',        'O',        'W',        '5' | 0x80,
+    '(',        'O',        'S',        'S',        ')',        ' ',        '=',        'A',
+    'O',        '5',        'S' | 0x80, '#',        ':',        '^',        '(',        'O',
+    'M',        ')',        '=',        'A',        'H',        'M' | 0x80, '(',        'O',
+    ')',        '=',        'A',        'A' | 0x80,
+
+    ']',        'P' | 0x80, ' ',        '(',        'P',        ')',        ' ',        '=',
+    'P',        'I',        'Y',        '4' | 0x80, '(',        'P',        'H',        ')',
+    '=',        'F' | 0x80, '(',        'P',        'E',        'O',        'P',        'L',
+    ')',        '=',        'P',        'I',        'Y',        '5',        'P',        'U',
+    'L' | 0x80, '(',        'P',        'O',        'W',        ')',        '=',        'P',
+    'A',        'W',        '4' | 0x80, '(',        'P',        'U',        'T',        ')',
+    ' ',        '=',        'P',        'U',        'H',        'T' | 0x80, '(',        'P',
+    ')',        'P',        '=' | 0x80, '(',        'P',        ')',        'S',        '=' | 0x80,
+    '(',        'P',        ')',        'N',        '=' | 0x80, '(',        'P',        'R',
+    'O',        'F',        '.',        ')',        '=',        'P',        'R',        'O',
+    'H',        'F',        'E',        'H',        '4',        'S',        'E',        'R' | 0x80,
+    '(',        'P',        ')',        '=',        'P' | 0x80,
+
+    ']',        'Q' | 0x80, ' ',        '(',        'Q',        ')',        ' ',        '=',
+    'K',        'Y',        'U',        'W',        '4' | 0x80, '(',        'Q',        'U',
+    'A',        'R',        ')',        '=',        'K',        'W',        'O',        'H',
+    '5',        'R' | 0x80, '(',        'Q',        'U',        ')',        '=',        'K',
+    'W' | 0x80, '(',        'Q',        ')',        '=',        'K' | 0x80, ']',        'R' | 0x80,
+    ' ',        '(',        'R',        ')',        ' ',        '=',        'A',        'A',
+    '5',        'R' | 0x80, ' ',        '(',        'R',        'E',        ')',        '^',
+    '#',        '=',        'R',        'I',        'Y' | 0x80, '(',        'R',        ')',
+    'R',        '=' | 0x80, '(',        'R',        ')',        '=',        'R' | 0x80,
+
+    ']',        'S' | 0x80, ' ',        '(',        'S',        ')',        ' ',        '=',
+    'E',        'H',        '4',        'S' | 0x80, '(',        'S',        'H',        ')',
+    '=',        'S',        'H' | 0x80, '#',        '(',        'S',        'I',        'O',
+    'N',        ')',        '=',        'Z',        'H',        'U',        'N' | 0x80, '(',
+    'S',        'O',        'M',        'E',        ')',        '=',        'S',        'A',
+    'H',        'M' | 0x80, '#',        '(',        'S',        'U',        'R',        ')',
+    '#',        '=',        'Z',        'H',        'E',        'R' | 0x80, '(',        'S',
+    'U',        'R',        ')',        '#',        '=',        'S',        'H',        'E',
+    'R' | 0x80, '#',        '(',        'S',        'U',        ')',        '#',        '=',
+    'Z',        'H',        'U',        'W' | 0x80, '#',        '(',        'S',        'S',
+    'U',        ')',        '#',        '=',        'S',        'H',        'U',        'W' | 0x80,
+    '#',        '(',        'S',        'E',        'D',        ')',        '=',        'Z',
+    'D' | 0x80, '#',        '(',        'S',        ')',        '#',        '=',        'Z' | 0x80,
+    '(',        'S',        'A',        'I',        'D',        ')',        '=',        'S',
+    'E',        'H',        'D' | 0x80, '^',        '(',        'S',        'I',        'O',
+    'N',        ')',        '=',        'S',        'H',        'U',        'N' | 0x80, '(',
+    'S',        ')',        'S',        '=' | 0x80, '.',        '(',        'S',        ')',
+    ' ',        '=',        'Z' | 0x80, '#',        ':',        '.',        'E',        '(',
+    'S',        ')',        ' ',        '=',        'Z' | 0x80, '#',        ':',        '^',
+    '#',        '(',        'S',        ')',        ' ',        '=',        'S' | 0x80, 'U',
+    '(',        'S',        ')',        ' ',        '=',        'S' | 0x80, ' ',        ':',
+    '#',        '(',        'S',        ')',        ' ',        '=',        'Z' | 0x80, '#',
+    '#',        '(',        'S',        ')',        ' ',        '=',        'Z' | 0x80, ' ',
+    '(',        'S',        'C',        'H',        ')',        '=',        'S',        'K' | 0x80,
+    '(',        'S',        ')',        'C',        '+',        '=' | 0x80, '#',        '(',
+    'S',        'M',        ')',        '=',        'Z',        'U',        'M' | 0x80, '#',
+    '(',        'S',        'N',        ')',        '\'',       '=',        'Z',        'U',
+    'M' | 0x80, '(',        'S',        'T',        'L',        'E',        ')',        '=',
+    'S',        'U',        'L' | 0x80, '(',        'S',        ')',        '=',        'S' | 0x80,
+
+    ']',        'T' | 0x80, ' ',        '(',        'T',        ')',        ' ',        '=',
+    'T',        'I',        'Y',        '4' | 0x80, ' ',        '(',        'T',        'H',
+    'E',        ')',        ' ',        '#',        '=',        'D',        'H',        'I',
+    'Y' | 0x80, ' ',        '(',        'T',        'H',        'E',        ')',        ' ',
+    '=',        'D',        'H',        'A',        'X' | 0x80, '(',        'T',        'O',
+    ')',        ' ',        '=',        'T',        'U',        'X' | 0x80, ' ',        '(',
+    'T',        'H',        'A',        'T',        ')',        '=',        'D',        'H',
+    'A',        'E',        'T' | 0x80, ' ',        '(',        'T',        'H',        'I',
+    'S',        ')',        ' ',        '=',        'D',        'H',        'I',        'H',
+    'S' | 0x80, ' ',        '(',        'T',        'H',        'E',        'Y',        ')',
+    '=',        'D',        'H',        'E',        'Y' | 0x80, ' ',        '(',        'T',
+    'H',        'E',        'R',        'E',        ')',        '=',        'D',        'H',
+    'E',        'H',        'R' | 0x80, '(',        'T',        'H',        'E',        'R',
+    ')',        '=',        'D',        'H',        'E',        'R' | 0x80, '(',        'T',
+    'H',        'E',        'I',        'R',        ')',        '=',        'D',        'H',
+    'E',        'H',        'R' | 0x80, ' ',        '(',        'T',        'H',        'A',
+    'N',        ')',        ' ',        '=',        'D',        'H',        'A',        'E',
+    'N' | 0x80, ' ',        '(',        'T',        'H',        'E',        'M',        ')',
+    ' ',        '=',        'D',        'H',        'A',        'E',        'N' | 0x80, '(',
+    'T',        'H',        'E',        'S',        'E',        ')',        ' ',        '=',
+    'D',        'H',        'I',        'Y',        'Z' | 0x80, ' ',        '(',        'T',
+    'H',        'E',        'N',        ')',        '=',        'D',        'H',        'E',
+    'H',        'N' | 0x80, '(',        'T',        'H',        'R',        'O',        'U',
+    'G',        'H',        ')',        '=',        'T',        'H',        'R',        'U',
+    'W',        '4' | 0x80, '(',        'T',        'H',        'O',        'S',        'E',
+    ')',        '=',        'D',        'H',        'O',        'H',        'Z' | 0x80, '(',
+    'T',        'H',        'O',        'U',        'G',        'H',        ')',        ' ',
+    '=',        'D',        'H',        'O',        'W' | 0x80, '(',        'T',        'O',
+    'D',        'A',        'Y',        ')',        '=',        'T',        'U',        'X',
+    'D',        'E',        'Y' | 0x80, '(',        'T',        'O',        'M',        'O',
+    ')',        'R',        'R',        'O',        'W',        '=',        'T',        'U',
+    'M',        'A',        'A',        '5' | 0x80, '(',        'T',        'O',        ')',
+    'T',        'A',        'L',        '=',        'T',        'O',        'W',        '5' | 0x80,
+    ' ',        '(',        'T',        'H',        'U',        'S',        ')',        '=',
+    'D',        'H',        'A',        'H',        '4',        'S' | 0x80, '(',        'T',
+    'H',        ')',        '=',        'T',        'H' | 0x80, '#',        ':',        '(',
+    'T',        'E',        'D',        ')',        '=',        'T',        'I',        'X',
+    'D' | 0x80, 'S',        '(',        'T',        'I',        ')',        '#',        'N',
+    '=',        'C',        'H' | 0x80, '(',        'T',        'I',        ')',        'O',
+    '=',        'S',        'H' | 0x80, '(',        'T',        'I',        ')',        'A',
+    '=',        'S',        'H' | 0x80, '(',        'T',        'I',        'E',        'N',
+    ')',        '=',        'S',        'H',        'U',        'N' | 0x80, '(',        'T',
+    'U',        'R',        ')',        '#',        '=',        'C',        'H',        'E',
+    'R' | 0x80, '(',        'T',        'U',        ')',        'A',        '=',        'C',
+    'H',        'U',        'W' | 0x80, ' ',        '(',        'T',        'W',        'O',
+    ')',        '=',        'T',        'U',        'W' | 0x80, '&',        '(',        'T',
+    ')',        'E',        'N',        ' ',        '=' | 0x80, '(',        'T',        ')',
+    '=',        'T' | 0x80,
+
+    ']',        'U' | 0x80, ' ',        '(',        'U',        ')',        ' ',        '=',
+    'Y',        'U',        'W',        '4' | 0x80, ' ',        '(',        'U',        'N',
+    ')',        'I',        '=',        'Y',        'U',        'W',        'N' | 0x80, ' ',
+    '(',        'U',        'N',        ')',        '=',        'A',        'H',        'N' | 0x80,
+    ' ',        '(',        'U',        'P',        'O',        'N',        ')',        '=',
+    'A',        'X',        'P',        'A',        'O',        'N' | 0x80, '@',        '(',
+    'U',        'R',        ')',        '#',        '=',        'U',        'H',        '4',
+    'R' | 0x80, '(',        'U',        'R',        ')',        '#',        '=',        'Y',
+    'U',        'H',        '4',        'R' | 0x80, '(',        'U',        'R',        ')',
+    '=',        'E',        'R' | 0x80, '(',        'U',        ')',        '^',        ' ',
+    '=',        'A',        'H' | 0x80, '(',        'U',        ')',        '^',        '^',
+    '=',        'A',        'H',        '5' | 0x80, '(',        'U',        'Y',        ')',
+    '=',        'A',        'Y',        '5' | 0x80, ' ',        'G',        '(',        'U',
+    ')',        '#',        '=' | 0x80, 'G',        '(',        'U',        ')',        '%',
+    '=' | 0x80, 'G',        '(',        'U',        ')',        '#',        '=',        'W' | 0x80,
+    '#',        'N',        '(',        'U',        ')',        '=',        'Y',        'U',
+    'W' | 0x80, '@',        '(',        'U',        ')',        '=',        'U',        'W' | 0x80,
+    '(',        'U',        ')',        '=',        'Y',        'U',        'W' | 0x80,
+
+    ']',        'V' | 0x80, ' ',        '(',        'V',        ')',        ' ',        '=',
+    'V',        'I',        'Y',        '4' | 0x80, '(',        'V',        'I',        'E',
+    'W',        ')',        '=',        'V',        'Y',        'U',        'W',        '5' | 0x80,
+    '(',        'V',        ')',        '=',        'V' | 0x80,
+
+    ']',        'W' | 0x80, ' ',        '(',        'W',        ')',        ' ',        '=',
+    'D',        'A',        'H',        '4',        'B',        'U',        'L',        'Y',
+    'U',        'W' | 0x80, ' ',        '(',        'W',        'E',        'R',        'E',
+    ')',        '=',        'W',        'E',        'R' | 0x80, '(',        'W',        'A',
+    ')',        'S',        'H',        '=',        'W',        'A',        'A' | 0x80, '(',
+    'W',        'A',        ')',        'S',        'T',        '=',        'W',        'E',
+    'Y' | 0x80, '(',        'W',        'A',        ')',        'S',        '=',        'W',
+    'A',        'H' | 0x80, '(',        'W',        'A',        ')',        'T',        '=',
+    'W',        'A',        'A' | 0x80, '(',        'W',        'H',        'E',        'R',
+    'E',        ')',        '=',        'W',        'H',        'E',        'H',        'R' | 0x80,
+    '(',        'W',        'H',        'A',        'T',        ')',        '=',        'W',
+    'H',        'A',        'H',        'T' | 0x80, '(',        'W',        'H',        'O',
+    'L',        ')',        '=',        '/',        'H',        'O',        'W',        'L' | 0x80,
+    '(',        'W',        'H',        'O',        ')',        '=',        '/',        'H',
+    'U',        'W' | 0x80, '(',        'W',        'H',        ')',        '=',        'W',
+    'H' | 0x80, '(',        'W',        'A',        'R',        ')',        '#',        '=',
+    'W',        'E',        'H',        'R' | 0x80, '(',        'W',        'A',        'R',
+    ')',        '=',        'W',        'A',        'O',        'R' | 0x80, '(',        'W',
+    'O',        'R',        ')',        '^',        '=',        'W',        'E',        'R' | 0x80,
+    '(',        'W',        'R',        ')',        '=',        'R' | 0x80, '(',        'W',
+    'O',        'M',        ')',        'A',        '=',        'W',        'U',        'H',
+    'M' | 0x80, '(',        'W',        'O',        'M',        ')',        'E',        '=',
+    'W',        'I',        'H',        'M' | 0x80, '(',        'W',        'E',        'A',
+    ')',        'R',        '=',        'W',        'E',        'H' | 0x80, '(',        'W',
+    'A',        'N',        'T',        ')',        '=',        'W',        'A',        'A',
+    '5',        'N',        'T' | 0x80, 'A',        'N',        'S',        '(',        'W',
+    'E',        'R',        ')',        '=',        'E',        'R' | 0x80, '(',        'W',
+    ')',        '=',        'W' | 0x80,
+
+    ']',        'X' | 0x80, ' ',        '(',        'X',        ')',        ' ',        '=',
+    'E',        'H',        '4',        'K',        'R' | 0x80, ' ',        '(',        'X',
+    ')',        '=',        'Z' | 0x80, '(',        'X',        ')',        '=',        'K',
+    'S' | 0x80,
+
+    ']',        'Y' | 0x80, ' ',        '(',        'Y',        ')',        ' ',        '=',
+    'W',        'A',        'Y',        '4' | 0x80, '(',        'Y',        'O',        'U',
+    'N',        'G',        ')',        '=',        'Y',        'A',        'H',        'N',
+    'X' | 0x80, ' ',        '(',        'Y',        'O',        'U',        'R',        ')',
+    '=',        'Y',        'O',        'H',        'R' | 0x80, ' ',        '(',        'Y',
+    'O',        'U',        ')',        '=',        'Y',        'U',        'W' | 0x80, ' ',
+    '(',        'Y',        'E',        'S',        ')',        '=',        'Y',        'E',
+    'H',        'S' | 0x80, ' ',        '(',        'Y',        ')',        '=',        'Y' | 0x80,
+    'F',        '(',        'Y',        ')',        '=',        'A',        'Y' | 0x80, 'P',
+    'S',        '(',        'Y',        'C',        'H',        ')',        '=',        'A',
+    'Y',        'K' | 0x80, '#',        ':',        '^',        '(',        'Y',        ')',
+    '=',        'I',        'Y' | 0x80, '#',        ':',        '^',        '(',        'Y',
+    ')',        'I',        '=',        'I',        'Y' | 0x80, ' ',        ':',        '(',
+    'Y',        ')',        ' ',        '=',        'A',        'Y' | 0x80, ' ',        ':',
+    '(',        'Y',        ')',        '#',        '=',        'A',        'Y' | 0x80, ' ',
+    ':',        '(',        'Y',        ')',        '^',        '+',        ':',        '#',
+    '=',        'I',        'H' | 0x80, ' ',        ':',        '(',        'Y',        ')',
+    '^',        '#',        '=',        'A',        'Y' | 0x80, '(',        'Y',        ')',
+    '=',        'I',        'H' | 0x80,
+
+    ']',        'Z' | 0x80, ' ',        '(',        'Z',        ')',        ' ',        '=',
+    'Z',        'I',        'Y',        '4' | 0x80, '(',        'Z',        ')',        '=',
+    'Z' | 0x80, 'j' | 0x80};
+
+const unsigned char rules2[] = {
+    '(',        'A',        ')',        '=' | 0x80, '(',        '!',        ')',        '=',
+    '.' | 0x80, '(',        '"',        ')',        ' ',        '=',        '-',        'A',
+    'H',        '5',        'N',        'K',        'W',        'O',        'W',        'T',
+    '-' | 0x80, '(',        '"',        ')',        '=',        'K',        'W',        'O',
+    'W',        '4',        'T',        '-' | 0x80, '(',        '#',        ')',        '=',
+    ' ',        'N',        'A',        'H',        '4',        'M',        'B',        'E',
+    'R' | 0x80, '(',        '$',        ')',        '=',        ' ',        'D',        'A',
+    'A',        '4',        'L',        'E',        'R' | 0x80, '(',        '%',        ')',
+    '=',        ' ',        'P',        'E',        'R',        'S',        'E',        'H',
+    '4',        'N',        'T' | 0x80, '(',        '&',        ')',        '=',        ' ',
+    'A',        'E',        'N',        'D' | 0x80, '(',        '\'',       ')',        '=' | 0x80,
+    '(',        '*',        ')',        '=',        ' ',        'A',        'E',        '4',
+    'S',        'T',        'E',        'R',        'I',        'H',        'S',        'K' | 0x80,
+    '(',        '+',        ')',        '=',        ' ',        'P',        'L',        'A',
+    'H',        '4',        'S' | 0x80, '(',        ',',        ')',        '=',        ',' | 0x80,
+    ' ',        '(',        '-',        ')',        ' ',        '=',        '-' | 0x80, '(',
+    '-',        ')',        '=' | 0x80, '(',        '.',        ')',        '=',        ' ',
+    'P',        'O',        'Y',        'N',        'T' | 0x80, '(',        '/',        ')',
+    '=',        ' ',        'S',        'L',        'A',        'E',        '4',        'S',
+    'H' | 0x80, '(',        '0',        ')',        '=',        ' ',        'Z',        'I',
+    'Y',        '4',        'R',        'O',        'W' | 0x80, ' ',        '(',        '1',
+    'S',        'T',        ')',        '=',        'F',        'E',        'R',        '4',
+    'S',        'T' | 0x80, ' ',        '(',        '1',        '0',        'T',        'H',
+    ')',        '=',        'T',        'E',        'H',        '4',        'N',        'T',
+    'H' | 0x80, '(',        '1',        ')',        '=',        ' ',        'W',        'A',
+    'H',        '4',        'N' | 0x80, ' ',        '(',        '2',        'N',        'D',
+    ')',        '=',        'S',        'E',        'H',        '4',        'K',        'U',
+    'N',        'D' | 0x80, '(',        '2',        ')',        '=',        ' ',        'T',
+    'U',        'W',        '4' | 0x80, ' ',        '(',        '3',        'R',        'D',
+    ')',        '=',        'T',        'H',        'E',        'R',        '4',        'D' | 0x80,
+    '(',        '3',        ')',        '=',        ' ',        'T',        'H',        'R',
+    'I',        'Y',        '4' | 0x80, '(',        '4',        ')',        '=',        ' ',
+    'F',        'O',        'H',        '4',        'R' | 0x80, ' ',        '(',        '5',
+    'T',        'H',        ')',        '=',        'F',        'I',        'H',        '4',
+    'F',        'T',        'H' | 0x80, '(',        '5',        ')',        '=',        ' ',
+    'F',        'A',        'Y',        '4',        'V' | 0x80, ' ',        '(',        '6',
+    '4',        ')',        ' ',        '=',        'S',        'I',        'H',        '4',
+    'K',        'S',        'T',        'I',        'Y',        ' ',        'F',        'O',
+    'H',        'R' | 0x80, '(',        '6',        ')',        '=',        ' ',        'S',
+    'I',        'H',        '4',        'K',        'S' | 0x80, '(',        '7',        ')',
+    '=',        ' ',        'S',        'E',        'H',        '4',        'V',        'U',
+    'N' | 0x80, ' ',        '(',        '8',        'T',        'H',        ')',        '=',
+    'E',        'Y',        '4',        'T',        'H' | 0x80, '(',        '8',        ')',
+    '=',        ' ',        'E',        'Y',        '4',        'T' | 0x80, '(',        '9',
+    ')',        '=',        ' ',        'N',        'A',        'Y',        '4',        'N' | 0x80,
+    '(',        ':',        ')',        '=',        '.' | 0x80, '(',        ';',        ')',
+    '=',        '.' | 0x80, '(',        '<',        ')',        '=',        ' ',        'L',
+    'E',        'H',        '4',        'S',        ' ',        'D',        'H',        'A',
+    'E',        'N' | 0x80, '(',        '=',        ')',        '=',        ' ',        'I',
+    'Y',        '4',        'K',        'W',        'U',        'L',        'Z' | 0x80, '(',
+    '>',        ')',        '=',        ' ',        'G',        'R',        'E',        'Y',
+    '4',        'T',        'E',        'R',        ' ',        'D',        'H',        'A',
+    'E',        'N' | 0x80, '(',        '?',        ')',        '=',        '?' | 0x80, '(',
+    '@',        ')',        '=',        ' ',        'A',        'E',        '6',        'T' | 0x80,
+    '(',        '^',        ')',        '=',        ' ',        'K',        'A',        'E',
+    '4',        'R',        'I',        'X',        'T' | 0x80, ']',        'A' | 0x80};
+
+//26 items. From 'A' to 'Z'
+// positions for mem62 and mem63 for each character
+const unsigned char tab37489[] = {0,   149, 247, 162, 57, 197, 6,  126, 199, 38, 55, 78, 145,
+                                  241, 85,  161, 254, 36, 69,  45, 167, 54,  83, 46, 71, 218};
+
+const unsigned char tab37515[] = {125, 126, 126, 127, 128, 129, 130, 130, 130, 132, 132, 132, 132,
+                                  132, 133, 135, 135, 136, 136, 137, 138, 139, 139, 140, 140, 140};
+
+void STM32SAM::Output8BitAry(int index, unsigned char ary[5]) {
+    int k;
+
+    uint32_t bufferposOld = bufferpos;
+
+    bufferpos += timetable[oldtimetableindex][index];
+    oldtimetableindex = index;
+
+    int sample_uS = bufferpos - bufferposOld;
+
+    uint32_t f = 0;
+
+    // write a little bit in advance
+    for(k = 0; k < 5; k++) {
+        //   buffer[bufferpos / 50 + k] = ary[k];
+
+        // f = micros() + sample_uS / (_STM32SAM_SPEED + 1);
+        // while(micros() < f) {
+        // };
+        f = sample_uS / (_STM32SAM_SPEED + 1);
+        furi_delay_us(f);
+        SetAUDIO(ary[k]);
+        //  delayMicroseconds(sample_uS / 5 );
+    }
+
+    //  SetAUDIO(ary[0]);
+}
+
+void STM32SAM::Output8Bit(int index, unsigned char A) {
+    unsigned char ary[5] = {A, A, A, A, A};
+    Output8BitAry(index, ary);
+}
+
+//written by me because of different table positions.
+// mem[47] = ...
+// 168=pitches
+// 169=frequency1
+// 170=frequency2
+// 171=frequency3
+// 172=amplitude1
+// 173=amplitude2
+// 174=amplitude3
+unsigned char STM32SAM::Read(unsigned char p, unsigned char Y) {
+    switch(p) {
+    case 168:
+        return pitches[Y];
+    case 169:
+        return frequency1[Y];
+    case 170:
+        return frequency2[Y];
+    case 171:
+        return frequency3[Y];
+    case 172:
+        return amplitude1[Y];
+    case 173:
+        return amplitude2[Y];
+    case 174:
+        return amplitude3[Y];
+    }
+    // Serial1.println("Error reading to tables");
+    return 0;
+}
+
+void STM32SAM::Write(unsigned char p, unsigned char Y, unsigned char value) {
+    switch(p) {
+    case 168:
+        pitches[Y] = value;
+        return;
+    case 169:
+        frequency1[Y] = value;
+        return;
+    case 170:
+        frequency2[Y] = value;
+        return;
+    case 171:
+        frequency3[Y] = value;
+        return;
+    case 172:
+        amplitude1[Y] = value;
+        return;
+    case 173:
+        amplitude2[Y] = value;
+        return;
+    case 174:
+        amplitude3[Y] = value;
+        return;
+    }
+    //Serial1.println("Error writing to tables\n");
+}
+
+// -------------------------------------------------------------------------
+//Code48227
+// Render a sampled sound from the sampleTable.
+//
+//   Phoneme   Sample Start   Sample End
+//   32: S*    15             255
+//   33: SH    257            511
+//   34: F*    559            767
+//   35: TH    583            767
+//   36: /H    903            1023
+//   37: /X    1135           1279
+//   38: Z*    84             119
+//   39: ZH    340            375
+//   40: V*    596            639
+//   41: DH    596            631
+//
+//   42: CH
+//   43: **    399            511
+//
+//   44: J*
+//   45: **    257            276
+//   46: **
+//
+//   66: P*
+//   67: **    743            767
+//   68: **
+//
+//   69: T*
+//   70: **    231            255
+//   71: **
+//
+// The SampledPhonemesTable[] holds flags indicating if a phoneme is
+// voiced or not. If the upper 5 bits are zero, the sample is voiced.
+//
+// Samples in the sampleTable are compressed, with bits being converted to
+// bytes from high bit to low, as follows:
+//
+//   unvoiced 0 bit   -> X
+//   unvoiced 1 bit   -> 5
+//
+//   voiced 0 bit     -> 6
+//   voiced 1 bit     -> 24
+//
+// Where X is a value from the table:
+//
+//   { 0x18, 0x1A, 0x17, 0x17, 0x17 };
+//
+// The index into this table is determined by masking off the lower
+// 3 bits from the SampledPhonemesTable:
+//
+//        index = (SampledPhonemesTable[i] & 7) - 1;
+//
+// For voices samples, samples are interleaved between voiced output.
+
+// Code48227()
+void STM32SAM::RenderSample(unsigned char* mem66) {
+    int tempA;
+    // current phoneme's index
+    mem49 = Y;
+
+    // mask low three bits and subtract 1 get value to
+    // convert 0 bits on unvoiced samples.
+    A = mem39 & 7;
+    X = A - 1;
+
+    // store the result
+    mem56 = X;
+
+    // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 }
+    // T, S, Z                0          0x18
+    // CH, J, SH, ZH          1          0x1A
+    // P, F*, V, TH, DH       2          0x17
+    // /H                     3          0x17
+    // /X                     4          0x17
+
+    // get value from the table
+    mem53 = tab48426[X];
+    mem47 = X; //46016+mem[56]*256
+
+    // voiced sample?
+    A = mem39 & 248;
+    if(A == 0) {
+        // voiced phoneme: Z*, ZH, V*, DH
+        Y = mem49;
+        A = pitches[mem49] >> 4;
+
+        // jump to voiced portion
+        goto pos48315;
+    }
+
+    Y = A ^ 255;
+pos48274:
+
+    // step through the 8 bits in the sample
+    mem56 = 8;
+
+    // get the next sample from the table
+    // mem47*256 = offset to start of samples
+    A = sampleTable[mem47 * 256 + Y];
+pos48280:
+
+    // left shift to get the high bit
+    tempA = A;
+    A = A << 1;
+    //48281: BCC 48290
+
+    // bit not set?
+    if((tempA & 128) == 0) {
+        // convert the bit to value from table
+        X = mem53;
+        //mem[54296] = X;
+        // output the byte
+        Output8Bit(1, (X & 0x0f) * 16);
+        // if X != 0, exit loop
+        if(X != 0) goto pos48296;
+    }
+
+    // output a 5 for the on bit
+    Output8Bit(2, 5 * 16);
+
+    //48295: NOP
+pos48296:
+
+    X = 0;
+
+    // decrement counter
+    mem56--;
+
+    // if not done, jump to top of loop
+    if(mem56 != 0) goto pos48280;
+
+    // increment position
+    Y++;
+    if(Y != 0) goto pos48274;
+
+    // restore values and return
+    mem44 = 1;
+    Y = mem49;
+    return;
+
+    unsigned char phase1;
+
+pos48315:
+    // handle voiced samples here
+
+    // number of samples?
+    phase1 = A ^ 255;
+
+    Y = *mem66;
+    do {
+        //pos48321:
+
+        // shift through all 8 bits
+        mem56 = 8;
+        //A = Read(mem47, Y);
+
+        // fetch value from table
+        A = sampleTable[mem47 * 256 + Y];
+
+        // loop 8 times
+        //pos48327:
+        do {
+            //48327: ASL A
+            //48328: BCC 48337
+
+            // left shift and check high bit
+            tempA = A;
+            A = A << 1;
+            if((tempA & 128) != 0) {
+                // if bit set, output 26
+                X = 26;
+                Output8Bit(3, (X & 0xf) * 16);
+            } else {
+                //timetable 4
+                // bit is not set, output a 6
+                X = 6;
+                Output8Bit(4, (X & 0xf) * 16);
+            }
+
+            mem56--;
+        } while(mem56 != 0);
+
+        // move ahead in the table
+        Y++;
+
+        // continue until counter done
+        phase1++;
+
+    } while(phase1 != 0);
+    //  if (phase1 != 0) goto pos48321;
+
+    // restore values and return
+    A = 1;
+    mem44 = 1;
+    *mem66 = Y;
+    Y = mem49;
+    return;
+}
+
+// RENDER THE PHONEMES IN THE LIST
+//
+// The phoneme list is converted into sound through the steps:
+//
+// 1. Copy each phoneme <length> number of times into the frames list,
+//    where each frame represents 10 milliseconds of sound.
+//
+// 2. Determine the transitions lengths between phonemes, and linearly
+//    interpolate the values across the frames.
+//
+// 3. Offset the pitches by the fundamental frequency.
+//
+// 4. Render the each frame.
+
+//void Code47574()
+void STM32SAM::Render() {
+    unsigned char phase1 = 0; //mem43
+    unsigned char phase2 = 0;
+    unsigned char phase3 = 0;
+    unsigned char mem66 = 0;
+    unsigned char mem38 = 0;
+    unsigned char mem40 = 0;
+    unsigned char speedcounter = 0; //mem45
+    unsigned char mem48 = 0;
+    int i;
+    if(phonemeIndexOutput[0] == 255) return; //exit if no data
+
+    A = 0;
+    X = 0;
+    mem44 = 0;
+
+    // CREATE FRAMES
+    //
+    // The length parameter in the list corresponds to the number of frames
+    // to expand the phoneme to. Each frame represents 10 milliseconds of time.
+    // So a phoneme with a length of 7 = 7 frames = 70 milliseconds duration.
+    //
+    // The parameters are copied from the phoneme to the frame verbatim.
+
+    // pos47587:
+    do {
+        // get the index
+        Y = mem44;
+        // get the phoneme at the index
+        A = phonemeIndexOutput[mem44];
+        mem56 = A;
+
+        // if terminal phoneme, exit the loop
+        if(A == 255) break;
+
+        // period phoneme *.
+        if(A == 1) {
+            // add rising inflection
+            A = 1;
+            mem48 = 1;
+            //goto pos48376;
+            AddInflection(mem48, phase1);
+        }
+        /*
+      if (A == 2) goto pos48372;
+    */
+
+        // question mark phoneme?
+        if(A == 2) {
+            // create falling inflection
+            mem48 = 255;
+            AddInflection(mem48, phase1);
+        }
+        //  pos47615:
+
+        // get the stress amount (more stress = higher pitch)
+        phase1 = tab47492[stressOutput[Y] + 1];
+
+        // get number of frames to write
+        phase2 = phonemeLengthOutput[Y];
+        Y = mem56;
+
+        // copy from the source to the frames list
+        do {
+            frequency1[X] = freq1data[Y]; // F1 frequency
+            frequency2[X] = freq2data[Y]; // F2 frequency
+            frequency3[X] = freq3data[Y]; // F3 frequency
+            amplitude1[X] = ampl1data[Y]; // F1 amplitude
+            amplitude2[X] = ampl2data[Y]; // F2 amplitude
+            amplitude3[X] = ampl3data[Y]; // F3 amplitude
+            sampledConsonantFlag[X] =
+                sampledConsonantFlags[Y]; // phoneme data for sampled consonants
+            pitches[X] = pitch + phase1; // pitch
+            X++;
+            phase2--;
+        } while(phase2 != 0);
+        mem44++;
+    } while(mem44 != 0);
+    // -------------------
+    //pos47694:
+
+    // CREATE TRANSITIONS
+    //
+    // Linear transitions are now created to smoothly connect the
+    // end of one sustained portion of a phoneme to the following
+    // phoneme.
+    //
+    // To do this, three tables are used:
+    //
+    //  Table         Purpose
+    //  =========     ==================================================
+    //  blendRank     Determines which phoneme's blend values are used.
+    //
+    //  blendOut      The number of frames at the end of the phoneme that
+    //                will be used to transition to the following phoneme.
+    //
+    //  blendIn       The number of frames of the following phoneme that
+    //                will be used to transition into that phoneme.
+    //
+    // In creating a transition between two phonemes, the phoneme
+    // with the HIGHEST rank is used. Phonemes are ranked on how much
+    // their identity is based on their transitions. For example,
+    // vowels are and diphthongs are identified by their sustained portion,
+    // rather than the transitions, so they are given low values. In contrast,
+    // stop consonants (P, B, T, K) and glides (Y, L) are almost entirely
+    // defined by their transitions, and are given high rank values.
+    //
+    // Here are the rankings used by SAM:
+    //
+    //     Rank    Type                         Phonemes
+    //     2       All vowels                   IY, IH, etc.
+    //     5       Diphthong endings            YX, WX, ER
+    //     8       Terminal liquid consonants   LX, WX, YX, N, NX
+    //     9       Liquid consonants            L, RX, W
+    //     10      Glide                        R, OH
+    //     11      Glide                        WH
+    //     18      Voiceless fricatives         S, SH, F, TH
+    //     20      Voiced fricatives            Z, ZH, V, DH
+    //     23      Plosives, stop consonants    P, T, K, KX, DX, CH
+    //     26      Stop consonants              J, GX, B, D, G
+    //     27-29   Stop consonants (internal)   **
+    //     30      Unvoiced consonants          /H, /X and Q*
+    //     160     Nasal                        M
+    //
+    // To determine how many frames to use, the two phonemes are
+    // compared using the blendRank[] table. The phoneme with the
+    // higher rank is selected. In case of a tie, a blend of each is used:
+    //
+    //      if blendRank[phoneme1] ==  blendRank[phomneme2]
+    //          // use lengths from each phoneme
+    //          outBlendFrames = outBlend[phoneme1]
+    //          inBlendFrames = outBlend[phoneme2]
+    //      else if blendRank[phoneme1] > blendRank[phoneme2]
+    //          // use lengths from first phoneme
+    //          outBlendFrames = outBlendLength[phoneme1]
+    //          inBlendFrames = inBlendLength[phoneme1]
+    //      else
+    //          // use lengths from the second phoneme
+    //          // note that in and out are SWAPPED!
+    //          outBlendFrames = inBlendLength[phoneme2]
+    //          inBlendFrames = outBlendLength[phoneme2]
+    //
+    // Blend lengths can't be less than zero.
+    //
+    // Transitions are assumed to be symetrical, so if the transition
+    // values for the second phoneme are used, the inBlendLength and
+    // outBlendLength values are SWAPPED.
+    //
+    // For most of the parameters, SAM interpolates over the range of the last
+    // outBlendFrames-1 and the first inBlendFrames.
+    //
+    // The exception to this is the Pitch[] parameter, which is interpolates the
+    // pitch from the CENTER of the current phoneme to the CENTER of the next
+    // phoneme.
+    //
+    // Here are two examples. First, For example, consider the word "SUN" (S AH N)
+    //
+    //    Phoneme   Duration    BlendWeight    OutBlendFrames    InBlendFrames
+    //    S         2           18             1                 3
+    //    AH        8           2              4                 4
+    //    N         7           8              1                 2
+    //
+    // The formant transitions for the output frames are calculated as follows:
+    //
+    //     flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch
+    //    ------------------------------------------------
+    // S
+    //    241     0     6     0    73     0    99    61   Use S (weight 18) for transition instead of AH (weight 2)
+    //    241     0     6     0    73     0    99    61   <-- (OutBlendFrames-1) = (1-1) = 0 frames
+    // AH
+    //      0     2    10     2    66     0    96    59 * <-- InBlendFrames = 3 frames
+    //      0     4    14     3    59     0    93    57 *
+    //      0     8    18     5    52     0    90    55 *
+    //      0    15    22     9    44     1    87    53
+    //      0    15    22     9    44     1    87    53
+    //      0    15    22     9    44     1    87    53   Use N (weight 8) for transition instead of AH (weight 2).
+    //      0    15    22     9    44     1    87    53   Since N is second phoneme, reverse the IN and OUT values.
+    //      0    11    17     8    47     1    98    56 * <-- (InBlendFrames-1) = (2-1) = 1 frames
+    // N
+    //      0     8    12     6    50     1   109    58 * <-- OutBlendFrames = 1
+    //      0     5     6     5    54     0   121    61
+    //      0     5     6     5    54     0   121    61
+    //      0     5     6     5    54     0   121    61
+    //      0     5     6     5    54     0   121    61
+    //      0     5     6     5    54     0   121    61
+    //      0     5     6     5    54     0   121    61
+    //
+    // Now, consider the reverse "NUS" (N AH S):
+    //
+    //     flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch
+    //    ------------------------------------------------
+    // N
+    //     0     5     6     5    54     0   121    61
+    //     0     5     6     5    54     0   121    61
+    //     0     5     6     5    54     0   121    61
+    //     0     5     6     5    54     0   121    61
+    //     0     5     6     5    54     0   121    61
+    //     0     5     6     5    54     0   121    61   Use N (weight 8) for transition instead of AH (weight 2)
+    //     0     5     6     5    54     0   121    61   <-- (OutBlendFrames-1) = (1-1) = 0 frames
+    // AH
+    //     0     8    11     6    51     0   110    59 * <-- InBlendFrames = 2
+    //     0    11    16     8    48     0    99    56 *
+    //     0    15    22     9    44     1    87    53   Use S (weight 18) for transition instead of AH (weight 2)
+    //     0    15    22     9    44     1    87    53   Since S is second phoneme, reverse the IN and OUT values.
+    //     0     9    18     5    51     1    90    55 * <-- (InBlendFrames-1) = (3-1) = 2
+    //     0     4    14     3    58     1    93    57 *
+    // S
+    //   241     2    10     2    65     1    96    59 * <-- OutBlendFrames = 1
+    //   241     0     6     0    73     0    99    61
+
+    A = 0;
+    mem44 = 0;
+    mem49 = 0; // mem49 starts at as 0
+    X = 0;
+    while(1) //while No. 1
+    {
+        // get the current and following phoneme
+        Y = phonemeIndexOutput[X];
+        A = phonemeIndexOutput[X + 1];
+        X++;
+
+        // exit loop at end token
+        if(A == 255) break; //goto pos47970;
+
+        // get the ranking of each phoneme
+        X = A;
+        mem56 = blendRank[A];
+        A = blendRank[Y];
+
+        // compare the rank - lower rank value is stronger
+        if(A == mem56) {
+            // same rank, so use out blend lengths from each phoneme
+            phase1 = outBlendLength[Y];
+            phase2 = outBlendLength[X];
+        } else if(A < mem56) {
+            // first phoneme is stronger, so us it's blend lengths
+            phase1 = inBlendLength[X];
+            phase2 = outBlendLength[X];
+        } else {
+            // second phoneme is stronger, so use it's blend lengths
+            // note the out/in are swapped
+            phase1 = outBlendLength[Y];
+            phase2 = inBlendLength[Y];
+        }
+
+        Y = mem44;
+        A = mem49 + phonemeLengthOutput[mem44]; // A is mem49 + length
+        mem49 = A; // mem49 now holds length + position
+        A = A + phase2; //Maybe Problem because of carry flag
+
+        //47776: ADC 42
+        speedcounter = A;
+        mem47 = 168;
+        phase3 = mem49 - phase1; // what is mem49
+        A = phase1 + phase2; // total transition?
+        mem38 = A;
+
+        X = A;
+        X -= 2;
+        if((X & 128) == 0)
+            do //while No. 2
+            {
+                //pos47810:
+
+                // mem47 is used to index the tables:
+                // 168  pitches[]
+                // 169  frequency1
+                // 170  frequency2
+                // 171  frequency3
+                // 172  amplitude1
+                // 173  amplitude2
+                // 174  amplitude3
+
+                mem40 = mem38;
+
+                if(mem47 == 168) // pitch
+                {
+                    // unlike the other values, the pitches[] interpolates from
+                    // the middle of the current phoneme to the middle of the
+                    // next phoneme
+
+                    unsigned char mem36, mem37;
+                    // half the width of the current phoneme
+                    mem36 = phonemeLengthOutput[mem44] >> 1;
+                    // half the width of the next phoneme
+                    mem37 = phonemeLengthOutput[mem44 + 1] >> 1;
+                    // sum the values
+                    mem40 = mem36 + mem37; // length of both halves
+                    mem37 += mem49; // center of next phoneme
+                    mem36 = mem49 - mem36; // center index of current phoneme
+                    A = Read(
+                        mem47, mem37); // value at center of next phoneme - end interpolation value
+                    //A = mem[address];
+
+                    Y = mem36; // start index of interpolation
+                    mem53 = A - Read(mem47, mem36); // value to center of current phoneme
+                } else {
+                    // value to interpolate to
+                    A = Read(mem47, speedcounter);
+                    // position to start interpolation from
+                    Y = phase3;
+                    // value to interpolate from
+                    mem53 = A - Read(mem47, phase3);
+                }
+
+                //Code47503(mem40);
+                // ML : Code47503 is division with remainder, and mem50 gets the sign
+
+                // calculate change per frame
+                signed char m53 = (signed char)mem53;
+                mem50 = mem53 & 128;
+                unsigned char m53abs = abs(m53);
+                mem51 = m53abs % mem40; //abs((char)m53) % mem40;
+                mem53 = (unsigned char)((signed char)(m53) / mem40);
+
+                // interpolation range
+                X = mem40; // number of frames to interpolate over
+                Y = phase3; // starting frame
+
+                // linearly interpolate values
+
+                mem56 = 0;
+                //47907: CLC
+                //pos47908:
+                while(1) //while No. 3
+                {
+                    A = Read(mem47, Y) + mem53; //carry alway cleared
+
+                    mem48 = A;
+                    Y++;
+                    X--;
+                    if(X == 0) break;
+
+                    mem56 += mem51;
+                    if(mem56 >= mem40) //???
+                    {
+                        mem56 -= mem40; //carry? is set
+                        //if ((mem56 & 128)==0)
+                        if((mem50 & 128) == 0) {
+                            //47935: BIT 50
+                            //47937: BMI 47943
+                            if(mem48 != 0) mem48++;
+                        } else
+                            mem48--;
+                    }
+                    //pos47945:
+                    Write(mem47, Y, mem48);
+                } //while No. 3
+
+                //pos47952:
+                mem47++;
+                //if (mem47 != 175) goto pos47810;
+            } while(mem47 != 175); //while No. 2
+        //pos47963:
+        mem44++;
+        X = mem44;
+    } //while No. 1
+
+    //goto pos47701;
+    //pos47970:
+
+    // add the length of this phoneme
+    mem48 = mem49 + phonemeLengthOutput[mem44];
+
+    // ASSIGN PITCH CONTOUR
+    //
+    // This subtracts the F1 frequency from the pitch to create a
+    // pitch contour. Without this, the output would be at a single
+    // pitch level (monotone).
+
+    // don't adjust pitch if in sing mode
+    if(!singmode) {
+        // iterate through the buffer
+        for(i = 0; i < 256; i++) {
+            // subtract half the frequency of the formant 1.
+            // this adds variety to the voice
+            pitches[i] -= (frequency1[i] >> 1);
+        }
+    }
+
+    phase1 = 0;
+    phase2 = 0;
+    phase3 = 0;
+    mem49 = 0;
+    speedcounter = 72; //sam standard speed
+
+    // RESCALE AMPLITUDE
+    //
+    // Rescale volume from a linear scale to decibels.
+    //
+
+    //amplitude rescaling
+    for(i = 255; i >= 0; i--) {
+        amplitude1[i] = amplitudeRescale[amplitude1[i]];
+        amplitude2[i] = amplitudeRescale[amplitude2[i]];
+        amplitude3[i] = amplitudeRescale[amplitude3[i]];
+    }
+
+    Y = 0;
+    A = pitches[0];
+    mem44 = A;
+    X = A;
+    mem38 = A - (A >> 2); // 3/4*A ???
+
+    // PROCESS THE FRAMES
+    //
+    // In traditional vocal synthesis, the glottal pulse drives filters, which
+    // are attenuated to the frequencies of the formants.
+    //
+    // SAM generates these formants directly with sin and rectangular waves.
+    // To simulate them being driven by the glottal pulse, the waveforms are
+    // reset at the beginning of each glottal pulse.
+
+    //finally the loop for sound output
+    //pos48078:
+    while(1) {
+        // get the sampled information on the phoneme
+        A = sampledConsonantFlag[Y];
+        mem39 = A;
+
+        // unvoiced sampled phoneme?
+        A = A & 248;
+        if(A != 0) {
+            // render the sample for the phoneme
+            RenderSample(&mem66);
+
+            // skip ahead two in the phoneme buffer
+            Y += 2;
+            mem48 -= 2;
+        } else {
+            // simulate the glottal pulse and formants
+            unsigned char ary[5];
+            unsigned int p1 =
+                phase1 * 256; // Fixed point integers because we need to divide later on
+            unsigned int p2 = phase2 * 256;
+            unsigned int p3 = phase3 * 256;
+            int k;
+            for(k = 0; k < 5; k++) {
+                signed char sp1 = (signed char)sinus[0xff & (p1 >> 8)];
+                signed char sp2 = (signed char)sinus[0xff & (p2 >> 8)];
+                signed char rp3 = (signed char)rectangle[0xff & (p3 >> 8)];
+                signed int sin1 = sp1 * ((unsigned char)amplitude1[Y] & 0x0f);
+                signed int sin2 = sp2 * ((unsigned char)amplitude2[Y] & 0x0f);
+                signed int rect = rp3 * ((unsigned char)amplitude3[Y] & 0x0f);
+                signed int mux = sin1 + sin2 + rect;
+                mux /= 32;
+                mux += 128; // Go from signed to unsigned amplitude
+                ary[k] = mux;
+                p1 += frequency1[Y] * 256 / 4; // Compromise, this becomes a shift and works well
+                p2 += frequency2[Y] * 256 / 4;
+                p3 += frequency3[Y] * 256 / 4;
+            }
+            // output the accumulated value
+            Output8BitAry(0, ary);
+            speedcounter--;
+            if(speedcounter != 0) goto pos48155;
+            Y++; //go to next amplitude
+
+            // decrement the frame count
+            mem48--;
+        }
+
+        // if the frame count is zero, exit the loop
+        if(mem48 == 0) return;
+        speedcounter = speed;
+    pos48155:
+
+        // decrement the remaining length of the glottal pulse
+        mem44--;
+
+        // finished with a glottal pulse?
+        if(mem44 == 0) {
+        pos48159:
+            // fetch the next glottal pulse length
+            A = pitches[Y];
+            mem44 = A;
+            A = A - (A >> 2);
+            mem38 = A;
+
+            // reset the formant wave generators to keep them in
+            // sync with the glottal pulse
+            phase1 = 0;
+            phase2 = 0;
+            phase3 = 0;
+            continue;
+        }
+
+        // decrement the count
+        mem38--;
+
+        // is the count non-zero and the sampled flag is zero?
+        if((mem38 != 0) || (mem39 == 0)) {
+            // reset the phase of the formants to match the pulse
+            phase1 += frequency1[Y];
+            phase2 += frequency2[Y];
+            phase3 += frequency3[Y];
+            continue;
+        }
+
+        // voiced sampled phonemes interleave the sample with the
+        // glottal pulse. The sample flag is non-zero, so render
+        // the sample for the phoneme.
+        RenderSample(&mem66);
+        goto pos48159;
+    } //while
+
+    // The following code is never reached. It's left over from when
+    // the voiced sample code was part of this loop, instead of part
+    // of RenderSample();
+
+    //pos48315:
+    int tempA;
+    phase1 = A ^ 255;
+    Y = mem66;
+    do {
+        //pos48321:
+
+        mem56 = 8;
+        A = Read(mem47, Y);
+
+        //pos48327:
+        do {
+            //48327: ASL A
+            //48328: BCC 48337
+            tempA = A;
+            A = A << 1;
+            if((tempA & 128) != 0) {
+                X = 26;
+                // mem[54296] = X;
+                bufferpos += 150;
+                //
+                //
+                //        buffer[bufferpos / 50] = (X & 15) * 16;
+                //
+                //
+
+            } else {
+                //mem[54296] = 6;
+                X = 6;
+                bufferpos += 150;
+                //
+                //        buffer[bufferpos / 50] = (X & 15) * 16;
+                //
+                //
+            }
+
+            for(X = wait2; X > 0; X--)
+                ; //wait
+            mem56--;
+        } while(mem56 != 0);
+
+        Y++;
+        phase1++;
+
+    } while(phase1 != 0);
+    //  if (phase1 != 0) goto pos48321;
+    A = 1;
+    mem44 = 1;
+    mem66 = Y;
+    Y = mem49;
+    return;
+}
+
+// Create a rising or falling inflection 30 frames prior to
+// index X. A rising inflection is used for questions, and
+// a falling inflection is used for statements.
+
+void STM32SAM::AddInflection(unsigned char mem48, unsigned char phase1) {
+    //pos48372:
+    //  mem48 = 255;
+    //pos48376:
+
+    // store the location of the punctuation
+    mem49 = X;
+    A = X;
+    int Atemp = A;
+
+    // backup 30 frames
+    A = A - 30;
+    // if index is before buffer, point to start of buffer
+    if(Atemp <= 30) A = 0;
+    X = A;
+
+    // FIXME: Explain this fix better, it's not obvious
+    // ML : A =, fixes a problem with invalid pitch with '.'
+    while((A = pitches[X]) == 127) X++;
+
+pos48398:
+    //48398: CLC
+    //48399: ADC 48
+
+    // add the inflection direction
+    A += mem48;
+    phase1 = A;
+
+    // set the inflection
+    pitches[X] = A;
+pos48406:
+
+    // increment the position
+    X++;
+
+    // exit if the punctuation has been reached
+    if(X == mem49) return; //goto pos47615;
+    if(pitches[X] == 255) goto pos48406;
+    A = phase1;
+    goto pos48398;
+}
+
+/*
+    SAM's voice can be altered by changing the frequencies of the
+    mouth formant (F1) and the throat formant (F2). Only the voiced
+    phonemes (5-29 and 48-53) are altered.
+*/
+void STM32SAM::SetMouthThroat() {
+    unsigned char initialFrequency;
+    unsigned char newFrequency = 0;
+    //unsigned char mouth; //mem38880
+    //unsigned char throat; //mem38881
+
+    // mouth formants (F1) 5..29
+    unsigned char mouthFormants5_29[30] = {0,  0,  0,  0,  0,  10, 14, 19, 24, 27,
+                                           23, 21, 16, 20, 14, 18, 14, 18, 18, 16,
+                                           13, 15, 11, 18, 14, 11, 9,  6,  6,  6};
+
+    // throat formants (F2) 5..29
+    unsigned char throatFormants5_29[30] = {255, 255, 255, 255, 255, 84, 73, 67, 63, 40,
+                                            44,  31,  37,  45,  73,  49, 36, 30, 51, 37,
+                                            29,  69,  24,  50,  30,  24, 83, 46, 54, 86};
+
+    // there must be no zeros in this 2 tables
+    // formant 1 frequencies (mouth) 48..53
+    unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13};
+
+    // formant 2 frequencies (throat) 48..53
+    unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34};
+
+    unsigned char pos = 5; //mem39216
+    //pos38942:
+    // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2)
+    while(pos != 30) {
+        // recalculate mouth frequency
+        initialFrequency = mouthFormants5_29[pos];
+        if(initialFrequency != 0) newFrequency = trans(mouth, initialFrequency);
+        freq1data[pos] = newFrequency;
+
+        // recalculate throat frequency
+        initialFrequency = throatFormants5_29[pos];
+        if(initialFrequency != 0) newFrequency = trans(throat, initialFrequency);
+        freq2data[pos] = newFrequency;
+        pos++;
+    }
+
+    //pos39059:
+    // recalculate formant frequencies 48..53
+    pos = 48;
+    Y = 0;
+    while(pos != 54) {
+        // recalculate F1 (mouth formant)
+        initialFrequency = mouthFormants48_53[Y];
+        newFrequency = trans(mouth, initialFrequency);
+        freq1data[pos] = newFrequency;
+
+        // recalculate F2 (throat formant)
+        initialFrequency = throatFormants48_53[Y];
+        newFrequency = trans(throat, initialFrequency);
+        freq2data[pos] = newFrequency;
+        Y++;
+        pos++;
+    }
+}
+
+//return = (mem39212*mem39213) >> 1
+unsigned char STM32SAM::trans(unsigned char mem39212, unsigned char mem39213) {
+    //pos39008:
+    unsigned char carry;
+    int temp;
+    unsigned char mem39214, mem39215;
+    A = 0;
+    mem39215 = 0;
+    mem39214 = 0;
+    X = 8;
+    do {
+        carry = mem39212 & 1;
+        mem39212 = mem39212 >> 1;
+        if(carry != 0) {
+            /*
+                  39018: LSR 39212
+                  39021: BCC 39033
+      */
+            carry = 0;
+            A = mem39215;
+            temp = (int)A + (int)mem39213;
+            A = A + mem39213;
+            if(temp > 255) carry = 1;
+            mem39215 = A;
+        }
+        temp = mem39215 & 1;
+        mem39215 = (mem39215 >> 1) | (carry ? 128 : 0);
+        carry = temp;
+        //39033: ROR 39215
+        X--;
+    } while(X != 0);
+    temp = mem39214 & 128;
+    mem39214 = (mem39214 << 1) | (carry ? 1 : 0);
+    carry = temp;
+    temp = mem39215 & 128;
+    mem39215 = (mem39215 << 1) | (carry ? 1 : 0);
+    carry = temp;
+
+    return mem39215;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           Sam
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+//char input[]={"/HAALAOAO MAYN NAAMAEAE IHSTT SAEBAASTTIHAAN \x9b\x9b\0"};
+//unsigned char input[]={"/HAALAOAO \x9b\0"};
+//unsigned char input[]={"AA \x9b\0"};
+//unsigned char input[] = {"GUH5DEHN TAEG\x9b\0"};
+
+//unsigned char input[]={"AY5 AEM EY TAO4LXKIHNX KAX4MPYUX4TAH. GOW4 AH/HEH3D PAHNK.MEYK MAY8 DEY.\x9b\0"};
+//unsigned char input[]={"/HEH3LOW2, /HAW AH YUX2 TUXDEY. AY /HOH3P YUX AH FIYLIHNX OW4 KEY.\x9b\0"};
+//unsigned char input[]={"/HEY2, DHIHS IH3Z GREY2T. /HAH /HAH /HAH.AYL BIY5 BAEK.\x9b\0"};
+//unsigned char input[]={"/HAH /HAH /HAH \x9b\0"};
+//unsigned char input[]={"/HAH /HAH /HAH.\x9b\0"};
+//unsigned char input[]={".TUW BIY5Y3,, OHR NAA3T - TUW BIY5IYIY., DHAE4T IHZ DHAH KWEH4SCHAHN.\x9b\0"};
+//unsigned char input[]={"/HEY2, DHIHS \x9b\0"};
+
+//unsigned char input[]={" IYIHEHAEAAAHAOOHUHUXERAXIX  \x9b\0"};
+//unsigned char input[]={" RLWWYMNNXBDGJZZHVDH \x9b\0"};
+//unsigned char input[]={" SSHFTHPTKCH/H \x9b\0"};
+
+//unsigned char input[]={" EYAYOYAWOWUW ULUMUNQ YXWXRXLX/XDX\x9b\0"};
+
+void STM32SAM::SetInput(char* _input) {
+    int i, l;
+    l = strlen(_input);
+    if(l > 254) l = 254;
+    for(i = 0; i < l; i++) {
+        input[i] = _input[i];
+    }
+    input[l] = 0;
+}
+
+// 168=pitches
+// 169=frequency1
+// 170=frequency2
+// 171=frequency3
+// 172=amplitude1
+// 173=amplitude2
+// 174=amplitude3
+
+void STM32SAM::Init() {
+    bufferpos = 0;
+    int i;
+    SetMouthThroat();
+
+    bufferpos = 0;
+    // TODO, check for free the memory, 10 seconds of output should be more than enough
+    //buffer = malloc(22050*10);
+
+    // buffer = (char*) calloc(1, sizeof(char));
+
+    /*
+    freq2data = &mem[45136];
+    freq1data = &mem[45056];
+    freq3data = &mem[45216];
+  */
+    //pitches = &mem[43008];
+    /*
+    frequency1 = &mem[43264];
+    frequency2 = &mem[43520];
+    frequency3 = &mem[43776];
+  */
+    /*
+    amplitude1 = &mem[44032];
+    amplitude2 = &mem[44288];
+    amplitude3 = &mem[44544];
+  */
+    //phoneme = &mem[39904];
+    /*
+    ampl1data = &mem[45296];
+    ampl2data = &mem[45376];
+    ampl3data = &mem[45456];
+  */
+
+    for(i = 0; i < 256; i++) {
+        stress[i] = 0;
+        phonemeLength[i] = 0;
+    }
+
+    for(i = 0; i < 60; i++) {
+        phonemeIndexOutput[i] = 0;
+        stressOutput[i] = 0;
+        phonemeLengthOutput[i] = 0;
+    }
+    phonemeindex[255] =
+        255; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs
+}
+
+//int Code39771()
+int STM32SAM::SAMMain() {
+    Init();
+    phonemeindex[255] = 32; //to prevent buffer overflow
+
+    if(!Parser1()) {
+        return 0;
+    }
+
+    Parser2();
+    CopyStress();
+    SetPhonemeLength();
+    AdjustLengths();
+    Code41240();
+    do {
+        A = phonemeindex[X];
+        if(A > 80) {
+            phonemeindex[X] = 255;
+            break; // error: delete all behind it
+        }
+        X++;
+    } while(X != 0);
+
+    //pos39848:
+    InsertBreath();
+
+    //mem[40158] = 255;
+
+    PrepareOutput();
+
+    return 1;
+}
+
+//void Code48547()
+void STM32SAM::PrepareOutput() {
+    A = 0;
+    X = 0;
+    Y = 0;
+
+    //pos48551:
+    while(1) {
+        A = phonemeindex[X];
+        if(A == 255) {
+            A = 255;
+            phonemeIndexOutput[Y] = 255;
+            Render();
+            return;
+        }
+        if(A == 254) {
+            X++;
+            int temp = X;
+            //mem[48546] = X;
+            phonemeIndexOutput[Y] = 255;
+            Render();
+            //X = mem[48546];
+            X = temp;
+            Y = 0;
+            continue;
+        }
+
+        if(A == 0) {
+            X++;
+            continue;
+        }
+
+        phonemeIndexOutput[Y] = A;
+        phonemeLengthOutput[Y] = phonemeLength[X];
+        stressOutput[Y] = stress[X];
+        X++;
+        Y++;
+    }
+}
+
+//void Code41014()
+void STM32SAM::Insert(
+    unsigned char position /*var57*/,
+    unsigned char mem60,
+    unsigned char mem59,
+    unsigned char mem58) {
+    int i;
+    for(i = 253; i >= position; i--) // ML : always keep last safe-guarding 255
+    {
+        phonemeindex[i + 1] = phonemeindex[i];
+        phonemeLength[i + 1] = phonemeLength[i];
+        stress[i + 1] = stress[i];
+    }
+
+    phonemeindex[position] = mem60;
+    phonemeLength[position] = mem59;
+    stress[position] = mem58;
+    return;
+}
+
+//void Code48431()
+void STM32SAM::InsertBreath() {
+    unsigned char mem54;
+    unsigned char mem55;
+    unsigned char index; //variable Y
+    mem54 = 255;
+    X++;
+    mem55 = 0;
+    unsigned char mem66 = 0;
+    while(1) {
+        //pos48440:
+        X = mem66;
+        index = phonemeindex[X];
+        if(index == 255) return;
+        mem55 += phonemeLength[X];
+
+        if(mem55 < 232) {
+            if(index != 254) // ML : Prevents an index out of bounds problem
+            {
+                A = flags2[index] & 1;
+                if(A != 0) {
+                    X++;
+                    mem55 = 0;
+                    Insert(X, 254, mem59, 0);
+                    mem66++;
+                    mem66++;
+                    continue;
+                }
+            }
+            if(index == 0) mem54 = X;
+            mem66++;
+            continue;
+        }
+        X = mem54;
+        phonemeindex[X] = 31; // 'Q*' glottal stop
+        phonemeLength[X] = 4;
+        stress[X] = 0;
+        X++;
+        mem55 = 0;
+        Insert(X, 254, mem59, 0);
+        X++;
+        mem66 = X;
+    }
+}
+
+// Iterates through the phoneme buffer, copying the stress value from
+// the following phoneme under the following circumstance:
+
+//     1. The current phoneme is voiced, excluding plosives and fricatives
+//     2. The following phoneme is voiced, excluding plosives and fricatives, and
+//     3. The following phoneme is stressed
+//
+//  In those cases, the stress value+1 from the following phoneme is copied.
+//
+// For example, the word LOITER is represented as LOY5TER, with as stress
+// of 5 on the diphtong OY. This routine will copy the stress value of 6 (5+1)
+// to the L that precedes it.
+
+//void Code41883()
+void STM32SAM::CopyStress() {
+    // loop thought all the phonemes to be output
+    unsigned char pos = 0; //mem66
+    while(1) {
+        // get the phomene
+        Y = phonemeindex[pos];
+
+        // exit at end of buffer
+        if(Y == 255) return;
+
+        // if CONSONANT_FLAG set, skip - only vowels get stress
+        if((flags[Y] & 64) == 0) {
+            pos++;
+            continue;
+        }
+        // get the next phoneme
+        Y = phonemeindex[pos + 1];
+        if(Y == 255) //prevent buffer overflow
+        {
+            pos++;
+            continue;
+        } else
+            // if the following phoneme is a vowel, skip
+            if((flags[Y] & 128) == 0) {
+                pos++;
+                continue;
+            }
+
+        // get the stress value at the next position
+        Y = stress[pos + 1];
+
+        // if next phoneme is not stressed, skip
+        if(Y == 0) {
+            pos++;
+            continue;
+        }
+
+        // if next phoneme is not a VOWEL OR ER, skip
+        if((Y & 128) != 0) {
+            pos++;
+            continue;
+        }
+
+        // copy stress from prior phoneme to this one
+        stress[pos] = Y + 1;
+
+        // advance pointer
+        pos++;
+    }
+}
+
+// The input[] buffer contains a string of phonemes and stress markers along
+// the lines of:
+//
+//     DHAX KAET IHZ AH5GLIY. <0x9B>
+//
+// The byte 0x9B marks the end of the buffer. Some phonemes are 2 bytes
+// long, such as "DH" and "AX". Others are 1 byte long, such as "T" and "Z".
+// There are also stress markers, such as "5" and ".".
+//
+// The first character of the phonemes are stored in the table signInputTable1[].
+// The second character of the phonemes are stored in the table signInputTable2[].
+// The stress characters are arranged in low to high stress order in stressInputTable[].
+//
+// The following process is used to parse the input[] buffer:
+//
+// Repeat until the <0x9B> character is reached:
+//
+//        First, a search is made for a 2 character match for phonemes that do not
+//        end with the '*' (wildcard) character. On a match, the index of the phoneme
+//        is added to phonemeIndex[] and the buffer position is advanced 2 bytes.
+//
+//        If this fails, a search is made for a 1 character match against all
+//        phoneme names ending with a '*' (wildcard). If this succeeds, the
+//        phoneme is added to phonemeIndex[] and the buffer position is advanced
+//        1 byte.
+//
+//        If this fails, search for a 1 character match in the stressInputTable[].
+//        If this succeeds, the stress value is placed in the last stress[] table
+//        at the same index of the last added phoneme, and the buffer position is
+//        advanced by 1 byte.
+//
+//        If this fails, return a 0.
+//
+// On success:
+//
+//    1. phonemeIndex[] will contain the index of all the phonemes.
+//    2. The last index in phonemeIndex[] will be 255.
+//    3. stress[] will contain the stress value for each phoneme
+
+// input[] holds the string of phonemes, each two bytes wide
+// signInputTable1[] holds the first character of each phoneme
+// signInputTable2[] holds te second character of each phoneme
+// phonemeIndex[] holds the indexes of the phonemes after parsing input[]
+//
+// The parser scans through the input[], finding the names of the phonemes
+// by searching signInputTable1[] and signInputTable2[]. On a match, it
+// copies the index of the phoneme into the phonemeIndexTable[].
+//
+// The character <0x9B> marks the end of text in input[]. When it is reached,
+// the index 255 is placed at the end of the phonemeIndexTable[], and the
+// function returns with a 1 indicating success.
+int STM32SAM::Parser1() {
+    int i;
+    unsigned char sign1;
+    unsigned char sign2;
+    unsigned char position = 0;
+    X = 0;
+    A = 0;
+    Y = 0;
+
+    // CLEAR THE STRESS TABLE
+    for(i = 0; i < 256; i++) stress[i] = 0;
+
+    // THIS CODE MATCHES THE PHONEME LETTERS TO THE TABLE
+    // pos41078:
+    while(1) {
+        // GET THE FIRST CHARACTER FROM THE PHONEME BUFFER
+        sign1 = input[X];
+        // TEST FOR 155 (�) END OF LINE MARKER
+        if(sign1 == 155) {
+            // MARK ENDPOINT AND RETURN
+            phonemeindex[position] = 255; //mark endpoint
+            // REACHED END OF PHONEMES, SO EXIT
+            return 1; //all ok
+        }
+
+        // GET THE NEXT CHARACTER FROM THE BUFFER
+        X++;
+        sign2 = input[X];
+
+        // NOW sign1 = FIRST CHARACTER OF PHONEME, AND sign2 = SECOND CHARACTER OF PHONEME
+
+        // TRY TO MATCH PHONEMES ON TWO TWO-CHARACTER NAME
+        // IGNORE PHONEMES IN TABLE ENDING WITH WILDCARDS
+
+        // SET INDEX TO 0
+        Y = 0;
+    pos41095:
+
+        // GET FIRST CHARACTER AT POSITION Y IN signInputTable
+        // --> should change name to PhonemeNameTable1
+        A = signInputTable1[Y];
+
+        // FIRST CHARACTER MATCHES?
+        if(A == sign1) {
+            // GET THE CHARACTER FROM THE PhonemeSecondLetterTable
+            A = signInputTable2[Y];
+            // NOT A SPECIAL AND MATCHES SECOND CHARACTER?
+            if((A != '*') && (A == sign2)) {
+                // STORE THE INDEX OF THE PHONEME INTO THE phomeneIndexTable
+                phonemeindex[position] = Y;
+
+                // ADVANCE THE POINTER TO THE phonemeIndexTable
+                position++;
+                // ADVANCE THE POINTER TO THE phonemeInputBuffer
+                X++;
+
+                // CONTINUE PARSING
+                continue;
+            }
+        }
+
+        // NO MATCH, TRY TO MATCH ON FIRST CHARACTER TO WILDCARD NAMES (ENDING WITH '*')
+
+        // ADVANCE TO THE NEXT POSITION
+        Y++;
+        // IF NOT END OF TABLE, CONTINUE
+        if(Y != 81) goto pos41095;
+
+        // REACHED END OF TABLE WITHOUT AN EXACT (2 CHARACTER) MATCH.
+        // THIS TIME, SEARCH FOR A 1 CHARACTER MATCH AGAINST THE WILDCARDS
+
+        // RESET THE INDEX TO POINT TO THE START OF THE PHONEME NAME TABLE
+        Y = 0;
+    pos41134:
+        // DOES THE PHONEME IN THE TABLE END WITH '*'?
+        if(signInputTable2[Y] == '*') {
+            // DOES THE FIRST CHARACTER MATCH THE FIRST LETTER OF THE PHONEME
+            if(signInputTable1[Y] == sign1) {
+                // SAVE THE POSITION AND MOVE AHEAD
+                phonemeindex[position] = Y;
+
+                // ADVANCE THE POINTER
+                position++;
+
+                // CONTINUE THROUGH THE LOOP
+                continue;
+            }
+        }
+        Y++;
+        if(Y != 81) goto pos41134; //81 is size of PHONEME NAME table
+
+        // FAILED TO MATCH WITH A WILDCARD. ASSUME THIS IS A STRESS
+        // CHARACTER. SEARCH THROUGH THE STRESS TABLE
+
+        // SET INDEX TO POSITION 8 (END OF STRESS TABLE)
+        Y = 8;
+
+        // WALK BACK THROUGH TABLE LOOKING FOR A MATCH
+        while((sign1 != stressInputTable[Y]) && (Y > 0)) {
+            // DECREMENT INDEX
+            Y--;
+        }
+
+        // REACHED THE END OF THE SEARCH WITHOUT BREAKING OUT OF LOOP?
+        if(Y == 0) {
+            //mem[39444] = X;
+            //41181: JSR 42043 //Error
+            // FAILED TO MATCH ANYTHING, RETURN 0 ON FAILURE
+            return 0;
+        }
+        // SET THE STRESS FOR THE PRIOR PHONEME
+        stress[position - 1] = Y;
+    } //while
+}
+
+//change phonemelength depedendent on stress
+//void Code41203()
+void STM32SAM::SetPhonemeLength() {
+    unsigned char A;
+    int position = 0;
+    while(phonemeindex[position] != 255) {
+        A = stress[position];
+        //41218: BMI 41229
+        if((A == 0) || ((A & 128) != 0)) {
+            phonemeLength[position] = phonemeLengthTable[phonemeindex[position]];
+        } else {
+            phonemeLength[position] = phonemeStressedLengthTable[phonemeindex[position]];
+        }
+        position++;
+    }
+}
+
+void STM32SAM::Code41240() {
+    unsigned char pos = 0;
+
+    while(phonemeindex[pos] != 255) {
+        unsigned char index; //register AC
+        X = pos;
+        index = phonemeindex[pos];
+        if((flags[index] & 2) == 0) {
+            pos++;
+            continue;
+        } else if((flags[index] & 1) == 0) {
+            Insert(pos + 1, index + 1, phonemeLengthTable[index + 1], stress[pos]);
+            Insert(pos + 2, index + 2, phonemeLengthTable[index + 2], stress[pos]);
+            pos += 3;
+            continue;
+        }
+
+        do {
+            X++;
+            A = phonemeindex[X];
+        } while(A == 0);
+
+        if(A != 255) {
+            if((flags[A] & 8) != 0) {
+                pos++;
+                continue;
+            }
+            if((A == 36) || (A == 37)) {
+                pos++; // '/H' '/X'
+                continue;
+            }
+        }
+
+        Insert(pos + 1, index + 1, phonemeLengthTable[index + 1], stress[pos]);
+        Insert(pos + 2, index + 2, phonemeLengthTable[index + 2], stress[pos]);
+        pos += 3;
+    }
+}
+
+// Rewrites the phonemes using the following rules:
+//
+//       <DIPHTONG ENDING WITH WX> -> <DIPHTONG ENDING WITH WX> WX
+//       <DIPHTONG NOT ENDING WITH WX> -> <DIPHTONG NOT ENDING WITH WX> YX
+//       UL -> AX L
+//       UM -> AX M
+//       <STRESSED VOWEL> <SILENCE> <STRESSED VOWEL> -> <STRESSED VOWEL> <SILENCE> Q <VOWEL>
+//       T R -> CH R
+//       D R -> J R
+//       <VOWEL> R -> <VOWEL> RX
+//       <VOWEL> L -> <VOWEL> LX
+//       G S -> G Z
+//       K <VOWEL OR DIPHTONG NOT ENDING WITH IY> -> KX <VOWEL OR DIPHTONG NOT ENDING WITH IY>
+//       G <VOWEL OR DIPHTONG NOT ENDING WITH IY> -> GX <VOWEL OR DIPHTONG NOT ENDING WITH IY>
+//       S P -> S B
+//       S T -> S D
+//       S K -> S G
+//       S KX -> S GX
+//       <ALVEOLAR> UW -> <ALVEOLAR> UX
+//       CH -> CH CH' (CH requires two phonemes to represent it)
+//       J -> J J' (J requires two phonemes to represent it)
+//       <UNSTRESSED VOWEL> T <PAUSE> -> <UNSTRESSED VOWEL> DX <PAUSE>
+//       <UNSTRESSED VOWEL> D <PAUSE>  -> <UNSTRESSED VOWEL> DX <PAUSE>
+
+//void Code41397()
+void STM32SAM::Parser2() {
+    unsigned char pos = 0; //mem66;
+    unsigned char mem58 = 0;
+
+    // Loop through phonemes
+    while(1) {
+        // SET X TO THE CURRENT POSITION
+        X = pos;
+        // GET THE PHONEME AT THE CURRENT POSITION
+        A = phonemeindex[pos];
+
+        // Is phoneme pause?
+        if(A == 0) {
+            // Move ahead to the
+            pos++;
+            continue;
+        }
+
+        // If end of phonemes flag reached, exit routine
+        if(A == 255) return;
+
+        // Copy the current phoneme index to Y
+        Y = A;
+
+        // RULE:
+        //       <DIPHTONG ENDING WITH WX> -> <DIPHTONG ENDING WITH WX> WX
+        //       <DIPHTONG NOT ENDING WITH WX> -> <DIPHTONG NOT ENDING WITH WX> YX
+        // Example: OIL, COW
+
+        // Check for DIPHTONG
+        if((flags[A] & 16) == 0) goto pos41457;
+
+        // Not a diphthong. Get the stress
+        mem58 = stress[pos];
+
+        // End in IY sound?
+        A = flags[Y] & 32;
+
+        // If ends with IY, use YX, else use WX
+        if(A == 0)
+            A = 20;
+        else
+            A = 21; // 'WX' = 20 'YX' = 21
+        //pos41443:
+        // Insert at WX or YX following, copying the stress
+
+        Insert(pos + 1, A, mem59, mem58);
+        X = pos;
+        // Jump to ???
+        goto pos41749;
+
+    pos41457:
+
+        // RULE:
+        //       UL -> AX L
+        // Example: MEDDLE
+
+        // Get phoneme
+        A = phonemeindex[X];
+        // Skip this rule if phoneme is not UL
+        if(A != 78) goto pos41487; // 'UL'
+        A = 24; // 'L'                 //change 'UL' to 'AX L'
+
+    pos41466:
+        // Get current phoneme stress
+        mem58 = stress[X];
+
+        // Change UL to AX
+        phonemeindex[X] = 13; // 'AX'
+        // Perform insert. Note code below may jump up here with different values
+        Insert(X + 1, A, mem59, mem58);
+        pos++;
+        // Move to next phoneme
+        continue;
+
+    pos41487:
+
+        // RULE:
+        //       UM -> AX M
+        // Example: ASTRONOMY
+
+        // Skip rule if phoneme != UM
+        if(A != 79) goto pos41495; // 'UM'
+        // Jump up to branch - replaces current phoneme with AX and continues
+        A = 27; // 'M'  //change 'UM' to  'AX M'
+
+        goto pos41466;
+    pos41495:
+
+        // RULE:
+        //       UN -> AX N
+        // Example: FUNCTION
+
+        // Skip rule if phoneme != UN
+        if(A != 80) goto pos41503; // 'UN'
+
+        // Jump up to branch - replaces current phoneme with AX and continues
+        A = 28; // 'N' //change UN to 'AX N'
+
+        goto pos41466;
+    pos41503:
+
+        // RULE:
+        //       <STRESSED VOWEL> <SILENCE> <STRESSED VOWEL> -> <STRESSED VOWEL> <SILENCE> Q <VOWEL>
+        // EXAMPLE: AWAY EIGHT
+
+        Y = A;
+        // VOWEL set?
+        A = flags[A] & 128;
+
+        // Skip if not a vowel
+        if(A != 0) {
+            // Get the stress
+            A = stress[X];
+
+            // If stressed...
+            if(A != 0) {
+                // Get the following phoneme
+                X++;
+                A = phonemeindex[X];
+                // If following phoneme is a pause
+
+                if(A == 0) {
+                    // Get the phoneme following pause
+                    X++;
+                    Y = phonemeindex[X];
+
+                    // Check for end of buffer flag
+                    if(Y == 255) //buffer overflow
+                        // ??? Not sure about these flags
+                        A = 65 & 128;
+                    else
+                        // And VOWEL flag to current phoneme's flags
+                        A = flags[Y] & 128;
+
+                    // If following phonemes is not a pause
+                    if(A != 0) {
+                        // If the following phoneme is not stressed
+                        A = stress[X];
+                        if(A != 0) {
+                            // 31 = 'Q'
+                            Insert(X, 31, mem59, 0);
+                            pos++;
+                            continue;
+                        }
+                    }
+                }
+            }
+        }
+
+        // RULES FOR PHONEMES BEFORE R
+        //        T R -> CH R
+        // Example: TRACK
+
+        // Get current position and phoneme
+        X = pos;
+        A = phonemeindex[pos];
+        if(A != 23) goto pos41611; // 'R'
+
+        // Look at prior phoneme
+        X--;
+        A = phonemeindex[pos - 1];
+        //pos41567:
+        if(A == 69) // 'T'
+        {
+            phonemeindex[pos - 1] = 42;
+            goto pos41779;
+        }
+
+        // RULES FOR PHONEMES BEFORE R
+        //        D R -> J R
+        // Example: DRY
+
+        // Prior phonemes D?
+        if(A == 57) // 'D'
+        {
+            // Change D to J
+            phonemeindex[pos - 1] = 44;
+
+            goto pos41788;
+        }
+
+        // RULES FOR PHONEMES BEFORE R
+        //        <VOWEL> R -> <VOWEL> RX
+        // Example: ART
+
+        // If vowel flag is set change R to RX
+        A = flags[A] & 128;
+
+        if(A != 0) phonemeindex[pos] = 18; // 'RX'
+
+        // continue to next phoneme
+        pos++;
+        continue;
+
+    pos41611:
+
+        // RULE:
+        //       <VOWEL> L -> <VOWEL> LX
+        // Example: ALL
+
+        // Is phoneme L?
+        if(A == 24) // 'L'
+        {
+            // If prior phoneme does not have VOWEL flag set, move to next phoneme
+            if((flags[phonemeindex[pos - 1]] & 128) == 0) {
+                pos++;
+                continue;
+            }
+            // Prior phoneme has VOWEL flag set, so change L to LX and move to next phoneme
+
+            phonemeindex[X] = 19; // 'LX'
+            pos++;
+            continue;
+        }
+
+        // RULE:
+        //       G S -> G Z
+        //
+        // Can't get to fire -
+        //       1. The G -> GX rule intervenes
+        //       2. Reciter already replaces GS -> GZ
+
+        // Is current phoneme S?
+        if(A == 32) // 'S'
+        {
+            // If prior phoneme is not G, move to next phoneme
+            if(phonemeindex[pos - 1] != 60) {
+                pos++;
+                continue;
+            }
+            // Replace S with Z and move on
+
+            phonemeindex[pos] = 38; // 'Z'
+            pos++;
+            continue;
+        }
+
+        // RULE:
+        //             K <VOWEL OR DIPHTONG NOT ENDING WITH IY> -> KX <VOWEL OR DIPHTONG NOT ENDING WITH IY>
+        // Example: COW
+
+        // Is current phoneme K?
+        if(A == 72) // 'K'
+        {
+            // Get next phoneme
+            Y = phonemeindex[pos + 1];
+            // If at end, replace current phoneme with KX
+            if(Y == 255)
+                phonemeindex[pos] = 75; // ML : prevents an index out of bounds problem
+            else {
+                // VOWELS AND DIPHTONGS ENDING WITH IY SOUND flag set?
+                A = flags[Y] & 32;
+
+                // Replace with KX
+                if(A == 0) phonemeindex[pos] = 75; // 'KX'
+            }
+        } else
+
+            // RULE:
+            //             G <VOWEL OR DIPHTONG NOT ENDING WITH IY> -> GX <VOWEL OR DIPHTONG NOT ENDING WITH IY>
+            // Example: GO
+
+            // Is character a G?
+            if(A == 60) // 'G'
+            {
+                // Get the following character
+                unsigned char index = phonemeindex[pos + 1];
+
+                // At end of buffer?
+                if(index == 255) //prevent buffer overflow
+                {
+                    pos++;
+                    continue;
+                } else
+                    // If diphtong ending with YX, move continue processing next phoneme
+                    if((flags[index] & 32) != 0) {
+                        pos++;
+                        continue;
+                    }
+                // replace G with GX and continue processing next phoneme
+
+                phonemeindex[pos] = 63; // 'GX'
+                pos++;
+                continue;
+            }
+
+        // RULE:
+        //      S P -> S B
+        //      S T -> S D
+        //      S K -> S G
+        //      S KX -> S GX
+        // Examples: SPY, STY, SKY, SCOWL
+
+        Y = phonemeindex[pos];
+        //pos41719:
+        // Replace with softer version?
+        A = flags[Y] & 1;
+        if(A == 0) goto pos41749;
+        A = phonemeindex[pos - 1];
+        if(A != 32) // 'S'
+        {
+            A = Y;
+            goto pos41812;
+        }
+        // Replace with softer version
+
+        phonemeindex[pos] = Y - 12;
+        pos++;
+        continue;
+
+    pos41749:
+
+        // RULE:
+        //      <ALVEOLAR> UW -> <ALVEOLAR> UX
+        //
+        // Example: NEW, DEW, SUE, ZOO, THOO, TOO
+
+        //       UW -> UX
+
+        A = phonemeindex[X];
+        if(A == 53) // 'UW'
+        {
+            // ALVEOLAR flag set?
+            Y = phonemeindex[X - 1];
+            A = flags2[Y] & 4;
+            // If not set, continue processing next phoneme
+            if(A == 0) {
+                pos++;
+                continue;
+            }
+
+            phonemeindex[X] = 16;
+            pos++;
+            continue;
+        }
+    pos41779:
+
+        // RULE:
+        //       CH -> CH CH' (CH requires two phonemes to represent it)
+        // Example: CHEW
+
+        if(A == 42) // 'CH'
+        {
+            //        pos41783:
+
+            Insert(X + 1, A + 1, mem59, stress[X]);
+            pos++;
+            continue;
+        }
+
+    pos41788:
+
+        // RULE:
+        //       J -> J J' (J requires two phonemes to represent it)
+        // Example: JAY
+
+        if(A == 44) // 'J'
+        {
+            Insert(X + 1, A + 1, mem59, stress[X]);
+            pos++;
+            continue;
+        }
+
+        // Jump here to continue
+    pos41812:
+
+        // RULE: Soften T following vowel
+        // NOTE: This rule fails for cases such as "ODD"
+        //       <UNSTRESSED VOWEL> T <PAUSE> -> <UNSTRESSED VOWEL> DX <PAUSE>
+        //       <UNSTRESSED VOWEL> D <PAUSE>  -> <UNSTRESSED VOWEL> DX <PAUSE>
+        // Example: PARTY, TARDY
+
+        // Past this point, only process if phoneme is T or D
+
+        if(A != 69) // 'T'
+            if(A != 57) {
+                pos++; // 'D'
+                continue;
+            }
+        //pos41825:
+
+        // If prior phoneme is not a vowel, continue processing phonemes
+        if((flags[phonemeindex[X - 1]] & 128) == 0) {
+            pos++;
+            continue;
+        }
+
+        // Get next phoneme
+        X++;
+        A = phonemeindex[X];
+        //pos41841
+        // Is the next phoneme a pause?
+        if(A != 0) {
+            // If next phoneme is not a pause, continue processing phonemes
+            if((flags[A] & 128) == 0) {
+                pos++;
+                continue;
+            }
+            // If next phoneme is stressed, continue processing phonemes
+            // FIXME: How does a pause get stressed?
+            if(stress[X] != 0) {
+                pos++;
+                continue;
+            }
+            //pos41856:
+            // Set phonemes to DX
+
+            phonemeindex[pos] = 30; // 'DX'
+        } else {
+            A = phonemeindex[X + 1];
+            if(A == 255) //prevent buffer overflow
+                A = 65 & 128;
+            else
+                // Is next phoneme a vowel or ER?
+                A = flags[A] & 128;
+
+            if(A != 0) phonemeindex[pos] = 30; // 'DX'
+        }
+
+        pos++;
+
+    } // while
+} // parser 2
+
+// Applies various rules that adjust the lengths of phonemes
+//
+//         Lengthen <FRICATIVE> or <VOICED> between <VOWEL> and <PUNCTUATION> by 1.5
+//         <VOWEL> <RX | LX> <CONSONANT> - decrease <VOWEL> length by 1
+//         <VOWEL> <UNVOICED PLOSIVE> - decrease vowel by 1/8th
+//         <VOWEL> <UNVOICED CONSONANT> - increase vowel by 1/2 + 1
+//         <NASAL> <STOP CONSONANT> - set nasal = 5, consonant = 6
+//         <VOICED STOP CONSONANT> {optional silence} <STOP CONSONANT> - shorten both to 1/2 + 1
+//         <LIQUID CONSONANT> <DIPHTONG> - decrease by 2
+
+//void Code48619()
+void STM32SAM::AdjustLengths() {
+    // LENGTHEN VOWELS PRECEDING PUNCTUATION
+    //
+    // Search for punctuation. If found, back up to the first vowel, then
+    // process all phonemes between there and up to (but not including) the punctuation.
+    // If any phoneme is found that is a either a fricative or voiced, the duration is
+    // increased by (length * 1.5) + 1
+
+    // loop index
+    X = 0;
+    unsigned char index;
+
+    // iterate through the phoneme list
+    unsigned char loopIndex = 0;
+    while(1) {
+        // get a phoneme
+        index = phonemeindex[X];
+
+        // exit loop if end on buffer token
+        if(index == 255) break;
+
+        // not punctuation?
+        if((flags2[index] & 1) == 0) {
+            // skip
+            X++;
+            continue;
+        }
+
+        // hold index
+        loopIndex = X;
+
+        // Loop backwards from this point
+    pos48644:
+
+        // back up one phoneme
+        X--;
+
+        // stop once the beginning is reached
+        if(X == 0) break;
+
+        // get the preceding phoneme
+        index = phonemeindex[X];
+
+        if(index != 255) //inserted to prevent access overrun
+            if((flags[index] & 128) == 0) goto pos48644; // if not a vowel, continue looping
+
+        //pos48657:
+        do {
+            // test for vowel
+            index = phonemeindex[X];
+
+            if(index != 255) //inserted to prevent access overrun
+                // test for fricative/unvoiced or not voiced
+                if(((flags2[index] & 32) == 0) || ((flags[index] & 4) != 0)) //nochmal �berpr�fen
+                {
+                    //A = flags[Y] & 4;
+                    //if(A == 0) goto pos48688;
+
+                    // get the phoneme length
+                    A = phonemeLength[X];
+
+                    // change phoneme length to (length * 1.5) + 1
+                    A = (A >> 1) + A + 1;
+
+                    phonemeLength[X] = A;
+                }
+            // keep moving forward
+            X++;
+        } while(X != loopIndex);
+        //  if (X != loopIndex) goto pos48657;
+        X++;
+    } // while
+
+    // Similar to the above routine, but shorten vowels under some circumstances
+
+    // Loop throught all phonemes
+    loopIndex = 0;
+    //pos48697
+
+    while(1) {
+        // get a phoneme
+        X = loopIndex;
+        index = phonemeindex[X];
+
+        // exit routine at end token
+        if(index == 255) return;
+
+        // vowel?
+        A = flags[index] & 128;
+        if(A != 0) {
+            // get next phoneme
+            X++;
+            index = phonemeindex[X];
+
+            // get flags
+            if(index == 255)
+                mem56 = 65; // use if end marker
+            else
+                mem56 = flags[index];
+
+            // not a consonant
+            if((flags[index] & 64) == 0) {
+                // RX or LX?
+                if((index == 18) || (index == 19)) // 'RX' & 'LX'
+                {
+                    // get the next phoneme
+                    X++;
+                    index = phonemeindex[X];
+
+                    // next phoneme a consonant?
+                    if((flags[index] & 64) != 0) {
+                        // RULE: <VOWEL> RX | LX <CONSONANT>
+
+                        // decrease length of vowel by 1 frame
+                        phonemeLength[loopIndex]--;
+                    }
+                    // move ahead
+                    loopIndex++;
+                    continue;
+                }
+                // move ahead
+                loopIndex++;
+                continue;
+            }
+
+            // Got here if not <VOWEL>
+
+            // not voiced
+            if((mem56 & 4) == 0) {
+                // Unvoiced
+                // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX
+
+                // not an unvoiced plosive?
+                if((mem56 & 1) == 0) {
+                    // move ahead
+                    loopIndex++;
+                    continue;
+                }
+
+                // P*, T*, K*, KX
+
+                // RULE: <VOWEL> <UNVOICED PLOSIVE>
+                // <VOWEL> <P*, T*, K*, KX>
+
+                // move back
+                X--;
+
+                // decrease length by 1/8th
+                mem56 = phonemeLength[X] >> 3;
+                phonemeLength[X] -= mem56;
+
+                // move ahead
+                loopIndex++;
+                continue;
+            }
+
+            // RULE: <VOWEL> <VOICED CONSONANT>
+            // <VOWEL> <WH, R*, L*, W*, Y*, M*, N*, NX, DX, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX>
+
+            // decrease length
+            A = phonemeLength[X - 1];
+            phonemeLength[X - 1] = (A >> 2) + A + 1; // 5/4*A + 1
+
+            // move ahead
+            loopIndex++;
+            continue;
+        }
+
+        // WH, R*, L*, W*, Y*, M*, N*, NX, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX
+
+        //pos48821:
+
+        // RULE: <NASAL> <STOP CONSONANT>
+        //       Set punctuation length to 6
+        //       Set stop consonant length to 5
+
+        // nasal?
+        if((flags2[index] & 8) != 0) {
+            // M*, N*, NX,
+
+            // get the next phoneme
+            X++;
+            index = phonemeindex[X];
+
+            // end of buffer?
+            if(index == 255)
+                A = 65 & 2; //prevent buffer overflow
+            else
+                A = flags[index] & 2; // check for stop consonant
+
+            // is next phoneme a stop consonant?
+            if(A != 0)
+
+            // B*, D*, G*, GX, P*, T*, K*, KX
+
+            {
+                // set stop consonant length to 6
+                phonemeLength[X] = 6;
+
+                // set nasal length to 5
+                phonemeLength[X - 1] = 5;
+            }
+            // move to next phoneme
+            loopIndex++;
+            continue;
+        }
+
+        // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX
+
+        // RULE: <VOICED STOP CONSONANT> {optional silence} <STOP CONSONANT>
+        //       Shorten both to (length/2 + 1)
+
+        // (voiced) stop consonant?
+        if((flags[index] & 2) != 0) {
+            // B*, D*, G*, GX
+
+            // move past silence
+            do {
+                // move ahead
+                X++;
+                index = phonemeindex[X];
+            } while(index == 0);
+
+            // check for end of buffer
+            if(index == 255) //buffer overflow
+            {
+                // ignore, overflow code
+                if((65 & 2) == 0) {
+                    loopIndex++;
+                    continue;
+                }
+            } else if((flags[index] & 2) == 0) {
+                // if another stop consonant, move ahead
+                loopIndex++;
+                continue;
+            }
+
+            // RULE: <UNVOICED STOP CONSONANT> {optional silence} <STOP CONSONANT>
+
+            // X gets overwritten, so hold prior X value for debug statement
+            // int debugX = X;
+            // shorten the prior phoneme length to (length/2 + 1)
+            phonemeLength[X] = (phonemeLength[X] >> 1) + 1;
+            X = loopIndex;
+
+            // also shorten this phoneme length to (length/2 +1)
+            phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1;
+
+            // move ahead
+            loopIndex++;
+            continue;
+        }
+
+        // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **,
+
+        // RULE: <VOICED NON-VOWEL> <DIPHTONG>
+        //       Decrease <DIPHTONG> by 2
+
+        // liquic consonant?
+        if((flags2[index] & 16) != 0) {
+            // R*, L*, W*, Y*
+
+            // get the prior phoneme
+            index = phonemeindex[X - 1];
+
+            // prior phoneme a stop consonant>
+            if((flags[index] & 2) != 0) {
+                // Rule: <LIQUID CONSONANT> <DIPHTONG>
+
+                // decrease the phoneme length by 2 frames (20 ms)
+                phonemeLength[X] -= 2;
+            }
+        }
+
+        // move to next phoneme
+        loopIndex++;
+        continue;
+    }
+    //            goto pos48701;
+}
+
+// -------------------------------------------------------------------------
+// ML : Code47503 is division with remainder, and mem50 gets the sign
+void STM32SAM::Code47503(unsigned char mem52) {
+    Y = 0;
+    if((mem53 & 128) != 0) {
+        mem53 = -mem53;
+        Y = 128;
+    }
+    mem50 = Y;
+    A = 0;
+    for(X = 8; X > 0; X--) {
+        int temp = mem53;
+        mem53 = mem53 << 1;
+        A = A << 1;
+        if(temp >= 128) A++;
+        if(A >= mem52) {
+            A = A - mem52;
+            mem53++;
+        }
+    }
+
+    mem51 = A;
+    if((mem50 & 128) != 0) mem53 = -mem53;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           Reciter
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::Code37055(unsigned char mem59) {
+    X = mem59;
+    X--;
+    A = inputtemp[X];
+    Y = A;
+    A = tab36376[Y];
+    return;
+}
+
+void STM32SAM::Code37066(unsigned char mem58) {
+    X = mem58;
+    X++;
+    A = inputtemp[X];
+    Y = A;
+    A = tab36376[Y];
+}
+
+unsigned char STM32SAM::GetRuleByte(unsigned short mem62, unsigned char Y) {
+    unsigned int address = mem62;
+
+    if(mem62 >= 37541) {
+        address -= 37541;
+        return rules2[address + Y];
+    }
+    address -= 32000;
+    return rules[address + Y];
+}
+
+int STM32SAM::TextToPhonemes(unsigned char* input) // Code36484
+{
+    //unsigned char *tab39445 = &mem[39445];   //input and output
+    //unsigned char mem29;
+    unsigned char mem56; //output position for phonemes
+    unsigned char mem57;
+    unsigned char mem58;
+    unsigned char mem59;
+    unsigned char mem60;
+    unsigned char mem61;
+    unsigned short mem62; // memory position of current rule
+
+    unsigned char mem64; // position of '=' or current character
+    unsigned char mem65; // position of ')'
+    unsigned char mem66; // position of '('
+    unsigned char mem36653;
+
+    inputtemp[0] = 32;
+
+    // secure copy of input
+    // because input will be overwritten by phonemes
+    X = 1;
+    Y = 0;
+    do {
+        //pos36499:
+        A = input[Y] & 127;
+        if(A >= 112)
+            A = A & 95;
+        else if(A >= 96)
+            A = A & 79;
+
+        inputtemp[X] = A;
+        X++;
+        Y++;
+    } while(Y != 255);
+
+    X = 255;
+    inputtemp[X] = 27;
+    mem61 = 255;
+
+pos36550:
+    A = 255;
+    mem56 = 255;
+
+pos36554:
+    while(1) {
+        mem61++;
+        X = mem61;
+        A = inputtemp[X];
+        mem64 = A;
+        if(A == '[') {
+            mem56++;
+            X = mem56;
+            A = 155;
+            input[X] = 155;
+            //goto pos36542;
+            //          Code39771();    //Code39777();
+            return 1;
+        }
+
+        //pos36579:
+        if(A != '.') break;
+        X++;
+        Y = inputtemp[X];
+        A = tab36376[Y] & 1;
+        if(A != 0) break;
+        mem56++;
+        X = mem56;
+        A = '.';
+        input[X] = '.';
+    } //while
+
+    //pos36607:
+    A = mem64;
+    Y = A;
+    A = tab36376[A];
+    mem57 = A;
+    if((A & 2) != 0) {
+        mem62 = 37541;
+        goto pos36700;
+    }
+
+    //pos36630:
+    A = mem57;
+    if(A != 0) goto pos36677;
+    A = 32;
+    inputtemp[X] = ' ';
+    mem56++;
+    X = mem56;
+    if(X > 120) goto pos36654;
+    input[X] = A;
+    goto pos36554;
+
+    // -----
+
+    //36653 is unknown. Contains position
+
+pos36654:
+    input[X] = 155;
+    A = mem61;
+    mem36653 = A;
+    //  mem29 = A; // not used
+    //  Code36538(); das ist eigentlich
+    return 1;
+    //Code39771();
+    //go on if there is more input ???
+    mem61 = mem36653;
+    goto pos36550;
+
+pos36677:
+    A = mem57 & 128;
+    if(A == 0) {
+        //36683: BRK
+        return 0;
+    }
+
+    // go to the right rules for this character.
+    X = mem64 - 'A';
+    mem62 = tab37489[X] | (tab37515[X] << 8);
+
+    // -------------------------------------
+    // go to next rule
+    // -------------------------------------
+
+pos36700:
+
+    // find next rule
+    Y = 0;
+    do {
+        mem62 += 1;
+        A = GetRuleByte(mem62, Y);
+    } while((A & 128) == 0);
+    Y++;
+
+    //pos36720:
+    // find '('
+    while(1) {
+        A = GetRuleByte(mem62, Y);
+        if(A == '(') break;
+        Y++;
+    }
+    mem66 = Y;
+
+    //pos36732:
+    // find ')'
+    do {
+        Y++;
+        A = GetRuleByte(mem62, Y);
+    } while(A != ')');
+    mem65 = Y;
+
+    //pos36741:
+    // find '='
+    do {
+        Y++;
+        A = GetRuleByte(mem62, Y);
+        A = A & 127;
+    } while(A != '=');
+    mem64 = Y;
+
+    X = mem61;
+    mem60 = X;
+
+    // compare the string within the bracket
+    Y = mem66;
+    Y++;
+    //pos36759:
+    while(1) {
+        mem57 = inputtemp[X];
+        A = GetRuleByte(mem62, Y);
+        if(A != mem57) goto pos36700;
+        Y++;
+        if(Y == mem65) break;
+        X++;
+        mem60 = X;
+    }
+
+    // the string in the bracket is correct
+
+    //pos36787:
+    A = mem61;
+    mem59 = mem61;
+
+pos36791:
+    while(1) {
+        mem66--;
+        Y = mem66;
+        A = GetRuleByte(mem62, Y);
+        mem57 = A;
+        //36800: BPL 36805
+        if((A & 128) != 0) goto pos37180;
+        X = A & 127;
+        A = tab36376[X] & 128;
+        if(A == 0) break;
+        X = mem59 - 1;
+        A = inputtemp[X];
+        if(A != mem57) goto pos36700;
+        mem59 = X;
+    }
+
+    //pos36833:
+    A = mem57;
+    if(A == ' ') goto pos36895;
+    if(A == '#') goto pos36910;
+    if(A == '.') goto pos36920;
+    if(A == '&') goto pos36935;
+    if(A == '@') goto pos36967;
+    if(A == '^') goto pos37004;
+    if(A == '+') goto pos37019;
+    if(A == ':') goto pos37040;
+    //  Code42041();    //Error
+    //36894: BRK
+    return 0;
+
+    // --------------
+
+pos36895:
+    Code37055(mem59);
+    A = A & 128;
+    if(A != 0) goto pos36700;
+pos36905:
+    mem59 = X;
+    goto pos36791;
+
+    // --------------
+
+pos36910:
+    Code37055(mem59);
+    A = A & 64;
+    if(A != 0) goto pos36905;
+    goto pos36700;
+
+    // --------------
+
+pos36920:
+    Code37055(mem59);
+    A = A & 8;
+    if(A == 0) goto pos36700;
+pos36930:
+    mem59 = X;
+    goto pos36791;
+
+    // --------------
+
+pos36935:
+    Code37055(mem59);
+    A = A & 16;
+    if(A != 0) goto pos36930;
+    A = inputtemp[X];
+    if(A != 72) goto pos36700;
+    X--;
+    A = inputtemp[X];
+    if((A == 67) || (A == 83)) goto pos36930;
+    goto pos36700;
+
+    // --------------
+
+pos36967:
+    Code37055(mem59);
+    A = A & 4;
+    if(A != 0) goto pos36930;
+    A = inputtemp[X];
+    if(A != 72) goto pos36700;
+    if((A != 84) && (A != 67) && (A != 83)) goto pos36700;
+    mem59 = X;
+    goto pos36791;
+
+    // --------------
+
+pos37004:
+    Code37055(mem59);
+    A = A & 32;
+    if(A == 0) goto pos36700;
+
+pos37014:
+    mem59 = X;
+    goto pos36791;
+
+    // --------------
+
+pos37019:
+    X = mem59;
+    X--;
+    A = inputtemp[X];
+    if((A == 'E') || (A == 'I') || (A == 'Y')) goto pos37014;
+    goto pos36700;
+    // --------------
+
+pos37040:
+    Code37055(mem59);
+    A = A & 32;
+    if(A == 0) goto pos36791;
+    mem59 = X;
+    goto pos37040;
+
+    //---------------------------------------
+
+pos37077:
+    X = mem58 + 1;
+    A = inputtemp[X];
+    if(A != 'E') goto pos37157;
+    X++;
+    Y = inputtemp[X];
+    X--;
+    A = tab36376[Y] & 128;
+    if(A == 0) goto pos37108;
+    X++;
+    A = inputtemp[X];
+    if(A != 'R') goto pos37113;
+pos37108:
+    mem58 = X;
+    goto pos37184;
+pos37113:
+    if((A == 83) || (A == 68)) goto pos37108; // 'S' 'D'
+    if(A != 76) goto pos37135; // 'L'
+    X++;
+    A = inputtemp[X];
+    if(A != 89) goto pos36700;
+    goto pos37108;
+
+pos37135:
+    if(A != 70) goto pos36700;
+    X++;
+    A = inputtemp[X];
+    if(A != 85) goto pos36700;
+    X++;
+    A = inputtemp[X];
+    if(A == 76) goto pos37108;
+    goto pos36700;
+
+pos37157:
+    if(A != 73) goto pos36700;
+    X++;
+    A = inputtemp[X];
+    if(A != 78) goto pos36700;
+    X++;
+    A = inputtemp[X];
+    if(A == 71) goto pos37108;
+    //pos37177:
+    goto pos36700;
+
+    // -----------------------------------------
+
+pos37180:
+
+    A = mem60;
+    mem58 = A;
+
+pos37184:
+    Y = mem65 + 1;
+
+    //37187: CPY 64
+    //  if(? != 0) goto pos37194;
+    if(Y == mem64) goto pos37455;
+    mem65 = Y;
+    //37196: LDA (62),y
+    A = GetRuleByte(mem62, Y);
+    mem57 = A;
+    X = A;
+    A = tab36376[X] & 128;
+    if(A == 0) goto pos37226;
+    X = mem58 + 1;
+    A = inputtemp[X];
+    if(A != mem57) goto pos36700;
+    mem58 = X;
+    goto pos37184;
+pos37226:
+    A = mem57;
+    if(A == 32) goto pos37295; // ' '
+    if(A == 35) goto pos37310; // '#'
+    if(A == 46) goto pos37320; // '.'
+    if(A == 38) goto pos37335; // '&'
+    if(A == 64) goto pos37367; // ''
+    if(A == 94) goto pos37404; // ''
+    if(A == 43) goto pos37419; // '+'
+    if(A == 58) goto pos37440; // ':'
+    if(A == 37) goto pos37077; // '%'
+    //pos37291:
+    //  Code42041(); //Error
+    //37294: BRK
+    return 0;
+
+    // --------------
+pos37295:
+    Code37066(mem58);
+    A = A & 128;
+    if(A != 0) goto pos36700;
+pos37305:
+    mem58 = X;
+    goto pos37184;
+
+    // --------------
+
+pos37310:
+    Code37066(mem58);
+    A = A & 64;
+    if(A != 0) goto pos37305;
+    goto pos36700;
+
+    // --------------
+
+pos37320:
+    Code37066(mem58);
+    A = A & 8;
+    if(A == 0) goto pos36700;
+
+pos37330:
+    mem58 = X;
+    goto pos37184;
+
+    // --------------
+
+pos37335:
+    Code37066(mem58);
+    A = A & 16;
+    if(A != 0) goto pos37330;
+    A = inputtemp[X];
+    if(A != 72) goto pos36700;
+    X++;
+    A = inputtemp[X];
+    if((A == 67) || (A == 83)) goto pos37330;
+    goto pos36700;
+
+    // --------------
+
+pos37367:
+    Code37066(mem58);
+    A = A & 4;
+    if(A != 0) goto pos37330;
+    A = inputtemp[X];
+    if(A != 72) goto pos36700;
+    if((A != 84) && (A != 67) && (A != 83)) goto pos36700;
+    mem58 = X;
+    goto pos37184;
+
+    // --------------
+
+pos37404:
+    Code37066(mem58);
+    A = A & 32;
+    if(A == 0) goto pos36700;
+pos37414:
+    mem58 = X;
+    goto pos37184;
+
+    // --------------
+
+pos37419:
+    X = mem58;
+    X++;
+    A = inputtemp[X];
+    if((A == 69) || (A == 73) || (A == 89)) goto pos37414;
+    goto pos36700;
+
+    // ----------------------
+
+pos37440:
+
+    Code37066(mem58);
+    A = A & 32;
+    if(A == 0) goto pos37184;
+    mem58 = X;
+    goto pos37440;
+pos37455:
+    Y = mem64;
+    mem61 = mem60;
+
+pos37461:
+    //37461: LDA (62),y
+    A = GetRuleByte(mem62, Y);
+    mem57 = A;
+    A = A & 127;
+    if(A != '=') {
+        mem56++;
+        X = mem56;
+        input[X] = A;
+    }
+
+    //37478: BIT 57
+    //37480: BPL 37485  //not negative flag
+    if((mem57 & 128) == 0) goto pos37485; //???
+    goto pos36554;
+pos37485:
+    Y++;
+    goto pos37461;
+}
+
+// Constructor
+
+STM32SAM::STM32SAM(uint32_t STM32SAM_SPEED /* = 5 */) {
+    STM32SAM_SPEED = STM32SAM_SPEED & 0x1f; // limit it from 0 to 31
+
+    _STM32SAM_SPEED = STM32SAM_SPEED;
+
+    // set default voice
+
+    speed = 72;
+    pitch = 64;
+    mouth = 128;
+    throat = 128;
+
+    phonetic = 0;
+    singmode = 0;
+
+    wait1 = 7;
+    wait2 = 6;
+
+    mem59 = 0;
+
+    oldtimetableindex = 0;
+}
+
+STM32SAM::STM32SAM() {
+    _STM32SAM_SPEED = 7;
+
+    // set default voice
+
+    speed = 72;
+    pitch = 64;
+    mouth = 128;
+    throat = 128;
+
+    phonetic = 0;
+    singmode = 0;
+
+    wait1 = 7;
+    wait2 = 6;
+
+    mem59 = 0;
+
+    oldtimetableindex = 0;
+}
+
+/*
+  STM32SAM::~STM32SAM() {
+  {
+  // TODO: end();
+  }
+*/
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM sam  (variable string,  phonetic, sing, pitch, speed, mouth, throat)
+//           STM32SAM say (sing off, phonetic off) (const string)
+//           STM32SAM say (sing off, phonetic off) (variable string)
+//           STM32SAM sing (sing on, phonetic off) (const string)
+//           STM32SAM sing (sing on, phonetic off) (variable string)
+//           STM32SAM sayPhonetic (sing off, phonetic on) (const string)
+//           STM32SAM sayPhonetic (sing off, phonetic on) (variable string)
+//           STM32SAM singPhonetic (sing on, phonetic on) (const string)
+//           STM32SAM singPhonetic (sing on, phonetic on) (variable string)
+//           STM32SAM voice (pitch, speed, mouth, throat)
+//           STM32SAM setPitch (pitch)
+//           STM32SAM setSpeed (speed)
+//           STM32SAM setMouth (mouth)
+//           STM32SAM setThroat (throat)
+//
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM sam  (const string,  phonetic, sing, pitch, speed, mouth, throat)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+char to_upper_case(char c) {
+    if(c >= 'a' && c <= 'z') {
+        return c - 'a' + 'A';
+    }
+    return c;
+}
+
+void STM32SAM::sam(
+    const char* argv,
+    unsigned char _phonetic,
+    unsigned char _singmode,
+    unsigned char _pitch,
+    unsigned char _speed,
+    unsigned char _mouth,
+    unsigned char _throat) {
+    phonetic = _phonetic;
+    singmode = _singmode;
+    pitch = _pitch;
+    speed = _speed;
+    mouth = _mouth;
+    throat = _throat;
+
+    int i;
+
+    for(i = 0; i < 256; i++) {
+        input[i] = argv[i];
+    }
+
+    for(i = 0; input[i] != 0; i++) {
+        if(i != 0) {
+            input[i] = to_upper_case((int)argv[i]);
+        }
+    }
+
+    if(!phonetic) {
+        strncat(input, "[", 256);
+        if(!TextToPhonemes((unsigned char*)input)) {
+            // PrintUsage();
+            return;
+        }
+
+    } else {
+        strncat(input, "\x9b", 256);
+    }
+
+    SetInput(input);
+
+    if(!SAMMain()) {
+        return;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM sam  (variable string,  phonetic, sing, pitch, speed, mouth, throat)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::sam(
+    char* argv,
+    unsigned char _phonetic,
+    unsigned char _singmode,
+    unsigned char _pitch,
+    unsigned char _speed,
+    unsigned char _mouth,
+    unsigned char _throat) {
+    phonetic = _phonetic;
+    singmode = _singmode;
+    pitch = _pitch;
+    speed = _speed;
+    mouth = _mouth;
+    throat = _throat;
+
+    int i;
+
+    for(i = 0; i < 256; i++) {
+        input[i] = argv[i];
+    }
+
+    for(i = 0; input[i] != 0; i++) {
+        if(i != 0) {
+            input[i] = to_upper_case((int)argv[i]);
+        }
+    }
+
+    if(!phonetic) {
+        strncat(input, "[", 256);
+        if(!TextToPhonemes((unsigned char*)input)) {
+            // PrintUsage();
+            return;
+        }
+
+    } else {
+        strncat(input, "\x9b", 256);
+    }
+
+    SetInput(input);
+
+    if(!SAMMain()) {
+        return;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM say(sing off, phonetic off) (const string)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::say(const char* argv) {
+    int i;
+
+    phonetic = 0;
+    singmode = 0;
+
+    char const_input[256];
+
+    for(i = 0; i < 256; i++) {
+        const_input[i] = argv[i];
+    }
+
+    sam(const_input, phonetic, singmode, pitch, speed, mouth, throat);
+}
+
+void STM32SAM::say(char* argv) {
+    int i;
+
+    phonetic = 0;
+    singmode = 0;
+
+    char const_input[256];
+
+    for(i = 0; i < 256; i++) {
+        const_input[i] = argv[i];
+    }
+
+    sam(const_input, phonetic, singmode, pitch, speed, mouth, throat);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM sing (sing on, phonetic off)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::sing(const char* argv) {
+    int i;
+
+    phonetic = 0;
+    singmode = 1;
+
+    char const_input[256];
+
+    for(i = 0; i < 256; i++) {
+        const_input[i] = argv[i];
+    }
+
+    sam(const_input, phonetic, singmode, pitch, speed, mouth, throat);
+}
+
+void STM32SAM::sing(char* argv) {
+    int i;
+
+    phonetic = 0;
+    singmode = 1;
+
+    char const_input[256];
+
+    for(i = 0; i < 256; i++) {
+        const_input[i] = argv[i];
+    }
+
+    sam(const_input, phonetic, singmode, pitch, speed, mouth, throat);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM sayPhonetic (sing off, phonetic on)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::sayPhonetic(const char* argv) {
+    int i;
+
+    phonetic = 1;
+    singmode = 0;
+
+    char const_input[256];
+
+    for(i = 0; i < 256; i++) {
+        const_input[i] = argv[i];
+    }
+
+    sam(const_input, phonetic, singmode, pitch, speed, mouth, throat);
+}
+
+void STM32SAM::sayPhonetic(char* argv) {
+    int i;
+
+    phonetic = 1;
+    singmode = 0;
+
+    char const_input[256];
+
+    for(i = 0; i < 256; i++) {
+        const_input[i] = argv[i];
+    }
+
+    sam(const_input, phonetic, singmode, pitch, speed, mouth, throat);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM singPhonetic (sing on, phonetic on)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::singPhonetic(const char* argv) {
+    int i;
+
+    phonetic = 1;
+    singmode = 1;
+
+    char const_input[256];
+
+    for(i = 0; i < 256; i++) {
+        const_input[i] = argv[i];
+    }
+
+    sam(const_input, phonetic, singmode, pitch, speed, mouth, throat);
+}
+
+void STM32SAM::singPhonetic(char* argv) {
+    int i;
+
+    phonetic = 1;
+    singmode = 0;
+
+    char const_input[256];
+
+    for(i = 0; i < 256; i++) {
+        const_input[i] = argv[i];
+    }
+
+    sam(const_input, phonetic, singmode, pitch, speed, mouth, throat);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM voice (pitch, speed, mouth, throat)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::setVoice(
+    unsigned char _pitch /* = 64 */,
+    unsigned char _speed /* = 72 */,
+    unsigned char _mouth /* = 128 */,
+    unsigned char _throat /* = 128 */) {
+    pitch = _pitch;
+    speed = _speed;
+    mouth = _mouth;
+    throat = _throat;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM setPitch (pitch)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::setPitch(unsigned char _pitch /* = 64 */) {
+    pitch = _pitch;
+}
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM setSpeed (speed)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::setSpeed(unsigned char _speed /* = 72 */) {
+    speed = _speed;
+}
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM setMouth (mouth)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::setMouth(unsigned char _mouth /* = 128 */) {
+    mouth = _mouth;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           STM32SAM setThroat (throat)
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+
+void STM32SAM::setThroat(unsigned char _throat /* = 128 */) {
+    throat = _throat;
+}
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//           Hardware
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+// Hardware specifics, for easier porting to other microcontrollers
+
+//
+// Set PA8 pin as PWM, at 256 timer ticks overflow (8bit resolution)
+
+#include <math.h>
+#include <stm32wbxx_ll_tim.h>
+
+#define FURI_HAL_SPEAKER_TIMER TIM16
+#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1
+
+void STM32SAM::begin(void) {
+#ifdef USE_ROGER_CORE
+
+    pinMode(PA8, PWM); //   audio output pin
+
+    Timer1.setPeriod(
+        4); // Can't set at 256 ticks, only in uS. First nearest uS is 4 (Roger core is only for bluepill, that means 72*4=288 ticks, or 128*4=512 ticks when overclocked. It's ok, just overall volume will be lower, because maximum volume will be 256/288 or 256/512)
+
+#endif
+
+#ifdef USE_STM32duino_CORE
+    pinMode(PA8, OUTPUT);
+
+    PWM->pause();
+    PWM->setMode(1, TIMER_OUTPUT_COMPARE_PWM1, PA8); // TIM1 CH1 (PA8)
+    PWM->setPrescaleFactor(1);
+    PWM->setOverflow(256, TICK_FORMAT); // 256 ticks overflow, no matter the CPU (timer) speed
+    PWM->resume();
+
+#endif
+
+    LL_TIM_InitTypeDef TIM_InitStruct;
+    memset(&TIM_InitStruct, 0, sizeof(LL_TIM_InitTypeDef));
+    TIM_InitStruct.Prescaler = 4;
+    TIM_InitStruct.Autoreload = 255;
+    LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct);
+
+    LL_TIM_OC_InitTypeDef TIM_OC_InitStruct;
+    memset(&TIM_OC_InitStruct, 0, sizeof(LL_TIM_OC_InitTypeDef));
+    TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
+    TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
+    TIM_OC_InitStruct.CompareValue = 127;
+    LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct);
+
+    LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER);
+    LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER);
+} // begin
+
+inline void STM32SAM::SetAUDIO(unsigned char main_volume) {
+#ifdef USE_ROGER_CORE
+    Timer1.setCompare(TIMER_CH1, main_volume);
+#endif
+
+#ifdef USE_STM32duino_CORE
+    PWM->setCaptureCompare(1, main_volume, TICK_COMPARE_FORMAT);
+#endif
+
+    // if(main_volume > 64) {
+    //     LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, 127);
+    // } else {
+    //     LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, main_volume);
+    // }
+
+    float data = main_volume;
+    data /= 255.0f;
+    data -= 0.5f;
+    data *= 4.0f;
+    data = tanhf(data);
+
+    data += 0.5f;
+    data *= 255.0f;
+
+    if(data < 0) {
+        data = 0;
+    } else if(data > 255) {
+        data = 255;
+    }
+
+    LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, data);
+}

+ 96 - 0
sam/stm32_sam.h

@@ -0,0 +1,96 @@
+#include <furi.h>
+
+#ifndef __STM32SAM__
+#define __STM32SAM__
+
+// SAM Text-To-Speech (TTS), ported from https://github.com/s-macke/SAM
+
+class STM32SAM {
+public:
+    STM32SAM(uint32_t STM32SAM_SPEED);
+    STM32SAM();
+
+    void begin(void);
+
+    void
+        sam(const char* argv,
+            unsigned char phonetic,
+            unsigned char singmode,
+            unsigned char pitch,
+            unsigned char speed,
+            unsigned char mouth,
+            unsigned char throat);
+    void
+        sam(char* argv,
+            unsigned char phonetic,
+            unsigned char singmode,
+            unsigned char pitch,
+            unsigned char speed,
+            unsigned char mouth,
+            unsigned char throat);
+
+    void say(const char* argv);
+    void say(char* argv);
+    void sing(const char* argv);
+    void sing(char* argv);
+    void sayPhonetic(const char* argv);
+    void sayPhonetic(char* argv);
+    void singPhonetic(const char* argv);
+    void singPhonetic(char* argv);
+    void setVoice(
+        unsigned char _pitch = 64,
+        unsigned char _speed = 72,
+        unsigned char _mouth = 128,
+        unsigned char _throat = 128);
+    void setPitch(unsigned char _pitch = 64);
+    void setSpeed(unsigned char _speed = 72);
+    void setMouth(unsigned char _mouth = 128);
+    void setThroat(unsigned char _throat = 128);
+
+private:
+    void SetAUDIO(unsigned char main_volume);
+
+    void Output8BitAry(int index, unsigned char ary[5]);
+    void Output8Bit(int index, unsigned char A);
+    unsigned char Read(unsigned char p, unsigned char Y);
+    void Write(unsigned char p, unsigned char Y, unsigned char value);
+    void RenderSample(unsigned char* mem66);
+    void Render();
+    void AddInflection(unsigned char mem48, unsigned char phase1);
+    void SetMouthThroat();
+    unsigned char trans(unsigned char mem39212, unsigned char mem39213);
+    void SetInput(char* _input);
+    void Init();
+    int SAMMain();
+    void PrepareOutput();
+    void Insert(
+        unsigned char position /*var57*/,
+        unsigned char mem60,
+        unsigned char mem59,
+        unsigned char mem58);
+    void InsertBreath();
+    void CopyStress();
+    int Parser1();
+    void SetPhonemeLength();
+    void Code41240();
+    void Parser2();
+    void AdjustLengths();
+    void Code47503(unsigned char mem52);
+    void Code37055(unsigned char mem59);
+    void Code37066(unsigned char mem58);
+    unsigned char GetRuleByte(unsigned short mem62, unsigned char Y);
+    int TextToPhonemes(unsigned char* input); // Code36484
+
+    uint32_t _STM32SAM_SPEED;
+
+    unsigned char speed;
+    unsigned char pitch;
+    unsigned char mouth;
+    unsigned char throat;
+
+    unsigned char phonetic;
+    unsigned char singmode;
+
+}; // STM32SAM class
+
+#endif