<?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 fixed by RFC 6716, the specification for
* the Opus audio codec. 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;
/**
* SpeechPulseTables holds the tables used to read the pulses of a
* stretch of speech.
*
* The sound left after the shape and the pitch have been taken out is
* written as pulses: a block of sixteen samples carries a count of
* pulses, and that count is split in half again and again until each
* sample has its own. This file holds the likelihoods for reading the
* count, for each of those splits, for the extra bits a loud block
* carries, and for which way each pulse points.
*
* @author Chris Pollett
*/
class SpeechPulseTables
{
/**
* 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;
/**
* SAMPLES_IN_BLOCK is how many samples one block of pulses covers.
* A stretch of wide sound at twenty milliseconds holds twenty such
* blocks.
*/
const SAMPLES_IN_BLOCK = 16;
/**
* RATE_LEVELS is how many levels of pulse density a stretch may
* name. The level chooses which set of likelihoods the counts are
* read with.
*/
const RATE_LEVELS = 10;
/**
* MOST_PULSES_IN_BLOCK is the largest count a block may carry
* before the writer starts adding extra bits instead. A count one
* past this says more bits follow.
*/
const MOST_PULSES_IN_BLOCK = 16;
/**
* EXTRA_BIT_CHANCES is how likely each extra bit was, where a block
* carries them. The two answers are equally likely enough that one
* table serves.
*/
const EXTRA_BIT_CHANCES = [120, 0];
/**
* LEAN_CHANCES is how likely each degree of leaning on the sound
* before the stretch was. A stretch that stands on its own writes
* one of three.
*/
const LEAN_CHANCES = [128, 64, 0];
/**
* SEED_CHANCES is how likely each starting number for the noise the
* decoder adds back was. The four are equally likely.
*/
const SEED_CHANCES = [192, 128, 64, 0];
/**
* PULSE_RATE_CHANCES is how likely each level of pulse density was,
* one set of nine for speech made with the voice and one for speech
* made without it.
*/
const PULSE_RATE_CHANCES = [
241, 190, 178, 132, 87, 74, 41, 14, 0, 223, 193, 157, 140, 106,
57, 39, 18, 0];
/**
* PULSES_IN_BLOCK_CHANCES is how likely each count of pulses in a
* block was, one set of eighteen for each level of density.
*/
const PULSES_IN_BLOCK_CHANCES = [
125, 51, 26, 18, 15, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
198, 105, 45, 22, 15, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
213, 162, 116, 83, 59, 43, 32, 24, 18, 15, 12, 9, 7, 6, 5, 3, 2,
0, 239, 187, 116, 59, 28, 16, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
0, 250, 229, 188, 135, 86, 51, 30, 19, 13, 10, 8, 6, 5, 4, 3, 2,
1, 0, 249, 235, 213, 185, 156, 128, 103, 83, 66, 53, 42, 33, 26,
21, 17, 13, 10, 0, 254, 249, 235, 206, 164, 118, 77, 46, 27, 16,
10, 7, 5, 4, 3, 2, 1, 0, 255, 253, 249, 239, 220, 191, 156, 119,
85, 57, 37, 23, 15, 10, 6, 4, 2, 0, 255, 253, 251, 246, 237,
223, 203, 179, 152, 124, 98, 75, 55, 40, 29, 21, 15, 0, 255,
254, 253, 247, 220, 162, 106, 67, 42, 28, 18, 12, 9, 6, 4, 3, 2,
0];
/**
* SPLIT_CHANCES_ONE is how likely each way of splitting a count
* between two neighboring samples was. This is the last split, the
* one that gives each sample its own count.
*/
const SPLIT_CHANCES_ONE = [
128, 0, 214, 42, 0, 235, 128, 21, 0, 244, 184, 72, 11, 0, 248,
214, 128, 42, 7, 0, 248, 225, 170, 80, 25, 5, 0, 251, 236, 198,
126, 54, 18, 3, 0, 250, 238, 211, 159, 82, 35, 15, 5, 0, 250,
231, 203, 168, 128, 88, 53, 25, 6, 0, 252, 238, 216, 185, 148,
108, 71, 40, 18, 4, 0, 253, 243, 225, 199, 166, 128, 90, 57, 31,
13, 3, 0, 254, 246, 233, 212, 183, 147, 109, 73, 44, 23, 10, 2,
0, 255, 250, 240, 223, 198, 166, 128, 90, 58, 33, 16, 6, 1, 0,
255, 251, 244, 231, 210, 181, 146, 110, 75, 46, 25, 12, 5, 1, 0,
255, 253, 248, 238, 221, 196, 164, 128, 92, 60, 35, 18, 8, 3, 1,
0, 255, 253, 249, 242, 229, 208, 180, 146, 110, 76, 48, 27, 14,
7, 3, 1, 0];
/**
* SPLIT_CHANCES_TWO is how likely each way of splitting a count
* between two halves of two samples each was.
*/
const SPLIT_CHANCES_TWO = [
129, 0, 207, 50, 0, 236, 129, 20, 0, 245, 185, 72, 10, 0, 249,
213, 129, 42, 6, 0, 250, 226, 169, 87, 27, 4, 0, 251, 233, 194,
130, 62, 20, 4, 0, 250, 236, 207, 160, 99, 47, 17, 3, 0, 255,
240, 217, 182, 131, 81, 41, 11, 1, 0, 255, 254, 233, 201, 159,
107, 61, 20, 2, 1, 0, 255, 249, 233, 206, 170, 128, 86, 50, 23,
7, 1, 0, 255, 250, 238, 217, 186, 148, 108, 70, 39, 18, 6, 1, 0,
255, 252, 243, 226, 200, 166, 128, 90, 56, 30, 13, 4, 1, 0, 255,
252, 245, 231, 209, 180, 146, 110, 76, 47, 25, 11, 4, 1, 0, 255,
253, 248, 237, 219, 194, 163, 128, 93, 62, 37, 19, 8, 3, 1, 0,
255, 254, 250, 241, 226, 205, 177, 145, 111, 79, 51, 30, 15, 6,
2, 1, 0];
/**
* SPLIT_CHANCES_FOUR is how likely each way of splitting a count
* between two halves of four samples each was.
*/
const SPLIT_CHANCES_FOUR = [
129, 0, 203, 54, 0, 234, 129, 23, 0, 245, 184, 73, 10, 0, 250,
215, 129, 41, 5, 0, 252, 232, 173, 86, 24, 3, 0, 253, 240, 200,
129, 56, 15, 2, 0, 253, 244, 217, 164, 94, 38, 10, 1, 0, 253,
245, 226, 189, 132, 71, 27, 7, 1, 0, 253, 246, 231, 203, 159,
105, 56, 23, 6, 1, 0, 255, 248, 235, 213, 179, 133, 85, 47, 19,
5, 1, 0, 255, 254, 243, 221, 194, 159, 117, 70, 37, 12, 2, 1, 0,
255, 254, 248, 234, 208, 171, 128, 85, 48, 22, 8, 2, 1, 0, 255,
254, 250, 240, 220, 189, 149, 107, 67, 36, 16, 6, 2, 1, 0, 255,
254, 251, 243, 227, 201, 166, 128, 90, 55, 29, 13, 5, 2, 1, 0,
255, 254, 252, 246, 234, 213, 183, 147, 109, 73, 43, 22, 10, 4,
2, 1, 0];
/**
* SPLIT_CHANCES_EIGHT is how likely each way of splitting a count
* between the two halves of a block was. This is the first split.
*/
const SPLIT_CHANCES_EIGHT = [
130, 0, 200, 58, 0, 231, 130, 26, 0, 244, 184, 76, 12, 0, 249,
214, 130, 43, 6, 0, 252, 232, 173, 87, 24, 3, 0, 253, 241, 203,
131, 56, 14, 2, 0, 254, 246, 221, 167, 94, 35, 8, 1, 0, 254,
249, 232, 193, 130, 65, 23, 5, 1, 0, 255, 251, 239, 211, 162,
99, 45, 15, 4, 1, 0, 255, 251, 243, 223, 186, 131, 74, 33, 11,
3, 1, 0, 255, 252, 245, 230, 202, 158, 105, 57, 24, 8, 2, 1, 0,
255, 253, 247, 235, 214, 179, 132, 84, 44, 19, 7, 2, 1, 0, 255,
254, 250, 240, 223, 196, 159, 112, 69, 36, 15, 6, 2, 1, 0, 255,
254, 253, 245, 231, 209, 176, 136, 93, 55, 27, 11, 3, 2, 1, 0,
255, 254, 253, 252, 239, 221, 194, 158, 117, 76, 42, 18, 4, 3,
2, 1, 0];
/**
* SPLIT_TABLE_STARTS says where in a table of splits the
* likelihoods for a given count begin. A count of three is split
* with different likelihoods from a count of ten.
*/
const SPLIT_TABLE_STARTS = [
0, 0, 2, 5, 9, 14, 20, 27, 35, 44, 54, 65, 77, 90, 104, 119, 135];
/**
* PULSE_SIGN_CHANCES is how likely a pulse was to point upward,
* in sets of six by the kind of sound and how loudly the block was
* written.
*/
const PULSE_SIGN_CHANCES = [
254, 49, 67, 77, 82, 93, 99, 198, 11, 18, 24, 31, 36, 45, 255,
46, 66, 78, 87, 94, 104, 208, 14, 21, 32, 42, 51, 66, 255, 94,
104, 109, 112, 115, 118, 248, 53, 69, 80, 88, 95, 102];
}