/* -*- C++ -*- */ /* * Copyright 2008-2009 Steve Glass * * This file is part of OP25. * * OP25 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, or(at your option) * any later version. * * OP25 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 OP25; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Boston, MA * 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include "software_imbe_decoder.h" static const int BMTn[3600] = { 3, 3, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, 8, 9, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 3, 1, 1, 1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 8, 3, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, 8, 9, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 1, 1, 1, 1, 2, 2, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 8, 3, 4, 5, 8, 3, 4, 5, 6, 7, 8, 9, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 8, 3, 4, 5, 6, 7, 8, 9, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 1, 1, 1, 1, 2, 2, 6, 7, 8, 9, 10, 11, 12, 13, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 3, 4, 5, 8, 9, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 2, 2, 10, 11, 12, 13, 14, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 8, 9, 3, 4, 5, 6, 7, 8, 9, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 1, 1, 1, 1, 2, 2, 13, 14, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 3, 9, 3, 4, 5, 6, 8, 9, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 1, 1, 1, 1, 2, 2, 16, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 4, 5, 8, 9, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 4, 1, 1, 1, 1, 1, 1, 2, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 3, 4, 3, 4, 5, 6, 7, 8, 9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 3, 4, 5, 6, 1, 1, 1, 1, 1, 1, 2, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 3, 3, 4, 5, 6, 7, 8, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 4, 5, 6, 7, 8, 1, 1, 1, 1, 1, 1, 2, 2, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 3, 3, 4, 5, 8, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 3, 4, 5, 6, 7, 8, 9, 10, 1, 1, 1, 1, 1, 1, 1, 2, 2, 11, 12, 13, 14, 15, 16, 17, 18, 19, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 3, 3, 4, 5, 8, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 19, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 1, 1, 1, 1, 1, 1, 2, 2, 12, 13, 14, 15, 16, 17, 19, 20, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 3, 4, 5, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 20, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 2, 2, 14, 15, 16, 17, 18, 20, 21, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 3, 4, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 18, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 17, 18, 19, 21, 22, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 3, 3, 4, 5, 6, 7, 8, 10, 11, 13, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 19, 20, 22, 23, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 3, 3, 4, 5, 6, 7, 8, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 21, 23, 24, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 3, 3, 4, 5, 6, 8, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 23, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 3, 3, 4, 5, 8, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 3, 3, 4, 5, 8, 11, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 17, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 25, 26, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 3, 4, 5, 8, 11, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 18, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 23, 26, 3, 4, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 3, 4, 5, 11, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 19, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 23, 27, 3, 4, 5, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 3, 4, 5, 3, 4, 5, 6, 7, 8, 9, 12, 13, 16, 20, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 24, 28, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 4, 3, 4, 5, 6, 7, 8, 9, 12, 13, 16, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 24, 28, 3, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 3, 4, 3, 4, 5, 6, 7, 8, 9, 12, 13, 16, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 24, 29, 3, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 3, 3, 4, 5, 6, 7, 8, 9, 12, 13, 16, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 25, 30, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 3, 3, 4, 5, 6, 7, 8, 12, 16, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 26, 31, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 3, 3, 4, 5, 6, 7, 8, 12, 17, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 27, 32, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 3, 3, 4, 5, 6, 7, 8, 13, 18, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 18, 19, 23, 24, 28, 33, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 3, 3, 4, 5, 6, 8, 13, 18, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 23, 28, 33, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 3, 3, 4, 5, 6, 8, 13, 18, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 18, 19, 23, 28, 34, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 3, 3, 4, 5, 6, 8, 13, 18, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 18, 19, 23, 24, 29, 35, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 35, 36, 37, 38, 3, 3, 4, 5, 6, 8, 13, 18, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 18, 19, 24, 25, 30, 36, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 36, 37, 38, 39, 3, 3, 4, 5, 8, 13, 19, 3, 4, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 19, 20, 25, 26, 31, 37, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, 37, 38, 39, 40, 3, 3, 4, 5, 8, 14, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16, 17, 20, 21, 26, 27, 32, 38, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 38, 39, 40, 41, 3, 3, 4, 5, 8, 14, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16, 17, 20, 21, 26, 32, 38, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 38, 39, 40, 41, 42, 3, 3, 4, 5, 8, 14, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 16, 17, 20, 21, 26, 32, 39, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 39, 40, 41, 42, 43, 3, 3, 4, 5, 8, 14, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 16, 20, 21, 26, 27, 33, 40, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 35, 36, 37, 40, 41, 42, 43, 44, 3, 4, 5, 8, 14, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 16, 20, 21, 27, 28, 34, 41, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 3, 4, 5, 8, 14, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 16, 21, 22, 28, 29, 35, 42, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 35, 36, 37, 38, 39, 42, 43, 44, 45, 3, 4, 5, 8, 15, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 22, 23, 29, 30, 36, 43, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 36, 37, 38, 39, 43, 44, 45, 46, 3, 4, 5, 8, 15, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 22, 23, 29, 30, 36, 43, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 36, 37, 38, 39, 43, 44, 45, 46, 47, 3, 4, 5, 8, 15, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 22, 23, 29, 30, 36, 44, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 36, 37, 38, 39, 40, 44, 45, 46, 47, 3, 4, 5, 8, 15, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 22, 23, 29, 30, 37, 45, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41, 45, 46, 47, 48, 49, 3, 4, 8, 15, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 22, 23, 30, 31, 38, 46, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 38, 39, 40, 41, 42, 46, 47, 48, 49, 50, 3, 4, 8, 15, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 23, 24, 31, 32, 39, 47, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, 39, 40, 41, 42, 43, 47, 48, 49, 50, 3, 4, 8, 16, 3, 4, 5, 6, 7, 8, 9, 10, 16, 17, 18, 24, 25, 32, 33, 40, 48, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 22, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 40, 41, 42, 43, 44, 48, 49, 50, 51, 3, 4, 8, 16, 3, 4, 5, 6, 7, 8, 9, 10, 16, 17, 18, 24, 25, 32, 33, 40, 48, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 22, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 40, 41, 42, 43, 48, 49, 50, 51, 52, 3, 4, 8, 16, 3, 4, 5, 6, 7, 8, 9, 10, 16, 17, 18, 24, 25, 32, 33, 40, 49, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 22, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 40, 41, 42, 43, 44, 49, 50, 51, 52 }; static const int BMTb[3600] = { 512, 256, 256, 256, 256, 256, 256, 128, 128, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 8, 4, 2, 1, 4, 2, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 256, 256, 256, 128, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 4, 2, 1, 4, 2, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 256, 128, 128, 128, 128, 64, 64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 2, 1, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 128, 128, 64, 64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 8, 4, 2, 1, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 16, 8, 4, 2, 1, 4, 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 8, 4, 2, 1, 4, 2, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64, 64, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 8, 4, 2, 1, 4, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 64, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 64, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 64, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; static const int BitCount[1512] = { 10, 9, 9, 9, 9, 9, 8, 7, 9, 9, 8, 8, 8, 9, 7, 6, 5, 8, 8, 8, 7, 7, 9, 7, 6, 5, 4, 8, 7, 7, 7, 7, 8, 7, 6, 5, 4, 3, 7, 7, 7, 6, 6, 7, 7, 6, 5, 4, 3, 3, 7, 6, 6, 6, 6, 7, 7, 5, 4, 4, 3, 4, 3, 7, 6, 6, 6, 5, 6, 7, 5, 4, 4, 3, 3, 3, 3, 6, 6, 6, 5, 5, 6, 6, 5, 4, 4, 3, 3, 3, 3, 2, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 3, 2, 6, 5, 5, 5, 5, 5, 4, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 6, 5, 5, 4, 4, 5, 4, 5, 4, 4, 3, 3, 3, 3, 2, 3, 2, 1, 6, 5, 5, 4, 4, 5, 4, 5, 4, 4, 3, 3, 2, 3, 2, 1, 3, 2, 1, 5, 5, 5, 4, 4, 4, 4, 5, 4, 4, 3, 3, 2, 2, 3, 2, 1, 3, 2, 1, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 3, 2, 2, 3, 2, 1, 2, 2, 1, 5, 4, 4, 4, 4, 4, 3, 4, 4, 3, 4, 3, 2, 3, 2, 2, 2, 2, 1, 2, 2, 1, 5, 4, 4, 4, 4, 4, 3, 3, 4, 3, 3, 3, 3, 2, 3, 2, 1, 2, 2, 1, 2, 2, 1, 5, 4, 4, 4, 3, 4, 3, 3, 4, 3, 3, 3, 3, 2, 3, 2, 1, 2, 2, 1, 2, 1, 1, 1, 5, 4, 4, 3, 3, 4, 3, 3, 4, 3, 3, 3, 2, 2, 3, 2, 1, 2, 2, 1, 1, 2, 2, 1, 1, 5, 4, 4, 3, 3, 4, 3, 2, 4, 3, 2, 3, 2, 2, 3, 2, 2, 1, 2, 2, 1, 1, 2, 2, 1, 1, 4, 4, 4, 3, 3, 4, 3, 2, 4, 3, 2, 3, 2, 2, 2, 3, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 4, 4, 4, 3, 3, 3, 3, 2, 4, 3, 2, 2, 3, 2, 2, 2, 3, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 4, 4, 4, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 3, 2, 2, 1, 3, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 4, 4, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 3, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 4, 4, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 3, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 0, 4, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 3, 2, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 4, 3, 3, 3, 3, 3, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 0, 4, 3, 3, 3, 3, 3, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 0, 2, 1, 1, 1, 0, 4, 3, 3, 3, 3, 3, 2, 2, 2, 1, 3, 2, 2, 2, 1, 3, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 0, 2, 1, 1, 1, 0, 4, 3, 3, 3, 2, 3, 2, 2, 2, 1, 3, 2, 2, 2, 2, 3, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 0, 2, 1, 1, 1, 1, 0, 4, 3, 3, 3, 2, 3, 2, 2, 2, 1, 3, 2, 2, 2, 1, 3, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 0, 4, 3, 3, 3, 2, 3, 2, 2, 2, 1, 3, 2, 2, 2, 1, 3, 2, 1, 1, 1, 2, 2, 1, 1, 1, 0, 2, 1, 1, 1, 1, 0, 2, 1, 1, 1, 0, 0, 4, 3, 3, 3, 2, 3, 2, 2, 2, 1, 3, 2, 2, 1, 1, 3, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 2, 1, 1, 1, 1, 0, 2, 1, 1, 1, 0, 0, 4, 3, 3, 2, 2, 3, 2, 2, 1, 1, 3, 2, 2, 2, 1, 1, 3, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 2, 1, 1, 1, 1, 0, 2, 1, 1, 1, 0, 0, 4, 3, 3, 2, 2, 3, 2, 2, 2, 1, 1, 3, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 2, 1, 1, 1, 0, 0, 2, 1, 1, 1, 0, 0, 4, 3, 3, 2, 2, 3, 2, 2, 2, 1, 1, 3, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 2, 1, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 4, 3, 3, 2, 2, 3, 2, 2, 1, 1, 1, 3, 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 4, 3, 3, 2, 2, 3, 2, 2, 1, 1, 1, 3, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 3, 3, 3, 2, 2, 3, 2, 2, 1, 1, 1, 3, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 3, 3, 3, 2, 2, 3, 2, 2, 1, 1, 1, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 2, 1, 1, 1, 0, 0, 0, 3, 3, 3, 2, 2, 3, 2, 2, 1, 1, 1, 1, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 3, 3, 3, 2, 2, 3, 2, 2, 1, 1, 1, 1, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 2, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 3, 3, 3, 2, 2, 3, 2, 2, 1, 1, 1, 1, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3, 2, 2, 3, 2, 2, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 3, 3, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 3, 3, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, 3, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 0, 3, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 0, 3, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 0, 3, 3, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 0, 3, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0 }; static const float StepSize[1512] = { 0.003100, 0.004020, 0.003360, 0.002900, 0.002640, 0.006140, 0.012280, 0.024560, 0.006200, 0.004020, 0.006720, 0.005800, 0.005280, 0.006140, 0.024560, 0.046050, 0.085960, 0.012400, 0.008040, 0.006720, 0.011600, 0.010560, 0.006140, 0.024560, 0.046050, 0.085960, 0.122800, 0.012400, 0.016080, 0.013440, 0.011600, 0.010560, 0.012280, 0.024560, 0.046050, 0.085960, 0.122800, 0.199550, 0.024800, 0.016080, 0.013440, 0.021750, 0.019800, 0.024560, 0.024560, 0.046050, 0.085960, 0.122800, 0.199550, 0.156650, 0.024800, 0.030150, 0.025200, 0.021750, 0.019800, 0.024560, 0.024560, 0.085960, 0.122800, 0.122800, 0.156650, 0.122800, 0.156650, 0.024800, 0.030150, 0.025200, 0.021750, 0.036960, 0.046050, 0.024560, 0.085960, 0.122800, 0.096400, 0.199550, 0.156650, 0.199550, 0.156650, 0.046500, 0.030150, 0.025200, 0.040600, 0.036960, 0.046050, 0.046050, 0.085960, 0.096400, 0.122800, 0.156650, 0.199550, 0.156650, 0.199550, 0.204850, 0.046500, 0.030150, 0.047040, 0.040600, 0.036960, 0.085960, 0.085960, 0.067480, 0.122800, 0.096400, 0.122800, 0.156650, 0.199550, 0.204850, 0.199550, 0.204850, 0.046500, 0.056280, 0.047040, 0.040600, 0.036960, 0.085960, 0.096400, 0.085960, 0.067480, 0.122800, 0.156650, 0.199550, 0.156650, 0.199550, 0.204850, 0.260950, 0.204850, 0.046500, 0.056280, 0.047040, 0.058000, 0.052800, 0.085960, 0.096400, 0.085960, 0.096400, 0.122800, 0.156650, 0.199550, 0.156650, 0.199550, 0.204850, 0.199550, 0.204850, 0.248400, 0.046500, 0.056280, 0.047040, 0.058000, 0.052800, 0.085960, 0.096400, 0.085960, 0.096400, 0.122800, 0.156650, 0.199550, 0.204850, 0.199550, 0.204850, 0.248400, 0.199550, 0.204850, 0.248400, 0.086800, 0.056280, 0.047040, 0.058000, 0.052800, 0.122800, 0.096400, 0.085960, 0.096400, 0.122800, 0.156650, 0.199550, 0.204850, 0.175950, 0.199550, 0.204850, 0.248400, 0.199550, 0.204850, 0.248400, 0.086800, 0.056280, 0.067200, 0.058000, 0.052800, 0.122800, 0.096400, 0.122800, 0.096400, 0.122800, 0.156650, 0.175950, 0.199550, 0.204850, 0.175950, 0.199550, 0.204850, 0.248400, 0.260950, 0.204850, 0.248400, 0.086800, 0.080400, 0.067200, 0.058000, 0.052800, 0.122800, 0.156650, 0.122800, 0.096400, 0.134550, 0.122800, 0.156650, 0.175950, 0.199550, 0.204850, 0.175950, 0.260950, 0.204850, 0.248400, 0.260950, 0.204850, 0.248400, 0.086800, 0.080400, 0.067200, 0.058000, 0.052800, 0.122800, 0.156650, 0.134550, 0.122800, 0.156650, 0.134550, 0.199550, 0.156650, 0.175950, 0.199550, 0.204850, 0.248400, 0.260950, 0.204850, 0.248400, 0.260950, 0.204850, 0.248400, 0.086800, 0.080400, 0.067200, 0.058000, 0.085800, 0.122800, 0.156650, 0.134550, 0.122800, 0.156650, 0.134550, 0.199550, 0.156650, 0.175950, 0.199550, 0.204850, 0.248400, 0.260950, 0.204850, 0.248400, 0.260950, 0.289200, 0.248400, 0.228000, 0.086800, 0.080400, 0.067200, 0.094250, 0.085800, 0.122800, 0.156650, 0.134550, 0.122800, 0.156650, 0.134550, 0.199550, 0.204850, 0.175950, 0.199550, 0.204850, 0.248400, 0.260950, 0.204850, 0.248400, 0.228000, 0.260950, 0.204850, 0.248400, 0.228000, 0.086800, 0.080400, 0.067200, 0.094250, 0.085800, 0.122800, 0.156650, 0.175950, 0.122800, 0.156650, 0.175950, 0.199550, 0.204850, 0.175950, 0.199550, 0.204850, 0.175950, 0.228000, 0.260950, 0.204850, 0.248400, 0.228000, 0.260950, 0.204850, 0.248400, 0.228000, 0.124000, 0.080400, 0.067200, 0.094250, 0.085800, 0.122800, 0.156650, 0.175950, 0.122800, 0.156650, 0.175950, 0.199550, 0.204850, 0.175950, 0.161500, 0.199550, 0.204850, 0.248400, 0.228000, 0.260950, 0.204850, 0.248400, 0.228000, 0.260950, 0.289200, 0.248400, 0.228000, 0.124000, 0.080400, 0.067200, 0.094250, 0.085800, 0.199550, 0.156650, 0.175950, 0.122800, 0.156650, 0.175950, 0.161500, 0.199550, 0.204850, 0.175950, 0.161500, 0.199550, 0.204850, 0.248400, 0.228000, 0.260950, 0.289200, 0.248400, 0.228000, 0.260950, 0.289200, 0.248400, 0.228000, 0.124000, 0.080400, 0.067200, 0.094250, 0.085800, 0.199550, 0.156650, 0.175950, 0.161500, 0.199550, 0.156650, 0.175950, 0.161500, 0.199550, 0.204850, 0.175950, 0.228000, 0.199550, 0.204850, 0.248400, 0.228000, 0.260950, 0.289200, 0.248400, 0.228000, 0.260950, 0.289200, 0.248400, 0.228000, 0.124000, 0.080400, 0.109200, 0.094250, 0.085800, 0.199550, 0.156650, 0.175950, 0.161500, 0.199550, 0.156650, 0.175950, 0.161500, 0.199550, 0.204850, 0.175950, 0.228000, 0.260950, 0.204850, 0.248400, 0.228000, 0.260950, 0.289200, 0.248400, 0.228000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.124000, 0.080400, 0.109200, 0.094250, 0.085800, 0.199550, 0.156650, 0.175950, 0.161500, 0.199550, 0.156650, 0.175950, 0.161500, 0.199550, 0.204850, 0.175950, 0.228000, 0.260950, 0.204850, 0.248400, 0.228000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.124000, 0.130650, 0.109200, 0.094250, 0.085800, 0.199550, 0.156650, 0.175950, 0.161500, 0.199550, 0.156650, 0.175950, 0.161500, 0.199550, 0.204850, 0.248400, 0.228000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.124000, 0.130650, 0.109200, 0.094250, 0.085800, 0.199550, 0.204850, 0.175950, 0.161500, 0.199550, 0.204850, 0.175950, 0.161500, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.124000, 0.130650, 0.109200, 0.094250, 0.085800, 0.199550, 0.204850, 0.175950, 0.161500, 0.199550, 0.204850, 0.175950, 0.161500, 0.152150, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.124000, 0.130650, 0.109200, 0.094250, 0.085800, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.124000, 0.130650, 0.109200, 0.094250, 0.112200, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.199550, 0.204850, 0.175950, 0.161500, 0.152150, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.124000, 0.130650, 0.109200, 0.094250, 0.112200, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.124000, 0.130650, 0.109200, 0.094250, 0.112200, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.124000, 0.130650, 0.109200, 0.094250, 0.112200, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.124000, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.207600, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.124000, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.207600, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.124000, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.207600, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.124000, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.199550, 0.204850, 0.175950, 0.161500, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.124000, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.201500, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.201500, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.109200, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.142800, 0.123250, 0.112200, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.142800, 0.123250, 0.112200, 0.199550, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.204000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.142800, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.142800, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.000000, 0.201500, 0.130650, 0.142800, 0.123250, 0.112200, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.199550, 0.204850, 0.175950, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.207600, 0.198000, 0.000000, 0.260950, 0.204850, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.214800, 0.000000, 0.000000, 0.000000, 0.000000, 0.260950, 0.289200, 0.248400, 0.228000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 }; static const float AnnexE[64] = { -2.842205, -2.694235, -2.558260, -2.382850, -2.221042, -2.095574, -1.980845, -1.836058, -1.645556, -1.417658, -1.261301, -1.125631, -0.958207, -0.781591, -0.555837, -0.346976, -0.147249, 0.027755, 0.211495, 0.388380, 0.552873, 0.737223, 0.932197, 1.139032, 1.320995, 1.483433, 1.648297, 1.801447, 1.942731, 2.118613, 2.321486, 2.504443, 2.653909, 2.780654, 2.925355, 3.076390, 3.220825, 3.402869, 3.585096, 3.784606, 3.955521, 4.155636, 4.314009, 4.444150, 4.577542, 4.735552, 4.909493, 5.085264, 5.254767, 5.411894, 5.568094, 5.738523, 5.919215, 6.087701, 6.280685, 6.464201, 6.647736, 6.834672, 7.022583, 7.211777, 7.471016, 7.738948, 8.124863, 8.695827 }; static const float ws[211] = { 0.000000, 0.020000, 0.040000, 0.060000, 0.080000, 0.100000, 0.120000, 0.140000, 0.160000, 0.180000, 0.200000, 0.220000, 0.240000, 0.260000, 0.280000, 0.300000, 0.320000, 0.340000, 0.360000, 0.380000, 0.400000, 0.420000, 0.440000, 0.460000, 0.480000, 0.500000, 0.520000, 0.540000, 0.560000, 0.580000, 0.600000, 0.620000, 0.640000, 0.660000, 0.680000, 0.700000, 0.720000, 0.740000, 0.760000, 0.780000, 0.800000, 0.820000, 0.840000, 0.860000, 0.880000, 0.900000, 0.920000, 0.940000, 0.960000, 0.980000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.980000, 0.960000, 0.940000, 0.920000, 0.900000, 0.880000, 0.860000, 0.840000, 0.820000, 0.800000, 0.780000, 0.760000, 0.740000, 0.720000, 0.700000, 0.680000, 0.660000, 0.640000, 0.620000, 0.600000, 0.580000, 0.560000, 0.540000, 0.520000, 0.500000, 0.480000, 0.460000, 0.440000, 0.420000, 0.400000, 0.380000, 0.360000, 0.340000, 0.320000, 0.300000, 0.280000, 0.260000, 0.240000, 0.220000, 0.200000, 0.180000, 0.160000, 0.140000, 0.120000, 0.100000, 0.080000, 0.060000, 0.040000, 0.020000, 0.000000 }; static const float woaa[105] = { 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.040799, 1.083189, 1.127142, 1.172608, 1.219512, 1.267748, 1.317176, 1.367615, 1.418842, 1.470588, 1.522534, 1.574307, 1.625488, 1.675603, 1.724138, 1.770538, 1.814224, 1.854599, 1.891074, 1.923077, 1.950078, 1.971609, 1.987282, 1.996805, 2.000000, 1.996805, 1.987282, 1.971609, 1.950078, 1.923077, 1.891074, 1.854599, 1.814224, 1.770538, 1.724138, 1.675603, 1.625488, 1.574307, 1.522534, 1.470588, 1.418842, 1.367615, 1.317176, 1.267748, 1.219512, 1.172608, 1.127142, 1.083189, 1.040799 }; static const float PhzNz[57] = { 0.000000, 3.002978, -0.385743, -1.804058, 0.708389, 3.080091, 0.234237, -2.601564, 2.564900, 0.101063, -0.241570, -2.283176, 0.460491, -1.611275, 2.258339, -2.055267, 1.733923, 2.517236, -1.766211, 0.897032, -2.360999, -0.280836, -2.714514, 2.100092, 2.300326, -1.158767, -2.044268, -2.668387, -2.578737, 0.185036, 1.551429, 2.726814, 2.655614, 3.046857, 0.834348, -0.513595, 1.466037, 0.691121, 0.127319, -2.034924, -1.070655, 0.456588, -2.278682, 1.229021, -2.139595, -0.119750, -0.301534, 0.029391, 0.068775, 0.520336, 2.339119, -0.808328, 1.332154, 2.929768, -0.338316, 0.022767, -1.063795 }; static const float Ui[129] = { 460.246094, 90.698601, -140.362900, 3.415093, 99.369812, 445.443207, 522.042786, 252.818405, 125.521202, -119.443199, -342.607910, -393.066895, -494.564301, -284.859009, 351.480896, 660.536377, 149.394104, -654.466980, -845.040527, -496.079102, -155.383499, 313.371399, 370.925110, -207.061905, -49.371632, 355.883392, -295.865509, -950.418823, -646.136597, 154.876801, 475.990295, 251.149902, 275.690796, 176.195206, 39.321491, 323.984711, 3.765467, -740.295471, -684.010681, 22.967060, 532.828186, 327.829803, -17.576559, 36.373402, -144.939194, -400.725189, 59.048889, 408.261597, -3.164414, -207.470093, -76.218567, -8.249402, 56.827209, -221.976196, -346.998199, -139.244995, -582.422485, -1028.400024, -727.781982, -406.098907, -191.811295, 41.401581, -151.480103, -641.985779, -607.550781, -400.055786, -678.727417, -376.449890, 434.718109, 239.750504, -470.508392, -552.972717, -148.247299, 153.369507, 113.672798, 29.017599, 31.270840, -13.290440, -250.178604, -504.166809, -8.738471, 669.869019, 43.365711, -669.164429, -29.603149, 114.396599, -495.633301, -105.838203, 90.404091, -299.971100, 154.039200, 380.408691, 111.480400, 158.179993, -205.268204, -386.008087, -62.792370, -327.508087, -488.555298, 15.982190, 264.942902, 171.169998, 112.966904, -209.006302, -364.411591, 367.667999, 417.925293, -867.776184, -1286.915039, -779.282288, -557.706482, -184.866501, 189.383804, 140.763107, 143.058304, 522.142395, 586.625122, -52.709290, 46.055168, 955.700806, 807.637085, -213.939499, -450.946411, 209.997101, 114.041298, -608.001221, -67.676140, 800.976929, 918.058594 }; static const float Uq[129] = { 0.000000, 15.557470, -141.517395, 4.850000, 20.818390, -31.850750, 240.388107, 359.115509, 353.314514, -34.321480, -683.943787, -426.828705, 251.196106, 648.932800, 583.257080, -272.161804, -696.480774, -616.009888, -730.197388, -275.599213, -71.369781, -246.298599, 353.591187, 383.542999, -457.883911, -573.009827, 123.842796, 808.834473, 590.295227, -116.924400, 4.462234, 300.142792, -398.965790, -1374.654053, -1271.543945, -306.073090, 175.326508, 330.696106, 640.043701, 308.004608, -163.072403, 10.378300, -113.961601, -623.374390, -714.512207, -384.877991, 71.181877, 261.299896, 129.764801, -8.331214, -68.725418, 88.997963, 276.388611, -133.622498, -673.724915, -355.871704, -137.479996, -829.466675, -936.803223, -471.582794, -615.728271, -670.887085, -713.287109, -1046.473022, -679.554688, -198.067902, -328.069305, -487.968994, -368.145203, 482.697296, 1213.579956, 528.013977, -148.013107, 88.007896, 349.561005, 483.642792, -11.267410, -765.563721, -95.221008, 1021.109985, 810.747620, 291.417908, 516.477783, 771.458984, 430.919586, -105.049500, -259.056702, -412.976807, -776.695312, -506.850098, -208.051407, -624.956421, -280.915710, 302.574402, -349.600403, -520.683228, 278.127899, 446.518799, 21.136551, -178.466400, 262.635498, 683.496704, 448.290802, 360.132202, 334.482605, -306.716003, -777.159912, -433.828796, 88.513657, 278.588989, 94.746696, -541.088989, -645.232483, 321.504211, 801.454773, 511.169189, 164.987106, -538.676819, -971.696228, -735.475586, -533.916626, -355.275909, -234.147903, -468.023285, -691.458313, -533.001770, -291.729004, -199.716904, 0.000000 }; software_imbe_decoder::software_imbe_decoder() : out(fopen("audio.pcm", "w")) { int i,j; //initialize Old = 1; New = 0; psi1 = 0.0; for(i=0; i < 58; i++) { for(j=0; j < 2; j++) { log2Mu[i][j] = 0.0; } } for(i=0; i < 57; i++) { for(j=0; j < 2; j++) { phi[i][j] = 0.0; } } for(i=0; i < 256; i++) { Olduw[i] = 0.0; } } software_imbe_decoder::~software_imbe_decoder() { if(out) { fclose(out); } } void software_imbe_decoder::decode(uint8_t *buf) { // process input 144-bit IMBE frame - converts to 88-bit frame int i; unsigned int u0 = 0; unsigned int u1,u2,u3,u4,u5,u6,u7; unsigned int E0 = 0; unsigned int ET = 0; unsigned char O[12]; // PN/Hamming/Golay - etc. correct(buf, u0, u1, u2, u3, u4, u5, u6, u7, E0, ET) ; //replace the sync bit(LSB of u7) with the BOT flag BOT = 1; u7 = u7 | BOT; //ECC procedure called above always returns u7 LSB = 0 BOT = 0; // 'because E0 is 3 max and ET is 15 max, the 2 MSB of the error count byte are // ' free for other data such as a 100 bit/sec serial bit stream to carry info // ' such as time, channel, talk group, etc. O[0] =(((u0 / 16) & 240) +(u1 / 256)); O[1] =(((u2 / 16) & 240) +(u3 / 256)); O[2] =(((u4 / 8) & 224) +((u5 / 64) & 28) +(u6 / 512)); O[3] =(((u6 / 2) & 128) + u7); O[4] =(u0 & 255); O[5] =(u1 & 255); O[6] =(u2 & 255); O[7] =(u3 & 255); O[8] =(u4 & 255); O[9] =(u5 & 255); O[10] =(u6 & 255); O[11] = E0 + 4 * ET; #if 0 // IMBE diagnostix printf("1: "); for(i=0; i<12; i++) { printf("%02x ", O[i]); } printf("\n"); #endif // process 88-bit frame decode_audio(O); } void software_imbe_decoder::adaptive_smoothing(float SE, float ER, float ET) { float VM; float AM; float YM; float TM; int ell; if(ER <= .005 && ET <= 4) { VM = 1E+38; //infinity } else if( ER <= .0125 && ET == 0) { //(guessing typo in std) VM = 45.255 * powf(SE , .375) / exp(277.6 * ER); } else { VM = 1.414 * powf(SE , .375); } AM = 0; for(ell = 1; ell <= L; ell++) { if(M[ell][ New] > VM) vee[ell][ New] = 1; //CAUTION: AM = AM + M[ell][ New]; //smoothed vee(ell) replaces unsmoothed! } if(ER <= .005 && ET <= 6) TM = 20480; else TM = 6000 - 300 * ET + TM; if(TM <= AM) { YM = TM / AM; for(ell = 1; ell <= L; ell++) { M[ell][ New] = M[ell][ New] * YM; } } } void software_imbe_decoder::fft(float REX[], float IMX[]) { int I; int J; int K; int H; int KpH; int Ht2; float tmp_f; float l_Ui, l_Uq, Theta, Si, Sq, Ti, Xi, Tq, Xq; J = 64; for(I = 1; I <= 126; I++) { #define SWAP(x,y) tmp_f=x;x=y;y=tmp_f if(I < J) { SWAP(REX[J], REX[I]); SWAP(IMX[J], IMX[I]); } #undef SWAP K = 64; while(K <= J) { J = J - K; K = K / 2; } J = J + K; } H = 1; for(I = 1; I <= 7; I++) { Ht2 = H * 2; l_Ui = 1; l_Uq = 0; Theta = M_PI / H; Si = cos(Theta); Sq = -sin(Theta); for(J = 1; J <= H; J++) { for(K = J - 1; K <= 127; K+=Ht2) { KpH = K + H; Ti = REX[KpH] * l_Ui - IMX[KpH] * l_Uq; Xi = REX[K]; Tq = REX[KpH] * l_Uq + IMX[KpH] * l_Ui; Xq = IMX[K]; REX[KpH] = Xi - Ti; REX[K] = Xi + Ti; IMX[KpH] = Xq - Tq; IMX[K] = Xq + Tq; } Ti = l_Ui; l_Ui = Ti * Si - l_Uq * Sq; l_Uq = Ti * Sq + l_Uq * Si; } H = Ht2; } } void software_imbe_decoder::decode_audio(uint8_t *A) { uint32_t u0, u1, u2, u3, u4, u5, u6, u7, E0, ET; int K; int Len3, Start3, Len8, Start8; int en, ClipCount, tmp_f, samp; float SE=0, ER=0, OutSamp=0; unpack(A, u0, u1, u2, u3, u4, u5, u6, u7, E0, ET); ER = .95 * ER + .000365 * ET; if( ER > .0875) { // Huh?! } else if(u0 >= 3328 || E0 >= 2 || ET >=(10 + 40 * ER)) { // Whuh?! } else { K = rearrange(u0, u1, u2, u3, u4, u5, u6, u7); // re-arrange the bits from u to b (ToDo: make 'b' return value ???) decode_vuv(K); Len3 = L - 1; Start3 =((Len3 *(Len3 - 1)) / 2) - 28; Len8 = L - 6; Start8 =((Len8 *(Len8 - 1)) / 2) - 3; decode_spectral_amplitudes(Start3, Start8); enhance_spectral_amplitudes(SE); adaptive_smoothing(SE, ER, ET); //(8000 samp/sec) *(1 sec/50 frame) = 160 samp/frame //fHz = 4000 * w0 / M_PI //synth: synth_unvoiced(); synth_voiced(); //output: for(en = 0; en <= 159; en++) { // The unvoiced samples are loud and the voiced are low...I don't know why. // Most of the difference is compensated by removing the 146.6433 factor // in the synth_unvoiced procedure. The final tweak is done by raising the // voiced samples: OutSamp = suv[en] + sv[en] * 4; //balance v/uv loudness if(abs((int)OutSamp) > 32767) { OutSamp = 32767 *(OutSamp < 0) ? -1 : 1; // * sgn(OutSamp); ClipCount = ClipCount + 1; } samp =(int) rintf(OutSamp); // write(2, &samp, 2); if(out) { fwrite(&samp, 2, 1, out); } else { printf("warning: couldn't write output\n"); } } } OldL = L; Oldw0 = w0; tmp_f = Old; Old = New; New = tmp_f; } void software_imbe_decoder::decode_spectral_amplitudes(int Start3, int Start8) { float G[7]; //Can we use C(1 to 6,1) for this? int J[7]; float C[7][ 11] ; float T[57]; float Tmp ; float Tk ; float TD; float Tp ; int P3, P8, eye, jay, kay, ell, em, iTk; P3 = Start3; P8 = Start8; G[1] = AnnexE[bee[2]]; for(eye = 2; eye <= 6; eye++) { G[eye] = StepSize[P3] *(bee[eye + 1] - powf(2 ,(BitCount[P3] - 1)) + .5); P3 = P3 + 1; } for(eye = 1; eye <= 6; eye++) { Tmp = G[1]; for(em = 2; em <= 6; em++) { Tmp = Tmp + 2 * G[em] * cos(M_PI *(em - 1) *(eye - .5) / 6); } //R(eye) = Tmp C[eye][1] = Tmp; } ell = 8; for(eye = 1; eye <= 6; eye++) { J[eye] =(L + eye - 1) / 6; //Prediction Residual Block Length // FOR kay = 2 TO J(eye) for(kay = 2; kay <= J[eye]; kay++) { C[eye][ kay] = StepSize[P3] *(bee[ell] - powf(2 ,(BitCount[P3] - 1)) + .5); P3 = P3 + 1; P8 = P8 + 1; ell = ell + 1; } } ell = 0; for(eye = 1; eye <= 6; eye++) { for(jay = 1; jay <= J[eye]; jay++) { Tmp = C[eye][ 1]; // FOR kay = 2 TO J(eye) for(kay = 2; kay <= J[eye]; kay++) { Tmp = Tmp + 2 * C[eye][ kay] * cos(M_PI *(kay - 1) *(jay - .5) / J[eye]); } ell = ell + 1; T[ell] = Tmp; } } if(ell != L) exit(1); // ******* // we have the residuals in T(ell); now to sum with the predictions // ******* // first, set up the assumptions about the previous frame values // Note: L means L(0); OldL means L(-1) if(OldL == 0) { OldL = 30; for( ell = 0; ell <= 57; ell++) { log2Mu[ell][ Old] = 1; } } for(ell = OldL + 1; ell <= L + 1; ell++) { log2Mu[ell][ Old] = log2Mu[OldL][ Old]; } // make the predictions and sum with T(ell) if(L <= 15) Tp = .4; else if(L <= 24) Tp = .03 * L - .05; else Tp = .7; Tmp = 0; for(ell = 1; ell <= L; ell++) { Tk =((float)OldL /(float)L) *(float)ell; iTk =(int) Tk; TD = Tk - iTk; // temporarily use Mu(ell, New) as temp Mu[ell][ New] = Tp *((1 - TD) * log2Mu[iTk][ Old] + TD * log2Mu[iTk + 1][ Old]); Tmp = Tmp + Mu[ell][ New]; } Tmp = Tmp / L; for(ell = 1; ell <= L; ell++) { log2Mu[ell][ New] = T[ell] + Mu[ell][ New] - Tmp; // Mu(ell, New) no longer temp Mu[ell][ New] = powf(2 ,log2Mu[ell][ New]); } } void software_imbe_decoder::decode_vuv(int K) { int bee1, ell, kay; bee1 = bee[1]; for(ell = 1; ell <= L; ell++) { if(ell <= 36) kay =(ell + 2) / 3; else kay = 12; //vee(ell, New) = (bee1 \(2 ^(K - kay))) - 2 *(bee1 \(2 ^(K + 1 - kay))) vee[ell][ New] = ((bee1 & (1 << (K - kay))) > 0) ? 1 : 0; } } void software_imbe_decoder::enhance_spectral_amplitudes(float& SE) { float RM0; float RM1; float Tmp; float K1; float K2; float K3; float W; int ell; RM0 = 0; RM1 = 0; for(ell = 1; ell <= L; ell++) { Tmp = powf(Mu[ell][ New] , 2); RM0 = RM0 + Tmp; RM1 = RM1 + Tmp * cos(w0 * ell); } K1 = .96 * M_PI /(w0 * RM0 *(powf(RM0 , 2) - powf(RM1 , 2))); K2 = powf(RM0 , 2) + powf(RM1 , 2); K3 = 2 * RM0 * RM1; Tmp = 0; for(ell = 1; ell <= L; ell++) { W = sqrt(Mu[ell][ New]) * powf((K1 *(K2 - K3 * cos(w0 * ell))) , .25); if((8 * ell) <= L) M[ell][ New] = Mu[ell][ New]; else if(W > 1.2) M[ell][ New] = Mu[ell][ New] * 1.2; else if(W < .5) M[ell][ New] = Mu[ell][ New] * .5; else M[ell][ New] = Mu[ell][ New] * W; Tmp = Tmp + powf(M[ell][ New] , 2); } Tmp = sqrt(RM0 / Tmp); for(ell = 1; ell <= L; ell++) { M[ell][ New] = M[ell][ New] * Tmp; } // update SE SE = .95 * SE + .05 * RM0; if(SE < 10000) SE = 10000; } void software_imbe_decoder::ifft(float FDi[], float FDq[], float TD[]) // ToDo: replace "real IFFT" with fftw3 IFFT proc! { //Inverse FFT: // transform 129-point freq domain(FDx) to 256-point time domain(TD) float Ai[128]; float Aq[128]; int I; int J; int K; int H; float l_Ui, l_Uq, Si, Sq, Ti, Tq, Xi, Xq; for(I = 0; I <= 63; I++) { J = I + 64; //64 to 127 K = I * 2; //0 to 126(step 2) H = 128 - K; //128 to 2(step 2) Ai[I] = FDi[K] + FDq[K]; Aq[I] = FDi[K + 1] + FDq[K + 1]; Ai[J] = FDi[H] - FDq[H]; Aq[J] = FDi[H - 1] - FDq[H - 1]; } fft(Ai, Aq); for(I = 1; I <= 63; I++) { J = 128 - I; //127 to 65 K = I + 128; //129 to 191 H = J + 128; //255 to 193 FDi[K] =(Aq[I] + Aq[J]) / 2; FDi[H] = FDi[K] ; //a FDq[K] = -(Ai[I] - Ai[J]) / 2; FDq[H] = -FDq[K] ; //b FDi[I] =(Ai[I] + Ai[J]) / 2; FDi[J] = FDi[I] ; //c FDq[I] =(Aq[I] - Aq[J]) / 2; FDq[J] = -FDq[I] ; //d } //I,J=64 K,H=192 FDi[192] = Aq[64]; //a FDq[192] = 0 ; //b FDi[64] = Ai[64] ; //c (new) FDq[64] = 0 ; //d //I=0 J,K=128 H=256 ( Ax(128) wraps to Ax(0)) FDi[128] = Aq[0] ; //a FDq[128] = 0 ; //b FDi[0] = Ai[0] ; //c (new) FDq[0] = 0 ; //d l_Ui = 1; l_Uq = 0; Si = cos(M_PI / 128); Sq = -sin(M_PI / 128); for(I = 0; I <= 127; I++) { J = I + 128 ; //128 TO 255 Ti = FDi[J] * l_Ui - FDq[J] * l_Uq; Xi = FDi[I]; Tq = FDi[J] * l_Uq + FDq[J] * l_Ui; Xq = FDq[I]; TD[I + 128] =((Xi + Ti) -(Xq + Tq)); TD[I ] =((Xi - Ti) -(Xq - Tq)); Ti = l_Ui; l_Ui = Ti * Si - l_Uq * Sq; l_Uq = Ti * Sq + l_Uq * Si; } } uint16_t software_imbe_decoder::rearrange(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3, uint32_t u4, uint32_t u5, uint32_t u6, uint32_t u7) { int K; int I, ubit, Seq, col; bee[0] =((u0 / 16) & 0xfc) |((u7 / 2) & 3); w0 = 4 * M_PI /(bee[0] + 39.5); L =(int)(.9254 * floorf((M_PI / w0) + .25)); if(L < 9 || L > 56) exit(2); if( L > 36) { K = 12; } else { K =((L + 2) / 3); if(K > 12) exit(3); } for(I = 1; I <= L + 1; I++) { bee[I] = 0; } bee[2] =(u0 & 56) |((u7 / 8) & 1); Seq =(L - 9) * 75; ubit = 4; for(I = 0; I <= 2; I++) { if( u0 & ubit) { col = BMTn[Seq]; bee[col] = bee[col] + BMTb[Seq]; } Seq = Seq + 1; ubit = ubit / 2; } ubit = 2048; for(I = 0; I <= 11; I++) { if(u1 & ubit){ col = BMTn[Seq]; bee[col] = bee[col] + BMTb[Seq]; } Seq = Seq + 1; ubit = ubit / 2; } ubit = 2048; for(I = 0; I <= 11; I++) { if(u2 & ubit){ col = BMTn[Seq]; bee[col] = bee[col] + BMTb[Seq]; } Seq = Seq + 1; ubit = ubit / 2; } ubit = 2048; for(I = 0; I <= 11; I++) { if(u3 & ubit) { col = BMTn[Seq]; bee[col] = bee[col] + BMTb[Seq]; } Seq = Seq + 1; ubit = ubit / 2; } ubit = 1024; for(I = 0; I <= 10; I++) { if(u4 & ubit) { col = BMTn[Seq]; bee[col] = bee[col] + BMTb[Seq]; } Seq = Seq + 1; ubit = ubit / 2; } ubit = 1024; for(I = 0; I <= 10; I++) { if(u5 & ubit) { col = BMTn[Seq]; bee[col] = bee[col] + BMTb[Seq]; } Seq = Seq + 1; ubit = ubit / 2; } ubit = 1024; for(I = 0; I <= 10; I++) { if(u6 & ubit){ col = BMTn[Seq]; bee[col] = bee[col] + BMTb[Seq]; } Seq = Seq + 1; ubit = ubit / 2; } ubit = 64; for(I = 4; I <= 6; I++) { if(u7 & ubit) { col = BMTn[Seq]; bee[col] = bee[col] + BMTb[Seq]; } Seq = Seq + 1; ubit = ubit / 2; } return K; } void software_imbe_decoder::synth_unvoiced() { float Uwi[256] ; float Uwq[256] ; float uw[256] ; float Tmp ; int ell, bl, em, al, en; ell = 0; bl =(int) ceilf(128 / M_PI *(ell + .5) * w0); for(em = 0; em <= bl - 1; em++) { Uwi[em] = 0; Uwq[em] = 0; } Luv = 0; for(ell = 1; ell <= L; ell++) { al = bl; bl =(int) ceilf(128 / M_PI *(ell + .5) * w0); if( vee[ell][ New]) { // FOR em = al TO bl - 1 for(em = al; em <= bl - 1; em++) { Uwi[em] = 0; Uwq[em] = 0; } } else { Luv = Luv + 1; //precompute Tmp = Tmp = 0; // FOR en = al TO bl - 1 for(en = al; en <= bl - 1; en++) { Tmp = Tmp + powf(Ui[en] , 2) + pow(Uq[en] , 2); } Tmp = M[ell][ New] / sqrt(Tmp /(bl - al)); //too loud with 146.6433 factor //now do the rest of b.h.e. // FOR em = al TO bl - 1 for(em = al; em <= bl - 1; em++) { Uwi[em] =(Ui[em]) * Tmp; Uwq[em] =(Uq[em]) * Tmp; } } } // finally do over-freq // FOR em = bl TO 128 for(em = bl; em <= 128; em++) { Uwi[em] = 0; Uwq[em] = 0; } ifft(Uwi, Uwq, uw); // ws(n)*uw(n,-1) + ws(n-159)*uw(n-159,0) uw(-128 to 127) //suv(n) = -------------------------------------- // (ws(n)^2) +(ws(n-159)^2) ws(-105 to 105) for(en = 0; en <= 55; en++) { suv[en] = Olduw[en+128]; } for(en = 56; en <= 104; en++) { suv[en] =(ws[en+105] * Olduw[en+128] + ws[en - 55] * uw[en - 32]) * woaa[en]; } for(en = 105; en <= 159; en++) { suv[en] = uw[en - 32]; } for(en = -128; en <= 127; en++) { Olduw[en+128] = uw[en+128]; } } void software_imbe_decoder::synth_voiced() { float MaxL; float Tmp; float Dpl; float Dwl; float THa; float THb; float MNew; float MOld; float Mb; int ell, en; if( L > OldL) { MaxL = L; } else { MaxL = OldL; } psi1 = psi1 +(Oldw0 + w0) * 80; psi1 = remainderf(psi1, 2 * M_PI); // ToDo: decide if its 2pi or pi^2 for(ell = 1; ell <= L/4; ell++) { phi[ell][ New] = psi1 * ell; } Tmp = Luv / L; for(; ell <= MaxL; ell++) { phi[ell][ New] = psi1 * ell + Tmp * PhzNz[ell]; } for(en = 0; en <= 159; en++) { sv[en] = 0; } for(ell = 1; ell <= MaxL; ell++) { if(ell > L) { MNew = 0; } else { MNew = M[ell][ New]; } if(ell > OldL) { MOld = 0; } else { MOld = M[ell][ Old]; } if(vee[ell][ New]) { if ( vee[ell][ Old]) { if(ell < 8 & fabsf(w0 - Oldw0) < .1 * w0) { // (fine transition) const double PI_SQUARED = M_PI * M_PI; const double INV_PI_SQUARED = 1.0 / PI_SQUARED; Dpl = phi[ell][ New] - phi[ell][ Old] -(Oldw0 + w0) * ell * 80; Dwl = .00625 * (Dpl - PI_SQUARED * floorf((Dpl + M_PI) * INV_PI_SQUARED)); THa = (Oldw0 * (float)ell + Dwl); THb = (w0 - Oldw0) * ell * .003125; Mb = .00625 *(MNew - MOld); for(en = 0; en <= 159; en++) { sv[en] = sv[en] +(MOld + en * Mb) * cos(phi[ell][ Old] +(THa + THb * en) * en); } } else { // (coarse transition) for(en = 0; en <= 55; en++) { sv[en] = sv[en] + ws[en+105] * MOld * cos(Oldw0 * en * ell + phi[ell] [ Old]); } for(en = 56; en <= 105; en++) { sv[en] = sv[en] + ws[en+105] * MOld * cos(Oldw0 * en * ell + phi[ell][ Old]); sv[en] = sv[en] + ws[en-55] * MNew * cos(w0 *(en - 160) * ell + phi[ell][ New]); } for(en = 106; en <= 159; en++) { sv[en] = sv[en] + ws[en-55] * MNew * cos(w0 *(en - 160) * ell + phi[ell][ New]); } } } else { for(en = 56; en <= 159; en++) { sv[en] = sv[en] + ws[en-55] * MNew * cos(w0 *(en - 160) * ell + phi[ell][ New]); } } } else { if( vee[ell][Old]) { for(en = 0; en <= 105; en++) { sv[en] = sv[en] + ws[en+105] * MOld * cos(Oldw0 * en * ell + phi[ell][ Old]); } } } } } void software_imbe_decoder::unpack(uint8_t *A, uint32_t& u0, uint32_t& u1, uint32_t& u2, uint32_t& u3, uint32_t& u4, uint32_t& u5, uint32_t& u6, uint32_t& u7, uint32_t& E0, uint32_t& ET) { E0 = A[0]; ET = A[1]; u0 = A[4] +(E0 & 240) * 16; u1 = A[5] +(E0 & 15) * 256; u2 = A[6] +(ET & 240) * 16; u3 = A[7] +(ET & 15) * 256; E0 = A[2]; ET = A[3]; u4 = A[8] +(E0 & 224) * 8; u5 = A[9] +(E0 & 28) * 64; u6 = A[10] +(ET & 128) * 2 +(E0 & 3) * 512; u7 = ET & 127; E0 = A[11]; if(E0 & 192) exit(4); ET = E0 & 3; E0 =(E0 & 84) / 4; } uint32_t software_imbe_decoder::extract(const uint8_t* buf, size_t begin, size_t end) { uint32_t x = 0; for(size_t i = begin; i < end; ++i) { x <<= 1; x |= (buf[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0; } return x; } uint32_t software_imbe_decoder::pngen15(uint32_t& Pr) { int n = 0; for(int i = 14; i >= 0; --i) { Pr = (173 * Pr + 13849) & 0xffffu; if(Pr & 32768) { n += (1 << i); } } return n; } uint32_t software_imbe_decoder::pngen23(uint32_t& Pr) { int n = 0; for(int i = 22; i >= 0; --i) { Pr = (173 * Pr + 13849) & 0xffffu; if(Pr & 32768) { n += (1 << i); } } return n; } void software_imbe_decoder::correct(uint8_t* buf, uint32_t& u0, uint32_t& u1, uint32_t& u2, uint32_t& u3, uint32_t& u4, uint32_t& u5, uint32_t& u6, uint32_t& u7, uint32_t& E0, uint32_t& ET) { ET = 0; size_t errs = 0; uint32_t v0 = extract(buf, 0, 23); errs = golay_23_decode(v0); u0 = v0; E0 = ET; uint32_t pn = u0 << 4; uint32_t m1 = pngen23(pn); uint32_t v1 = extract(buf, 23, 46) ^ m1; errs += golay_23_decode(v1); u1 = v1; uint32_t m2 = pngen23(pn); uint32_t v2 = extract(buf, 46, 69) ^ m2; errs += golay_23_decode(v2); u2 = v2; uint32_t m3 = pngen23(pn); uint32_t v3 = extract(buf, 69, 92) ^ m3; errs += golay_23_decode(v3); u3 = v3; uint32_t m4 = pngen15(pn); uint16_t v4 = extract(buf, 92, 107) ^ m4; errs += hamming_15_decode(v4); u4 = v4; uint32_t m5 = pngen15(pn); uint16_t v5 = extract(buf, 107, 122) ^ m5; errs += hamming_15_decode(v5); u5 = v5; uint32_t m6 = pngen15(pn); uint16_t v6 = extract(buf, 122, 137) ^ m6; errs += hamming_15_decode(v6); u6 = v6; u7 = extract(buf, 137, 144); }