<?php
/**
* SeekQuarry/Yioop --
* Open Source Pure PHP Search Engine, Crawler, and Indexer
*
* Copyright (C) 2009 - 2026 Chris Pollett chris@pollett.org
*
* LICENSE:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* END LICENSE
*
* The tables in this file are the ones the standard for compressing
* speech fixes. They are taken from the reference implementation
* published by Xiph.Org, Skype Limited and others, which is offered
* under a three clause licence allowing use in other software so long as
* its notice is carried along:
*
* Copyright 2001-2023 Xiph.Org, Skype Limited, Octasic, Jean-Marc
* Valin, Timothy B. Terriberry, CSIRO, Gregory Maxwell, Mark
* Borgerding, Erik de Castro Lopo, Mozilla, Amazon.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the copyright notice,
* this list of conditions and the disclaimer are retained. This
* software is provided by the copyright holders as is, and any
* warranty is disclaimed.
*
* @author Chris Pollett chris@pollett.org
* @license https://www.gnu.org/licenses/ GPL3
* @link https://www.seekquarry.com/
* @copyright 2009 - 2026
* @filesource
*/
namespace seekquarry\yioop\library\av_processing;
/**
* SpeechShapeTables holds the tables that say what shape a stretch of
* speech has: the mouth and throat that made it, written as a set of
* frequencies that rise in order.
*
* A stretch does not carry those frequencies outright. It carries the
* number of a guess from a fixed book, and then a small mending for each
* frequency of that guess. This file holds the book, the likelihoods
* used to read a guess and its mendings, how much each frequency leans
* on the one before it, and the least gap two frequencies may sit apart.
*
* The numbers cover sound kept up to eight thousand cycles a second,
* which is what a browser records speech at, and are written with
* sixteen frequencies to a stretch.
*
* @author Chris Pollett
*/
class SpeechShapeTables
{
/**
* FREQUENCIES_IN_SHAPE is how many frequencies describe the shape of
* one stretch of wide sound.
*/
const FREQUENCIES_IN_SHAPE = 16;
/**
* GUESSES_IN_BOOK is how many guesses the fixed book holds. A
* stretch names one of them and then mends it.
*/
const GUESSES_IN_BOOK = 32;
/**
* WHOLE_BITS is how many bits the likelihoods in this file add up
* to, as in the rest of the speech decoding.
*/
const WHOLE_BITS = 8;
/**
* MENDING_STEPS is how many different mendings may be written for
* one frequency, counting from the largest downward step to the
* largest upward one.
*/
const MENDING_STEPS = 10;
/**
* MENDING_STEP_SIZE is how far one step of mending moves a
* frequency before the weight beside it is taken into account,
* written out of 65536.
*/
const MENDING_STEP_SIZE = 9830;
/**
* MENDING_LEVEL_ADJUST is taken off the size of a mending that is
* not zero, since the writer rounds toward zero and the reader has
* to undo that.
*/
const MENDING_LEVEL_ADJUST = 102;
/**
* MENDING_BEYOND_CHANCES is how likely each further step was where a
* mending sits at either end of its range. The writer may have
* wanted to move further than the range allows, and says how much
* further with these.
*/
const MENDING_BEYOND_CHANCES = [100, 40, 16, 7, 3, 1, 0];
/**
* SHAPE_BLEND_CHANCES is how likely each degree of blending with the
* stretch before was. A stretch of four quarters blends its shape
* with the one before it, and says how much here.
*/
const SHAPE_BLEND_CHANCES = [243, 221, 192, 181, 0];
/**
* SHAPE_FIRST_GUESSES is the book of guesses at the shape of a
* stretch. Each guess holds sixteen frequencies, so the book is read
* sixteen numbers at a time. A frequency is written as a fraction of
* the highest one the sound can hold.
*/
const SHAPE_FIRST_GUESSES = [
7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208,
223, 239, 13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171,
187, 203, 220, 236, 15, 21, 34, 51, 61, 78, 92, 106, 126, 136,
152, 167, 185, 205, 225, 240, 10, 21, 36, 50, 63, 79, 95, 110,
126, 141, 157, 173, 189, 205, 221, 237, 17, 20, 37, 51, 59, 78,
89, 107, 123, 134, 150, 164, 184, 205, 224, 240, 10, 15, 32, 51,
67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236, 8, 21,
37, 51, 65, 79, 98, 113, 126, 138, 155, 168, 179, 192, 209, 218,
12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, 185, 203,
219, 236, 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171,
186, 204, 220, 237, 11, 28, 43, 58, 74, 89, 105, 120, 135, 150,
165, 180, 196, 211, 226, 241, 6, 16, 33, 46, 60, 75, 92, 107,
123, 137, 156, 169, 185, 199, 214, 225, 11, 19, 30, 44, 57, 74,
89, 105, 121, 135, 152, 169, 186, 202, 218, 234, 12, 19, 29, 46,
57, 71, 88, 100, 120, 132, 148, 165, 182, 199, 216, 233, 17, 23,
35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237,
14, 17, 45, 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206,
221, 240, 9, 16, 29, 40, 56, 71, 88, 103, 119, 137, 154, 171,
189, 205, 222, 237, 16, 19, 36, 48, 57, 76, 87, 105, 118, 132,
150, 167, 185, 202, 218, 236, 12, 17, 29, 54, 71, 81, 94, 104,
126, 136, 149, 164, 182, 201, 221, 237, 15, 28, 47, 62, 79, 97,
115, 129, 142, 155, 168, 180, 194, 208, 223, 238, 8, 14, 30, 45,
62, 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239, 17, 30,
49, 62, 79, 92, 107, 119, 132, 145, 160, 174, 190, 204, 220,
235, 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189,
205, 222, 238, 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154,
171, 187, 204, 221, 236, 13, 17, 31, 43, 53, 70, 83, 103, 114,
131, 149, 167, 185, 203, 220, 237, 17, 22, 35, 42, 58, 78, 93,
110, 125, 139, 155, 170, 188, 206, 224, 240, 8, 15, 34, 50, 67,
83, 99, 115, 131, 146, 162, 178, 193, 209, 224, 239, 13, 16, 41,
66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, 241, 17,
25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212,
231, 19, 31, 49, 65, 83, 100, 117, 133, 147, 161, 174, 187, 200,
213, 227, 242, 18, 31, 52, 68, 88, 103, 117, 126, 138, 149, 163,
177, 192, 207, 223, 239, 16, 29, 47, 61, 76, 90, 106, 119, 133,
147, 161, 176, 193, 209, 224, 240, 15, 21, 35, 50, 61, 73, 86,
97, 110, 119, 129, 141, 175, 198, 218, 237];
/**
* SHAPE_GUESS_CHANCES is how likely each guess in the book was, for
* each of the two kinds of speech. The first thirty-two entries are
* for speech made without the voice and the rest for speech made
* with it.
*/
const SHAPE_GUESS_CHANCES = [
225, 204, 201, 184, 183, 175, 158, 154, 153, 135, 119, 115, 113,
110, 109, 99, 98, 95, 79, 68, 52, 50, 48, 45, 43, 32, 31, 27,
18, 10, 3, 0, 255, 251, 235, 230, 212, 201, 196, 182, 167, 166,
163, 151, 138, 124, 110, 104, 90, 78, 76, 70, 69, 57, 45, 34,
24, 21, 11, 6, 5, 4, 3, 0];
/**
* SHAPE_MEND_TABLE_FOR says which set of likelihoods to read a
* mending with, for each frequency of each guess in the book. A
* frequency near a crowded part of the book is mended more finely
* than one standing on its own.
*/
/**
* SHAPE_GUESS_WEIGHTS says how tightly each frequency of each guess
* in the book is held. A frequency the book pins down closely takes
* a smaller mending than one it leaves loose, so a mending is
* divided by the weight beside it.
*/
const SHAPE_GUESS_WEIGHTS = [
3657, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925,
2925, 2925, 2963, 2963, 2925, 2846, 3216, 3085, 2972, 3056,
3056, 3010, 3010, 3010, 2963, 2963, 3010, 2972, 2888, 2846,
2846, 2726, 3920, 4014, 2981, 3207, 3207, 2934, 3056, 2846,
3122, 3244, 2925, 2846, 2620, 2553, 2780, 2925, 3516, 3197,
3010, 3103, 3019, 2888, 2925, 2925, 2925, 2925, 2888, 2888,
2888, 2888, 2888, 2753, 5054, 5054, 2934, 3573, 3385, 3056,
3085, 2793, 3160, 3160, 2972, 2846, 2513, 2540, 2753, 2888,
4428, 4149, 2700, 2753, 2972, 3010, 2925, 2846, 2981, 3019,
2925, 2925, 2925, 2925, 2888, 2726, 3620, 3019, 2972, 3056,
3056, 2873, 2806, 3056, 3216, 3047, 2981, 3291, 3291, 2981,
3310, 2991, 5227, 5014, 2540, 3338, 3526, 3385, 3197, 3094,
3376, 2981, 2700, 2647, 2687, 2793, 2846, 2673, 5081, 5174,
4615, 4428, 2460, 2897, 3047, 3207, 3169, 2687, 2740, 2888,
2846, 2793, 2846, 2700, 3122, 2888, 2963, 2925, 2925, 2925,
2925, 2963, 2963, 2963, 2963, 2925, 2925, 2963, 2963, 2963,
4202, 3207, 2981, 3103, 3010, 2888, 2888, 2925, 2972, 2873,
2916, 3019, 2972, 3010, 3197, 2873, 3760, 3760, 3244, 3103,
2981, 2888, 2925, 2888, 2972, 2934, 2793, 2793, 2846, 2888,
2888, 2660, 3854, 4014, 3207, 3122, 3244, 2934, 3047, 2963,
2963, 3085, 2846, 2793, 2793, 2793, 2793, 2580, 3845, 4080,
3357, 3516, 3094, 2740, 3010, 2934, 3122, 3085, 2846, 2846,
2647, 2647, 2846, 2806, 5147, 4894, 3225, 3845, 3441, 3169,
2897, 3413, 3451, 2700, 2580, 2673, 2740, 2846, 2806, 2753,
4109, 3789, 3291, 3160, 2925, 2888, 2888, 2925, 2793, 2740,
2793, 2740, 2793, 2846, 2888, 2806, 5081, 5054, 3047, 3545,
3244, 3056, 3085, 2944, 3103, 2897, 2740, 2740, 2740, 2846,
2793, 2620, 4309, 4309, 2860, 2527, 3207, 3376, 3376, 3075,
3075, 3376, 3056, 2846, 2647, 2580, 2726, 2753, 3056, 2916,
2806, 2888, 2740, 2687, 2897, 3103, 3150, 3150, 3216, 3169,
3056, 3010, 2963, 2846, 4375, 3882, 2925, 2888, 2846, 2888,
2846, 2846, 2888, 2888, 2888, 2846, 2888, 2925, 2888, 2846,
2981, 2916, 2916, 2981, 2981, 3056, 3122, 3216, 3150, 3056,
3010, 2972, 2972, 2972, 2925, 2740, 4229, 4149, 3310, 3347,
2925, 2963, 2888, 2981, 2981, 2846, 2793, 2740, 2846, 2846,
2846, 2793, 4080, 4014, 3103, 3010, 2925, 2925, 2925, 2888,
2925, 2925, 2846, 2846, 2846, 2793, 2888, 2780, 4615, 4575,
3169, 3441, 3207, 2981, 2897, 3038, 3122, 2740, 2687, 2687,
2687, 2740, 2793, 2700, 4149, 4269, 3789, 3657, 2726, 2780,
2888, 2888, 3010, 2972, 2925, 2846, 2687, 2687, 2793, 2888,
4215, 3554, 2753, 2846, 2846, 2888, 2888, 2888, 2925, 2925,
2888, 2925, 2925, 2925, 2963, 2888, 5174, 4921, 2261, 3432,
3789, 3479, 3347, 2846, 3310, 3479, 3150, 2897, 2460, 2487,
2753, 2925, 3451, 3685, 3122, 3197, 3357, 3047, 3207, 3207,
2981, 3216, 3085, 2925, 2925, 2687, 2540, 2434, 2981, 3010,
2793, 2793, 2740, 2793, 2846, 2972, 3056, 3103, 3150, 3150,
3150, 3103, 3010, 3010, 2944, 2873, 2687, 2726, 2780, 3010,
3432, 3545, 3357, 3244, 3056, 3010, 2963, 2925, 2888, 2846,
3019, 2944, 2897, 3010, 3010, 2972, 3019, 3103, 3056, 3056,
3010, 2888, 2846, 2925, 2925, 2888, 3920, 3967, 3010, 3197,
3357, 3216, 3291, 3291, 3479, 3704, 3441, 2726, 2181, 2460,
2580, 2607];
const SHAPE_MEND_TABLE_FOR = [
0, 0, 0, 0, 0, 0, 0, 1, 100, 102, 102, 68, 68, 36, 34, 96, 164,
107, 158, 185, 180, 185, 139, 102, 64, 66, 36, 34, 34, 0, 1, 32,
208, 139, 141, 191, 152, 185, 155, 104, 96, 171, 104, 166, 102,
102, 102, 132, 1, 0, 0, 0, 0, 16, 16, 0, 80, 109, 78, 107, 185,
139, 103, 101, 208, 212, 141, 139, 173, 153, 123, 103, 36, 0, 0,
0, 0, 0, 0, 1, 48, 0, 0, 0, 0, 0, 0, 32, 68, 135, 123, 119, 119,
103, 69, 98, 68, 103, 120, 118, 118, 102, 71, 98, 134, 136, 157,
184, 182, 153, 139, 134, 208, 168, 248, 75, 189, 143, 121, 107,
32, 49, 34, 34, 34, 0, 17, 2, 210, 235, 139, 123, 185, 137, 105,
134, 98, 135, 104, 182, 100, 183, 171, 134, 100, 70, 68, 70, 66,
66, 34, 131, 64, 166, 102, 68, 36, 2, 1, 0, 134, 166, 102, 68,
34, 34, 66, 132, 212, 246, 158, 139, 107, 107, 87, 102, 100,
219, 125, 122, 137, 118, 103, 132, 114, 135, 137, 105, 171, 106,
50, 34, 164, 214, 141, 143, 185, 151, 121, 103, 192, 34, 0, 0,
0, 0, 0, 1, 208, 109, 74, 187, 134, 249, 159, 137, 102, 110,
154, 118, 87, 101, 119, 101, 0, 2, 0, 36, 36, 66, 68, 35, 96,
164, 102, 100, 36, 0, 2, 33, 167, 138, 174, 102, 100, 84, 2, 2,
100, 107, 120, 119, 36, 197, 24, 0];
/**
* SHAPE_MEND_CHANCES is how likely each mending was, in sets of
* nine, one set for each degree of fineness.
*/
const SHAPE_MEND_CHANCES = [
255, 254, 253, 244, 12, 3, 2, 1, 0, 255, 254, 252, 224, 38, 3,
2, 1, 0, 255, 254, 251, 209, 57, 4, 2, 1, 0, 255, 254, 244, 195,
69, 4, 2, 1, 0, 255, 251, 232, 184, 84, 7, 2, 1, 0, 255, 254,
240, 186, 86, 14, 2, 1, 0, 255, 254, 239, 178, 91, 30, 5, 1, 0,
255, 248, 227, 177, 100, 19, 2, 1, 0];
/**
* SHAPE_LEAN_ON_NEIGHBOUR is how much of a frequency's mending is
* carried into the next one, for each of the two kinds of speech.
* Neighboring frequencies move together, so a mending is worth
* writing once and leaning on.
*/
const SHAPE_LEAN_ON_NEIGHBOUR = [
175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198,
192, 182, 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142,
160, 142, 155];
/**
* SHAPE_LEAST_GAP is the smallest gap allowed between one frequency
* and the next, with the first entry the gap from zero and the last
* the gap to the top. Frequencies that crossed would describe a
* shape no mouth can make.
*/
/**
* COSINE_TABLE holds twice the cosine of each of a hundred and
* twenty-nine evenly spaced angles, written out of 4096. Turning a
* frequency into a filter term needs that cosine, and reading it
* from a table with a straight line drawn between two entries is
* what every decoder does, so the answers agree to the last digit.
*/
const COSINE_TABLE = [
8192, 8190, 8182, 8170, 8152, 8130, 8104, 8072, 8034, 7994,
7946, 7896, 7840, 7778, 7714, 7644, 7568, 7490, 7406, 7318,
7226, 7128, 7026, 6922, 6812, 6698, 6580, 6458, 6332, 6204,
6070, 5934, 5792, 5648, 5502, 5352, 5198, 5040, 4880, 4718,
4552, 4382, 4212, 4038, 3862, 3684, 3502, 3320, 3136, 2948,
2760, 2570, 2378, 2186, 1990, 1794, 1598, 1400, 1202, 1002, 802,
602, 402, 202, 0, -202, -402, -602, -802, -1002, -1202, -1400,
-1598, -1794, -1990, -2186, -2378, -2570, -2760, -2948, -3136,
-3320, -3502, -3684, -3862, -4038, -4212, -4382, -4552, -4718,
-4880, -5040, -5198, -5352, -5502, -5648, -5792, -5934, -6070,
-6204, -6332, -6458, -6580, -6698, -6812, -6922, -7026, -7128,
-7226, -7318, -7406, -7490, -7568, -7644, -7714, -7778, -7840,
-7896, -7946, -7994, -8034, -8072, -8104, -8130, -8152, -8170,
-8182, -8190, -8192];
const SHAPE_LEAST_GAP = [
100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347];
}