summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-08-28 22:38:41 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-08-28 22:38:41 +0000
commit4fc717a4c19a1fe0349977d7b9c86561c5a5cf2d (patch)
treeeb6113c7491072f7b5136e24775737764e2cdede
parent65c2c58b3aa26164bd919665e4d710efa2fa7c79 (diff)
downloadrockbox-4fc717a4c19a1fe0349977d7b9c86561c5a5cf2d.tar.gz
rockbox-4fc717a4c19a1fe0349977d7b9c86561c5a5cf2d.zip
Added FS#2939 Encoder Codec Interface + Codecs by Antonius Hellmann with additional FM Recording support and my modifications
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10789 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs.c25
-rw-r--r--apps/codecs.h24
-rw-r--r--apps/codecs/Makefile3
-rw-r--r--apps/codecs/SOURCES8
-rw-r--r--apps/codecs/mp3_enc.c2860
-rw-r--r--apps/codecs/wav_enc.c172
-rw-r--r--apps/codecs/wavpack_enc.c230
-rw-r--r--apps/filetree.c5
-rw-r--r--apps/lang/english.lang17
-rw-r--r--apps/main_menu.c26
-rw-r--r--apps/playback.c215
-rw-r--r--apps/playback.h5
-rw-r--r--apps/recorder/radio.c380
-rw-r--r--apps/recorder/radio.h12
-rw-r--r--apps/recorder/recording.c578
-rw-r--r--apps/recorder/recording.h27
-rw-r--r--apps/settings.c29
-rw-r--r--apps/settings.h1
-rw-r--r--apps/sound_menu.c78
-rw-r--r--apps/status.c4
-rw-r--r--apps/talk.c2
-rw-r--r--apps/talk.h1
-rw-r--r--apps/tree.c2
-rw-r--r--firmware/drivers/power.c2
-rw-r--r--firmware/export/audio.h46
-rw-r--r--firmware/export/config-h100.h3
-rw-r--r--firmware/export/config-h120.h3
-rw-r--r--firmware/export/config-h300.h3
-rw-r--r--firmware/export/config-iaudiox5.h4
-rw-r--r--firmware/export/fmradio.h16
-rw-r--r--firmware/export/id3.h42
-rw-r--r--firmware/export/pcm_record.h14
-rw-r--r--firmware/id3.c71
-rw-r--r--firmware/mpeg.c2
-rw-r--r--firmware/pcm_record.c736
-rw-r--r--firmware/powermgmt.c3
36 files changed, 4796 insertions, 853 deletions
diff --git a/apps/codecs.c b/apps/codecs.c
index c0b4aadeb4..addb8b5e40 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -40,6 +40,7 @@
#include "mpeg.h"
#include "buffer.h"
#include "mp3_playback.h"
+#include "playback.h"
#include "backlight.h"
#include "ata.h"
#include "talk.h"
@@ -208,11 +209,28 @@ struct codec_api ci = {
profile_func_exit,
#endif
+#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
+ false,
+ enc_get_inputs,
+ enc_set_parameters,
+ enc_alloc_chunk,
+ enc_free_chunk,
+ enc_wavbuf_near_empty,
+ enc_get_wav_data,
+ &enc_set_header_callback,
+#endif
+
/* new stuff at the end, sort into place next time
the API gets incompatible */
};
+void codec_get_full_path(char *path, const char *codec_fn)
+{
+ /* Create full codec path */
+ snprintf(path, MAX_PATH-1, ROCKBOX_DIR CODECS_DIR "/%s", codec_fn);
+}
+
int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
struct codec_api *api)
{
@@ -277,15 +295,18 @@ int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
int codec_load_file(const char *plugin, struct codec_api *api)
{
char msgbuf[80];
+ char path[MAX_PATH];
int fd;
int rc;
+
+ codec_get_full_path(path, plugin);
/* zero out codec buffer to ensure a properly zeroed bss area */
memset(codecbuf, 0, CODEC_SIZE);
- fd = open(plugin, O_RDONLY);
+ fd = open(path, O_RDONLY);
if (fd < 0) {
- snprintf(msgbuf, sizeof(msgbuf)-1, "Couldn't load codec: %s", plugin);
+ snprintf(msgbuf, sizeof(msgbuf)-1, "Couldn't load codec: %s", path);
logf("Codec load error:%d", fd);
gui_syncsplash(HZ*2, true, msgbuf);
return fd;
diff --git a/apps/codecs.h b/apps/codecs.h
index 9ef67c4948..dde376d73c 100644
--- a/apps/codecs.h
+++ b/apps/codecs.h
@@ -46,6 +46,9 @@
#include "profile.h"
#endif
#if (CONFIG_CODEC == SWCODEC)
+#if !defined(SIMULATOR)
+#include "pcm_record.h"
+#endif
#include "dsp.h"
#include "playback.h"
#endif
@@ -84,7 +87,7 @@
#define CODEC_MAGIC 0x52434F44 /* RCOD */
/* increase this every time the api struct changes */
-#define CODEC_API_VERSION 8
+#define CODEC_API_VERSION 9
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
@@ -284,6 +287,21 @@ struct codec_api {
void (*profile_func_enter)(void *this_fn, void *call_site);
void (*profile_func_exit)(void *this_fn, void *call_site);
#endif
+
+#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
+ bool enc_codec_loaded;
+ void (*enc_get_inputs)(int *buffer_size,
+ int *channels, int *quality);
+ void (*enc_set_parameters)(int chunk_size, int num_chunks,
+ int samp_per_chunk, char *head_ptr, int head_size,
+ int enc_id);
+ unsigned int* (*enc_alloc_chunk)(void);
+ void (*enc_free_chunk)(void);
+ int (*enc_wavbuf_near_empty)(void);
+ char* (*enc_get_wav_data)(int size);
+ void (**enc_set_header_callback)(void *head_buffer,
+ int head_size, int num_samples, bool is_file_header);
+#endif
/* new stuff at the end, sort into place next time
the API gets incompatible */
@@ -317,6 +335,10 @@ extern unsigned char plugin_end_addr[];
#endif
#endif
+/* create full codec path from filenames in audio_formats[]
+ assumes buffer size is MAX_PATH */
+void codec_get_full_path(char *path, const char *codec_fn);
+
/* defined by the codec loader (codec.c) */
int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
struct codec_api *api);
diff --git a/apps/codecs/Makefile b/apps/codecs/Makefile
index e365698625..6e4663be41 100644
--- a/apps/codecs/Makefile
+++ b/apps/codecs/Makefile
@@ -58,6 +58,9 @@ $(OBJDIR)/wavpack.elf : $(OBJDIR)/wavpack.o $(BUILDDIR)/libwavpack.a
$(OBJDIR)/alac.elf : $(OBJDIR)/alac.o $(BUILDDIR)/libalac.a $(BUILDDIR)/libm4a.a
$(OBJDIR)/aac.elf : $(OBJDIR)/aac.o $(BUILDDIR)/libfaad.a $(BUILDDIR)/libm4a.a
$(OBJDIR)/shorten.elf : $(OBJDIR)/shorten.o $(BUILDDIR)/libffmpegFLAC.a
+$(OBJDIR)/mp3_enc.elf: $(OBJDIR)/mp3_enc.o
+$(OBJDIR)/wav_enc.elf: $(OBJDIR)/wav_enc.o
+$(OBJDIR)/wavpack_enc.elf: $(OBJDIR)/wavpack_enc.o $(BUILDDIR)/libwavpack.a
$(OBJDIR)/%.elf :
@echo "LD $(notdir $@)"
diff --git a/apps/codecs/SOURCES b/apps/codecs/SOURCES
index 3537457313..3bd09b4dae 100644
--- a/apps/codecs/SOURCES
+++ b/apps/codecs/SOURCES
@@ -1,4 +1,5 @@
#if CONFIG_CODEC == SWCODEC
+/* decoders */
vorbis.c
mpa.c
flac.c
@@ -13,4 +14,11 @@ aac.c
shorten.c
aiff.c
sid.c
+#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
+/* encoders */
+mp3_enc.c
+wav_enc.c
+wavpack_enc.c
#endif
+#endif
+
diff --git a/apps/codecs/mp3_enc.c b/apps/codecs/mp3_enc.c
new file mode 100644
index 0000000000..1cd84988aa
--- /dev/null
+++ b/apps/codecs/mp3_enc.c
@@ -0,0 +1,2860 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 Antonius Hellmann
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+// Shine is an MP3 encoder
+// Copyright (C) 1999-2000 Gabriel Bouvigne
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+
+#include "codeclib.h"
+
+#ifndef SIMULATOR
+
+CODEC_HEADER
+
+#define SAMP_PER_FRAME 1152
+#define SAMP_PER_FRAME2 576
+#define HAN_SIZE 512
+#define SBLIMIT 32
+#define WAVE_RIFF_PCM 0
+#define MAX_CHANNELS 2
+#define MAX_GRANULES 2
+#define HTN 34
+
+typedef unsigned long uint32;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+
+enum e_byte_order { order_unknown, order_bigEndian, order_littleEndian };
+
+#define memcpy ci->memcpy
+#define memset ci->memset
+
+typedef struct {
+ int type; /* 0=(22.05,24,16kHz) 1=(44.1,48,32kHz) */
+ int mode; /* 0=stereo, 1=jstereo, 2=dual, 3=mono */
+ int bitrate;
+ int padding;
+ long bits_per_frame;
+ long bitrate_index;
+ int smprate_index;
+} mpeg_t;
+
+/* Side information */
+typedef struct {
+ unsigned part2_3_length;
+ unsigned big_values;
+ int count1;
+ unsigned global_gain;
+ unsigned table_select[4];
+ unsigned region0_count;
+ unsigned region1_count;
+ unsigned address1;
+ unsigned address2;
+ unsigned address3;
+ long quantizerStepSize;
+} side_info_t;
+
+typedef struct {
+ enum e_byte_order byte_order;
+ side_info_t cod_info[2][2];
+ long frac_per_frame;
+ long byte_per_frame;
+ long slot_lag;
+ int sideinfo_len;
+ int mean_bits;
+ int channels;
+ long samplerate;
+ mpeg_t mpg;
+} config_t;
+
+typedef struct {
+ int bitpos; /* current bitpos for writing */
+ uint32 bbuf[263];
+} BF_Data;
+
+struct huffcodetab {
+ int xlen; /*max. x-index+ */
+ int ylen; /*max. y-index+ */
+ int linbits; /*number of linbits */
+ int linmax; /*max number stored in linbits */
+ const uint16 *table; /*pointer to array[xlen][ylen] */
+ const uint8 *hlen; /*pointer to array[xlen][ylen] */
+};
+
+/* !!!!!!!! start of IRAM area: do not insert before x_int1 array !!!!!!!!! */
+short x_int0 [HAN_SIZE] IBSS_ATTR; // 1024 Bytes
+int mdct_freq [2][2][SAMP_PER_FRAME2] IBSS_ATTR; // 9216 Bytes
+short x_int1 [HAN_SIZE] IBSS_ATTR; // 1024 Bytes
+/* !!!!!!!!!!!!!!!!!! here you may insert other data !!!!!!!!!!!!!!!!!!!!!! */
+uint8 int2idx [5000] IBSS_ATTR; // 5000 Bytes
+uint16 enc_data [2][2][SAMP_PER_FRAME2] IBSS_ATTR; // 4608 Bytes
+short y_int [64] IBSS_ATTR; // 256 Bytes
+int scalefac [23] IBSS_ATTR; // 92 Bytes
+int mdct_in [36] IBSS_ATTR; // 144 Bytes
+int sb_sample [2][3][18][SBLIMIT] IBSS_ATTR; // 13824 Bytes
+BF_Data CodedData IBSS_ATTR; // 1040 Bytes
+int ca_int [8] IBSS_ATTR; // 32 Bytes
+int cs_int [8] IBSS_ATTR; // 32 Bytes
+int win_int [18][36] IBSS_ATTR; // 2592 Bytes
+short filter_int [SBLIMIT][64] IBSS_ATTR; // 8192 Bytes
+short enwindow_int[512] IBSS_ATTR; // 1024 Bytes
+uint8 ht_count1 [2][2][16] IBSS_ATTR; // 64 Bytes
+uint16 t1HB [ 4] IBSS_ATTR; // Bytes
+uint16 t2HB [ 9] IBSS_ATTR; // Bytes
+uint16 t3HB [ 9] IBSS_ATTR; // Bytes
+uint16 t5HB [ 16] IBSS_ATTR; // Bytes
+uint16 t6HB [ 16] IBSS_ATTR; // Bytes
+uint16 t7HB [ 36] IBSS_ATTR; // Bytes
+uint16 t8HB [ 36] IBSS_ATTR; // Bytes
+uint16 t9HB [ 36] IBSS_ATTR; // Bytes
+uint16 t10HB [ 64] IBSS_ATTR; // Bytes
+uint16 t11HB [ 64] IBSS_ATTR; // Bytes
+uint16 t12HB [ 64] IBSS_ATTR; // Bytes
+uint16 t13HB [256] IBSS_ATTR; // Bytes
+uint16 t15HB [256] IBSS_ATTR; // Bytes
+uint16 t16HB [256] IBSS_ATTR; // Bytes
+uint16 t24HB [256] IBSS_ATTR; // Bytes
+uint8 t1l [ 4] IBSS_ATTR; // Bytes
+uint8 t2l [ 9] IBSS_ATTR; // Bytes
+uint8 t3l [ 9] IBSS_ATTR; // Bytes
+uint8 t5l [ 16] IBSS_ATTR; // Bytes
+uint8 t6l [ 16] IBSS_ATTR; // Bytes
+uint8 t7l [ 36] IBSS_ATTR; // Bytes
+uint8 t8l [ 36] IBSS_ATTR; // Bytes
+uint8 t9l [ 36] IBSS_ATTR; // Bytes
+uint8 t10l [ 64] IBSS_ATTR; // Bytes
+uint8 t11l [ 64] IBSS_ATTR; // Bytes
+uint8 t12l [ 64] IBSS_ATTR; // Bytes
+uint8 t13l [256] IBSS_ATTR; // Bytes
+uint8 t15l [256] IBSS_ATTR; // Bytes
+uint8 t16l [256] IBSS_ATTR; // Bytes
+uint8 t24l [256] IBSS_ATTR; // Bytes
+struct huffcodetab ht [HTN] IBSS_ATTR; // Bytes
+
+static struct codec_api *ci;
+static int enc_channels;
+static short *x_int[2];
+static config_t cfg;
+
+static const uint8 ht_count1_const[2][2][16] =
+{ { { 1, 5, 4, 5, 6, 5,4,4,7,3,6,0,7,2,3, 1 }, /* table0 */
+ { 1, 5, 5, 7, 5, 8,7,9,5,7,7,9,7,9,9,10 } }, /* hleng0 */
+ { {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1, 0 }, /* table1 */
+ { 4, 5, 5, 6, 5, 6,6,7,5,6,6,7,6,7,7, 8 } } }; /* hleng1 */
+
+static const uint16 t1HB_const[4] = {1,1,1,0};
+static const uint16 t2HB_const[9] = {1,2,1,3,1,1,3,2,0};
+static const uint16 t3HB_const[9] = {3,2,1,1,1,1,3,2,0};
+static const uint16 t5HB_const[16] = {1,2,6,5,3,1,4,4,7,5,7,1,6,1,1,0};
+static const uint16 t6HB_const[16] = {7,3,5,1,6,2,3,2,5,4,4,1,3,3,2,0};
+static const uint16 t7HB_const[36] = {1,2,10,19,16,10,3,3,7,10,5,3,11,4,13,17,8,4,12,11,18,15,11,2,7,6,9,14,3,1,6,4,5,3,2,0};
+static const uint16 t8HB_const[36] = {3,4,6,18,12,5,5,1,2,16,9,3,7,3,5,14,7,3,19,17,15,13,10,4,13,5,8,11,5,1,12,4,4,1,1,0};
+static const uint16 t9HB_const[36] = {7,5,9,14,15,7,6,4,5,5,6,7,7,6,8,8,8,5,15,6,9,10,5,1,11,7,9,6,4,1,14,4,6,2,6,0};
+static const uint16 t10HB_const[64] = {1,2,10,23,35,30,12,17,3,3,8,12,18,21,12,7,11,9,15,21,32,40,19,6,14,13,22,34,46,23,18,
+ 7,20,19,33,47,27,22,9,3,31,22,41,26,21,20,5,3,14,13,10,11,16,6,5,1,9,8,7,8,4 ,4,2,0};
+static const uint16 t11HB_const[64] = {3,4,10,24,34,33,21,15,5,3,4,10,32,17,11,10,11,7,13,18,30,31,20,5,25,11,19,59,27,18,12,
+ 5,35,33,31,58,30,16,7,5,28,26,32,19,17,15,8,14,14,12,9,13,14,9,4,1,11,4,6,6,6,3,2,0};
+static const uint16 t12HB_const[64] = {9,6,16,33,41,39,38,26,7,5,6,9,23,16,26,11,17,7,11,14,21,30,10,7,17,10,15,12,18,28,14,
+ 5,32,13,22,19,18,16,9,5,40,17,31,29,17,13,4,2,27,12,11,15,10,7,4,1,27,12,8,12,6,3,1,0};
+static const uint16 t13HB_const[256] = {1,5,14,21,34,51,46,71,42,52,68,52,67,44,43,19,3,4,12,19,31,26,44,33,31,24,32,
+ 24,31,35,22,14,15,13,23,36,59,49,77,65,29,40,30,40,27,33,42,16,22,20,37,61,56,
+ 79,73,64,43,76,56,37,26,31,25,14,35,16,60,57,97,75,114,91,54,73,55,41,48,53,
+ 23,24,58,27,50,96,76,70,93,84,77,58,79,29,74,49,41,17,47,45,78,74,115,94,90,
+ 79,69,83,71,50,59,38,36,15,72,34,56,95,92,85,91,90,86,73,77,65,51,44,43,42,43,
+ 20,30,44,55,78,72,87,78,61,46,54,37,30,20,16,53,25,41,37,44,59,54,81,66,76,57,
+ 54,37,18,39,11,35,33,31,57,42,82,72,80,47,58,55,21,22,26,38,22,53,25,23,38,70,
+ 60,51,36,55,26,34,23,27,14,9,7,34,32,28,39,49,75,30,52,48,40,52,28,18,17,9,5,
+ 45,21,34,64,56,50,49,45,31,19,12,15,10,7,6,3,48,23,20,39,36,35,53,21,16,23,13,
+ 10,6,1,4,2,16,15,17,27,25,20,29,11,17,12,16,8,1,1,0,1};
+static const uint16 t15HB_const[256] = {7,12,18,53,47,76,124,108,89,123,108,119,107,81,122,63,13,5,16,27,46,36,61,51,
+ 42,70,52,83,65,41,59,36,19,17,15,24,41,34,59,48,40,64,50,78,62,80,56,33,29,28,
+ 25,43,39,63,55,93,76,59,93,72,54,75,50,29,52,22,42,40,67,57,95,79,72,57,89,69,
+ 49,66,46,27,77,37,35,66,58,52,91,74,62,48,79,63,90,62,40,38,125,32,60,56,50,
+ 92,78,65,55,87,71,51,73,51,70,30,109,53,49,94,88,75,66,122,91,73,56,42,64,44,
+ 21,25,90,43,41,77,73,63,56,92,77,66,47,67,48,53,36,20,71,34,67,60,58,49,88,76,
+ 67,106,71,54,38,39,23,15,109,53,51,47,90,82,58,57,48,72,57,41,23,27,62,9,86,
+ 42,40,37,70,64,52,43,70,55,42,25,29,18,11,11,118,68,30,55,50,46,74,65,49,39,
+ 24,16,22,13,14,7,91,44,39,38,34,63,52,45,31,52,28,19,14,8,9,3,123,60,58,53,47,
+ 43,32,22,37,24,17,12,15,10,2,1,71,37,34,30,28,20,17,26,21,16,10,6,8,6,2,0};
+static const uint16 t16HB_const[256] = {1,5,14,44,74,63,110,93,172,149,138,242,225,195,376,17,3,4,12,20,35,62,53,47,
+ 83,75,68,119,201,107,207,9,15,13,23,38,67,58,103,90,161,72,127,117,110,209,
+ 206,16,45,21,39,69,64,114,99,87,158,140,252,212,199,387,365,26,75,36,68,65,
+ 115,101,179,164,155,264,246,226,395,382,362,9,66,30,59,56,102,185,173,265,142,
+ 253,232,400,388,378,445,16,111,54,52,100,184,178,160,133,257,244,228,217,385,
+ 366,715,10,98,48,91,88,165,157,148,261,248,407,397,372,380,889,884,8,85,84,81,
+ 159,156,143,260,249,427,401,392,383,727,713,708,7,154,76,73,141,131,256,245,
+ 426,406,394,384,735,359,710,352,11,139,129,67,125,247,233,229,219,393,743,737,
+ 720,885,882,439,4,243,120,118,115,227,223,396,746,742,736,721,712,706,223,436,
+ 6,202,224,222,218,216,389,386,381,364,888,443,707,440,437,1728,4,747,211,210,
+ 208,370,379,734,723,714,1735,883,877,876,3459,865,2,377,369,102,187,726,722,
+ 358,711,709,866,1734,871,3458,870,434,0,12,10,7,11,10,17,11,9,13,12,10,7,5,3,1,3};
+static const uint16 t24HB_const[256] = {15,13,46,80,146,262,248,434,426,669,653,649,621,517,1032,88,14,12,21,38,71,
+ 130,122,216,209,198,327,345,319,297,279,42,47,22,41,74,68,128,120,221,207,194,
+ 182,340,315,295,541,18,81,39,75,70,134,125,116,220,204,190,178,325,311,293,
+ 271,16,147,72,69,135,127,118,112,210,200,188,352,323,306,285,540,14,263,66,
+ 129,126,119,114,214,202,192,180,341,317,301,281,262,12,249,123,121,117,113,
+ 215,206,195,185,347,330,308,291,272,520,10,435,115,111,109,211,203,196,187,
+ 353,332,313,298,283,531,381,17,427,212,208,205,201,193,186,177,169,320,303,
+ 286,268,514,377,16,335,199,197,191,189,181,174,333,321,305,289,275,521,379,
+ 371,11,668,184,183,179,175,344,331,314,304,290,277,530,383,373,366,10,652,346,
+ 171,168,164,318,309,299,287,276,263,513,375,368,362,6,648,322,316,312,307,302,
+ 292,284,269,261,512,376,370,364,359,4,620,300,296,294,288,282,273,266,515,380,
+ 374,369,365,361,357,2,1033,280,278,274,267,264,259,382,378,372,367,363,360,
+ 358,356,0,43,20,19,17,15,13,11,9,7,6,4,7,5,3,1,3};
+
+static const uint8 t1l_const[4] = {1,3,2,3};
+static const uint8 t2l_const[9] = {1,3,6,3,3,5,5,5,6};
+static const uint8 t3l_const[9] = {2,2,6,3,2,5,5,5,6};
+static const uint8 t5l_const[16] = {1,3,6,7,3,3,6,7,6,6,7,8,7,6,7,8};
+static const uint8 t6l_const[16] = {3,3,5,7,3,2,4,5,4,4,5,6,6,5,6,7};
+static const uint8 t7l_const[36] = {1,3,6,8,8,9,3,4,6,7,7,8,6,5,7,8,8,9,7,7,8,9,9,9,7,7,8,9,9,10,8,8,9,10,10,10};
+static const uint8 t8l_const[36] = {2,3,6,8,8,9,3,2,4,8,8,8,6,4,6,8,8,9,8,8,8,9,9,10,8,7,8,9,10,10,9,8,9,9,11,11};
+static const uint8 t9l_const[36] = {3,3,5,6,8,9,3,3,4,5,6,8,4,4,5,6,7,8,6,5,6,7,7,8,7,6,7,7,8,9,8,7,8,8,9,9};
+static const uint8 t10l_const[64] = {1,3,6,8,9,9,9,10,3,4,6,7,8,9,8,8,6,6,7,8,9,10,9,9,7,7,8,9,10,10,9,10,8,8,9,10,
+ 10,10,10,10,9,9,10,10,11,11,10,11,8,8,9,10,10,10,11,11,9,8,9,10,10,11,11,11};
+static const uint8 t11l_const[64] = {2,3,5,7,8,9,8,9,3,3,4,6,8,8,7,8,5,5,6,7,8,9,8,8,7,6,7,9,8,10,8,9,8,8,8,9,9,10,
+ 9,10,8,8,9,10,10,11,10,11,8,7,7,8,9,10,10,10,8,7,8,9,10,10,10,10};
+static const uint8 t12l_const[64] = {4,3,5,7,8,9,9,9,3,3,4,5,7,7,8,8,5,4,5,6,7,8,7,8,6,5,6,6,7,8,8,8,7,6,7,7,8,
+ 8,8,9,8,7,8,8,8,9,8,9,8,7,7,8,8,9,9,10,9,8,8,9,9,9,9,10};
+static const uint8 t13l_const[256] = {1,4,6,7,8,9,9,10,9,10,11,11,12,12,13,13,3,4,6,7,8,8,9,9,9,9,10,10,11,12,12,12,
+ 6,6,7,8,9,9,10,10,9,10,10,11,11,12,13,13,7,7,8,9,9,10,10,10,10,11,11,11,11,12,
+ 13,13,8,7,9,9,10,10,11,11,10,11,11,12,12,13,13,14,9,8,9,10,10,10,11,11,11,11,
+ 12,11,13,13,14,14,9,9,10,10,11,11,11,11,11,12,12,12,13,13,14,14,10,9,10,11,11,
+ 11,12,12,12,12,13,13,13,14,16,16,9,8,9,10,10,11,11,12,12,12,12,13,13,14,15,15,
+ 10,9,10,10,11,11,11,13,12,13,13,14,14,14,16,15,10,10,10,11,11,12,12,13,12,13,
+ 14,13,14,15,16,17,11,10,10,11,12,12,12,12,13,13,13,14,15,15,15,16,11,11,11,12,
+ 12,13,12,13,14,14,15,15,15,16,16,16,12,11,12,13,13,13,14,14,14,14,14,15,16,15,
+ 16,16,13,12,12,13,13,13,15,14,14,17,15,15,15,17,16,16,12,12,13,14,14,14,15,14,
+ 15,15,16,16,19,18,19,16};
+static const uint8 t15l_const[256] = {3,4,5,7,7,8,9,9,9,10,10,11,11,11,12,13,4,3,5,6,7,7,8,8,8,9,9,10,10,10,11,11,5,
+ 5,5,6,7,7,8,8,8,9,9,10,10,11,11,11,6,6,6,7,7,8,8,9,9,9,10,10,10,11,11,11,7,6,7,
+ 7,8,8,9,9,9,9,10,10,10,11,11,11,8,7,7,8,8,8,9,9,9,9,10,10,11,11,11,12,9,7,8,8,
+ 8,9,9,9,9,10,10,10,11,11,12,12,9,8,8,9,9,9,9,10,10,10,10,10,11,11,11,12,9,8,8,
+ 9,9,9,9,10,10,10,10,11,11,12,12,12,9,8,9,9,9,9,10,10,10,11,11,11,11,12,12,12,10,
+ 9,9,9,10,10,10,10,10,11,11,11,11,12,13,12,10,9,9,9,10,10,10,10,11,11,11,11,12,
+ 12,12,13,11,10,9,10,10,10,11,11,11,11,11,11,12,12,13,13,11,10,10,10,10,11,11,11,
+ 11,12,12,12,12,12,13,13,12,11,11,11,11,11,11,11,12,12,12,12,13,13,12,13,12,11,
+ 11,11,11,11,11,12,12,12,12,12,13,13,13,13};
+static const uint8 t16l_const[256] = {1,4,6,8,9,9,10,10,11,11,11,12,12,12,13,9,3,4,6,7,8,9,9,9,10,10,10,11,12,11,12,
+ 8,6,6,7,8,9,9,10,10,11,10,11,11,11,12,12,9,8,7,8,9,9,10,10,10,11,11,12,12,12,
+ 13,13,10,9,8,9,9,10,10,11,11,11,12,12,12,13,13,13,9,9,8,9,9,10,11,11,12,11,12,
+ 12,13,13,13,14,10,10,9,9,10,11,11,11,11,12,12,12,12,13,13,14,10,10,9,10,10,11,
+ 11,11,12,12,13,13,13,13,15,15,10,10,10,10,11,11,11,12,12,13,13,13,13,14,14,14,
+ 10,11,10,10,11,11,12,12,13,13,13,13,14,13,14,13,11,11,11,10,11,12,12,12,12,13,
+ 14,14,14,15,15,14,10,12,11,11,11,12,12,13,14,14,14,14,14,14,13,14,11,12,12,12,
+ 12,12,13,13,13,13,15,14,14,14,14,16,11,14,12,12,12,13,13,14,14,14,16,15,15,15,
+ 17,15,11,13,13,11,12,14,14,13,14,14,15,16,15,17,15,14,11,9,8,8,9,9,10,10,10,11,
+ 11,11,11,11,11,11,8};
+static const uint8 t24l_const[256] = {4,4,6,7,8,9,9,10,10,11,11,11,11,11,12,9,4,4,5,6,7,8,8,9,9,9,10,10,10,10,10,8,6,
+ 5,6,7,7,8,8,9,9,9,9,10,10,10,11,7,7,6,7,7,8,8,8,9,9,9,9,10,10,10,10,7,8,7,7,8,
+ 8,8,8,9,9,9,10,10,10,10,11,7,9,7,8,8,8,8,9,9,9,9,10,10,10,10,10,7,9,8,8,8,8,9,
+ 9,9,9,10,10,10,10,10,11,7,10,8,8,8,9,9,9,9,10,10,10,10,10,11,11,8,10,9,9,9,9,9,
+ 9,9,9,10,10,10,10,11,11,8,10,9,9,9,9,9,9,10,10,10,10,10,11,11,11,8,11,9,9,9,9,
+ 10,10,10,10,10,10,11,11,11,11,8,11,10,9,9,9,10,10,10,10,10,10,11,11,11,11,8,11,
+ 10,10,10,10,10,10,10,10,10,11,11,11,11,11,8,11,10,10,10,10,10,10,10,11,11,11,11,
+ 11,11,11,8,12,10,10,10,10,10,10,11,11,11,11,11,11,11,11,8,8,7,7,7,7,7,7,7,7,7,
+ 7,8,8,8,8,4};
+
+static const struct huffcodetab ht_const[HTN] =
+{
+{ 0, 0, 0, 0, NULL, NULL},
+{ 2, 2, 0, 0, t1HB, t1l},
+{ 3, 3, 0, 0, t2HB, t2l},
+{ 3, 3, 0, 0, t3HB, t3l},
+{ 0, 0, 0, 0, NULL, NULL},// Apparently not used
+{ 4, 4, 0, 0, t5HB, t5l},
+{ 4, 4, 0, 0, t6HB, t6l},
+{ 6, 6, 0, 0, t7HB, t7l},
+{ 6, 6, 0, 0, t8HB, t8l},
+{ 6, 6, 0, 0, t9HB, t9l},
+{ 8, 8, 0, 0,t10HB, t10l},
+{ 8, 8, 0, 0,t11HB, t11l},
+{ 8, 8, 0, 0,t12HB, t12l},
+{16,16, 0, 0,t13HB, t13l},
+{ 0, 0, 0, 0, NULL, NULL},// Apparently not used
+{16,16, 0, 0,t15HB, t15l},
+{16,16, 1, 1,t16HB, t16l},
+{16,16, 2, 3,t16HB, t16l},
+{16,16, 3, 7,t16HB, t16l},
+{16,16, 4, 15,t16HB, t16l},
+{16,16, 6, 63,t16HB, t16l},
+{16,16, 8, 255,t16HB, t16l},
+{16,16,10,1023,t16HB, t16l},
+{16,16,13,8191,t16HB, t16l},
+{16,16, 4, 15,t24HB, t24l},
+{16,16, 5, 31,t24HB, t24l},
+{16,16, 6, 63,t24HB, t24l},
+{16,16, 7, 127,t24HB, t24l},
+{16,16, 8, 255,t24HB, t24l},
+{16,16, 9, 511,t24HB, t24l},
+{16,16,11,2047,t24HB, t24l},
+{16,16,13,8191,t24HB, t24l} };
+
+static const struct
+{
+ unsigned region0_count;
+ unsigned region1_count;
+} subdv_table[23] =
+{ {0, 0}, /* 0 bands */
+ {0, 0}, /* 1 bands */
+ {0, 0}, /* 2 bands */
+ {0, 0}, /* 3 bands */
+ {0, 0}, /* 4 bands */
+ {0, 1}, /* 5 bands */
+ {1, 1}, /* 6 bands */
+ {1, 1}, /* 7 bands */
+ {1, 2}, /* 8 bands */
+ {2, 2}, /* 9 bands */
+ {2, 3}, /* 10 bands */
+ {2, 3}, /* 11 bands */
+ {3, 4}, /* 12 bands */
+ {3, 4}, /* 13 bands */
+ {3, 4}, /* 14 bands */
+ {4, 5}, /* 15 bands */
+ {4, 5}, /* 16 bands */
+ {4, 6}, /* 17 bands */
+ {5, 6}, /* 18 bands */
+ {5, 6}, /* 19 bands */
+ {5, 7}, /* 20 bands */
+ {6, 7}, /* 21 bands */
+ {6, 7}, /* 22 bands */
+};
+
+/* This is table B.9: coefficients for aliasing reduction */
+static const int ca_int_const[8] = {0xffffbe25,0xffffc39e,0xffffd7e3,0xffffe8b7,0xfffff3e5,0xfffffac2,0xfffffe2f,0xffffff87};
+static const int cs_int_const[8] = {0x00006dc2,0x000070dd,0x0000798d,0x00007ddd,0x00007f6d,0x00007fe4,0x00007ffd,0x00008000};
+static const int win_int_const[18][36] = {
+{ 0x0000006b,0x00000121,0x000001a7,0x000001f9,0x00000215,0x000001f9,0x000001a7,0x00000121,0x0000006b,0xffffff8b,0xfffffe87,0xfffffd68,0xfffffc35,0xfffffaf9,0xfffff9bd,0xfffff88b,0xfffff76b,0xfffff667,0xfffff587,0xfffff4d1,0xfffff44b,0xfffff3f8,0xfffff3dd,0xfffff3f8,0xfffff44b,0xfffff4d1,0xfffff587,0xfffff667,0xfffff76b,0xfffff88b,0xfffff9bd,0xfffffaf9,0xfffffc35,0xfffffd68,0xfffffe87,0xffffff8b,},
+{ 0xffffff83,0xfffffe49,0xfffffcf3,0xfffffbc3,0xfffffaf9,0xfffffacb,0xfffffb5a,0xfffffcb0,0xfffffebf,0x0000015e,0x00000451,0x0000074d,0x00000a02,0x00000c23,0x00000d72,0x00000dc4,0x00000d06,0x00000b45,0x000008a6,0x00000565,0x000001cf,0xfffffe3b,0xfffffaf9,0xfffff853,0xfffff67c,0xfffff594,0xfffff59b,0xfffff67a,0xfffff801,0xfffff9f1,0xfffffc01,0xfffffdeb,0xffffff72,0x00000066,0x000000b5,0x00000060,},
+{ 0xffffffab,0xffffffc2,0x000000ec,0x000002e3,0x00000507,0x0000068f,0x000006c7,0x00000545,0x00000214,0xfffffdbc,0xfffff922,0xfffff55d,0xfffff366,0xfffff3dd,0xfffff6d7,0xfffffbd4,0x000001d7,0x000007a2,0x00000bfb,0x00000dfa,0x00000d3e,0x00000a00,0x00000507,0xffffff74,0xfffffa77,0xfffff70d,0xfffff5c4,0xfffff69f,0xfffff922,0xfffffc79,0xffffffb7,0x00000215,0x00000327,0x000002ef,0x000001d7,0x00000085,},
+{ 0x0000008c,0x000001d7,0x00000244,0x000000ec,0xfffffdeb,0xfffffa77,0xfffff85e,0xfffff922,0xfffffd1d,0x00000327,0x000008f3,0x00000bfb,0x00000aa3,0x00000507,0xfffffd11,0xfffff5c4,0xfffff206,0xfffff366,0xfffff971,0x000001d7,0x00000961,0x00000d3e,0x00000c23,0x000006c7,0xffffff7b,0xfffff922,0xfffff600,0xfffff6d7,0xfffffabb,0xffffffab,0x00000387,0x00000507,0x0000042c,0x00000214,0x0000003e,0xffffffb7,},
+{ 0x0000003c,0xffffff4b,0xfffffd28,0xfffffc0d,0xfffffdeb,0x00000283,0x0000070f,0x000007ff,0x000003ad,0xfffffbfd,0xfffff594,0xfffff4ec,0xfffffb2d,0x00000507,0x00000c88,0x00000cd4,0x00000565,0xfffffa91,0xfffff2e0,0xfffff2fa,0xfffffab0,0x00000530,0x00000c23,0x00000ba7,0x00000497,0xfffffbaf,0xfffff650,0xfffff720,0xfffffcb0,0x000002ec,0x00000611,0x00000507,0x000001a2,0xfffffed3,0xfffffe49,0xffffff6e,},
+{ 0xffffff69,0xfffffe87,0x00000022,0x0000039b,0x00000507,0x0000016b,0xfffffad7,0xfffff76b,0xfffffb91,0x000004d7,0x00000b2f,0x0000081a,0xfffffd46,0xfffff3dd,0xfffff490,0xffffff65,0x00000b2f,0x00000d8d,0x00000445,0xfffff76b,0xfffff221,0xfffff8b7,0x00000507,0x00000c50,0x000008d7,0xfffffe87,0xfffff6b3,0xfffff77b,0xfffffedf,0x000005a2,0x00000669,0x00000215,0xfffffdb4,0xfffffced,0xfffffedf,0x0000002f,},
+{ 0xffffffde,0x00000179,0x000002ba,0xffffffd1,0xfffffaf9,0xfffffb29,0x0000024c,0x00000895,0x00000529,0xfffffa5e,0xfffff4d1,0xfffffc65,0x0000094d,0x00000c23,0x00000097,0xfffff3b0,0xfffff4d1,0x00000313,0x00000ddf,0x00000895,0xfffff997,0xfffff273,0xfffffaf9,0x00000885,0x00000b70,0x00000179,0xfffff729,0xfffff7e6,0x00000121,0x00000749,0x0000046f,0xfffffdeb,0xfffffbbb,0xfffffe95,0x00000121,0x0000009b,},
+{ 0x0000009d,0x000000b5,0xfffffd8f,0xfffffc9c,0x00000215,0x00000682,0x000000ff,0xfffff801,0xfffffa27,0x00000662,0x00000a6c,0xfffffe70,0xfffff37f,0xfffffaf9,0x00000ac2,0x00000b04,0xfffffa9b,0xfffff1ea,0xfffffe26,0x00000d06,0x00000873,0xfffff7bf,0xfffff3dd,0x000001a5,0x00000be4,0x00000451,0xfffff7af,0xfffff861,0x00000350,0x00000793,0x000000db,0xfffffaf9,0xfffffd66,0x000001df,0x000001b7,0xffffffec,},
+{ 0x00000006,0xfffffe29,0xffffff56,0x00000414,0x00000215,0xfffffa2d,0xfffffbe5,0x000006de,0x0000067d,0xfffff8eb,0xfffff70d,0x00000671,0x00000b30,0xfffffaf9,0xfffff311,0x00000301,0x00000dfa,0xffffff62,0xfffff1cf,0xfffffe29,0x00000d8e,0x00000414,0xfffff3dd,0xfffffa2d,0x00000a1d,0x000006de,0xfffff845,0xfffff8eb,0x00000545,0x00000671,0xfffffcf8,0xfffffaf9,0x00000149,0x00000301,0xffffffc2,0xffffff62,},
+{ 0xffffff62,0x0000003e,0x00000301,0xfffffeb7,0xfffffaf9,0x00000308,0x00000671,0xfffffabb,0xfffff8eb,0x000007bb,0x000006de,0xfffff5e3,0xfffffa2d,0x00000c23,0x00000414,0xfffff272,0xfffffe29,0x00000e31,0xffffff62,0xfffff206,0x00000301,0x00000cef,0xfffffaf9,0xfffff4d0,0x00000671,0x000008f3,0xfffff8eb,0xfffff983,0x000006de,0x0000041b,0xfffffa2d,0xfffffdeb,0x00000414,0x000000aa,0xfffffe29,0xfffffffa,},
+{ 0x00000014,0x000001b7,0xfffffe21,0xfffffd66,0x00000507,0x000000db,0xfffff86d,0x00000350,0x0000079f,0xfffff7af,0xfffffbaf,0x00000be4,0xfffffe5b,0xfffff3dd,0x00000841,0x00000873,0xfffff2fa,0xfffffe26,0x00000e16,0xfffffa9b,0xfffff4fc,0x00000ac2,0x00000507,0xfffff37f,0x00000190,0x00000a6c,0xfffff99e,0xfffffa27,0x000007ff,0x000000ff,0xfffff97e,0x00000215,0x00000364,0xfffffd8f,0xffffff4b,0x0000009d,},
+{ 0x0000009b,0xfffffedf,0xfffffe95,0x00000445,0xfffffdeb,0xfffffb91,0x00000749,0xfffffedf,0xfffff7e6,0x000008d7,0x00000179,0xfffff490,0x00000885,0x00000507,0xfffff273,0x00000669,0x00000895,0xfffff221,0x00000313,0x00000b2f,0xfffff3b0,0xffffff69,0x00000c23,0xfffff6b3,0xfffffc65,0x00000b2f,0xfffffa5e,0xfffffad7,0x00000895,0xfffffdb4,0xfffffb29,0x00000507,0xffffffd1,0xfffffd46,0x00000179,0x00000022,},
+{ 0xffffffd1,0xfffffedf,0x00000313,0xfffffdb4,0xfffffdeb,0x00000669,0xfffffa5e,0xfffffedf,0x00000885,0xfffff6b3,0x00000179,0x000008d7,0xfffff3b0,0x00000507,0x00000749,0xfffff221,0x00000895,0x00000445,0xfffff273,0x00000b2f,0x0000009b,0xfffff490,0x00000c23,0xfffffd46,0xfffff7e6,0x00000b2f,0xfffffb29,0xfffffb91,0x00000895,0xfffffad7,0xfffffe95,0x00000507,0xfffffc65,0x00000022,0x00000179,0xffffff69,},
+{ 0xffffff6e,0x000001b7,0xfffffed3,0xfffffe5e,0x00000507,0xfffff9ef,0x000002ec,0x00000350,0xfffff720,0x000009b0,0xfffffbaf,0xfffffb69,0x00000ba7,0xfffff3dd,0x00000530,0x00000550,0xfffff2fa,0x00000d20,0xfffffa91,0xfffffa9b,0x00000cd4,0xfffff378,0x00000507,0x000004d3,0xfffff4ec,0x00000a6c,0xfffffbfd,0xfffffc53,0x000007ff,0xfffff8f1,0x00000283,0x00000215,0xfffffc0d,0x000002d8,0xffffff4b,0xffffffc4,},
+{ 0x00000049,0x0000003e,0xfffffdec,0x0000042c,0xfffffaf9,0x00000387,0x00000055,0xfffffabb,0x00000929,0xfffff600,0x000006de,0xffffff7b,0xfffff939,0x00000c23,0xfffff2c2,0x00000961,0xfffffe29,0xfffff971,0x00000c9a,0xfffff206,0x00000a3c,0xfffffd11,0xfffffaf9,0x00000aa3,0xfffff405,0x000008f3,0xfffffcd9,0xfffffd1d,0x000006de,0xfffff85e,0x00000589,0xfffffdeb,0xffffff14,0x00000244,0xfffffe29,0x0000008c,},
+{ 0x00000085,0xfffffe29,0x000002ef,0xfffffcd9,0x00000215,0x00000049,0xfffffc79,0x000006de,0xfffff69f,0x00000a3c,0xfffff70d,0x00000589,0xffffff74,0xfffffaf9,0x00000a00,0xfffff2c2,0x00000dfa,0xfffff405,0x000007a2,0xfffffe29,0xfffffbd4,0x00000929,0xfffff3dd,0x00000c9a,0xfffff55d,0x000006de,0xfffffdbc,0xfffffdec,0x00000545,0xfffff939,0x0000068f,0xfffffaf9,0x000002e3,0xffffff14,0xffffffc2,0x00000055,},
+{ 0xffffffa0,0x000000b5,0xffffff9a,0xffffff72,0x00000215,0xfffffc01,0x0000060f,0xfffff801,0x00000986,0xfffff59b,0x00000a6c,0xfffff67c,0x000007ad,0xfffffaf9,0x000001c5,0x000001cf,0xfffffa9b,0x000008a6,0xfffff4bb,0x00000d06,0xfffff23c,0x00000d72,0xfffff3dd,0x00000a02,0xfffff8b3,0x00000451,0xfffffea2,0xfffffebf,0x00000350,0xfffffb5a,0x00000535,0xfffffaf9,0x0000043d,0xfffffcf3,0x000001b7,0xffffff83,},
+{ 0xffffff8b,0x00000179,0xfffffd68,0x000003cb,0xfffffaf9,0x00000643,0xfffff88b,0x00000895,0xfffff667,0x00000a79,0xfffff4d1,0x00000bb5,0xfffff3f8,0x00000c23,0xfffff3f8,0x00000bb5,0xfffff4d1,0x00000a79,0xfffff667,0x00000895,0xfffff88b,0x00000643,0xfffffaf9,0x000003cb,0xfffffd68,0x00000179,0xffffff8b,0xffffff95,0x00000121,0xfffffe59,0x000001f9,0xfffffdeb,0x000001f9,0xfffffe59,0x00000121,0xffffff95,}};
+
+static const short filter_int_const[SBLIMIT][64] = {
+{ 23170, 24279, 25330, 26320, 27246, 28106, 28899, 29622, 30274, 30853, 31357, 31786, 32138, 32413, 32610, 32729, 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, 0, -1607, -3211, -4807, -6392, -7961, -9511,-11038,-12539,-14009,-15446,-16845,-18204,-19519,-20787,-22005, },
+{ -23169,-19519,-15446,-11038, -6392, -1607, 3212, 7962, 12540, 16846, 20788, 24279, 27246, 29622, 31357, 32413, 32767, 32413, 31357, 29622, 27246, 24279, 20788, 16846, 12540, 7962, 3212, -1607, -6392,-11038,-15446,-19519,-23169,-26319,-28898,-30852,-32137,-32728,-32609,-31785,-30273,-28105,-25329,-22005,-18204,-14009, -9511, -4807, 0, 4808, 9512, 14010, 18205, 22006, 25330, 28106, 30274, 31786, 32610, 32729, 32138, 30853, 28899, 26320, },
+{ -23169,-28105,-31356,-32728,-32137,-29621,-25329,-19519,-12539, -4807, 3212, 11039, 18205, 24279, 28899, 31786, 32767, 31786, 28899, 24279, 18205, 11039, 3212, -4807,-12539,-19519,-25329,-29621,-32137,-32728,-31356,-28105,-23169,-16845, -9511, -1607, 6393, 14010, 20788, 26320, 30274, 32413, 32610, 30853, 27246, 22006, 15447, 7962, 0, -7961,-15446,-22005,-27245,-30852,-32609,-32412,-30273,-26319,-20787,-14009, -6392, 1608, 9512, 16846, },
+{ 23170, 14010, 3212, -7961,-18204,-26319,-31356,-32728,-30273,-24278,-15446, -4807, 6393, 16846, 25330, 30853, 32767, 30853, 25330, 16846, 6393, -4807,-15446,-24278,-30273,-32728,-31356,-26319,-18204, -7961, 3212, 14010, 23170, 29622, 32610, 31786, 27246, 19520, 9512, -1607,-12539,-22005,-28898,-32412,-32137,-28105,-20787,-11038, 0, 11039, 20788, 28106, 32138, 32413, 28899, 22006, 12540, 1608, -9511,-19519,-27245,-31785,-32609,-29621, },
+{ 23170, 30853, 32610, 28106, 18205, 4808, -9511,-22005,-30273,-32728,-28898,-19519, -6392, 7962, 20788, 29622, 32767, 29622, 20788, 7962, -6392,-19519,-28898,-32728,-30273,-22005, -9511, 4808, 18205, 28106, 32610, 30853, 23170, 11039, -3211,-16845,-27245,-32412,-31356,-24278,-12539, 1608, 15447, 26320, 32138, 31786, 25330, 14010, 0,-14009,-25329,-31785,-32137,-26319,-15446, -1607, 12540, 24279, 31357, 32413, 27246, 16846, 3212,-11038, },
+{ -23169, -7961, 9512, 24279, 32138, 30853, 20788, 4808,-12539,-26319,-32609,-29621,-18204, -1607, 15447, 28106, 32767, 28106, 15447, -1607,-18204,-29621,-32609,-26319,-12539, 4808, 20788, 30853, 32138, 24279, 9512, -7961,-23169,-31785,-31356,-22005, -6392, 11039, 25330, 32413, 30274, 19520, 3212,-14009,-27245,-32728,-28898,-16845, 0, 16846, 28899, 32729, 27246, 14010, -3211,-19519,-30273,-32412,-25329,-11038, 6393, 22006, 31357, 31786, },
+{ -23169,-32412,-28898,-14009, 6393, 24279, 32610, 28106, 12540, -7961,-25329,-32728,-27245,-11038, 9512, 26320, 32767, 26320, 9512,-11038,-27245,-32728,-25329, -7961, 12540, 28106, 32610, 24279, 6393,-14009,-28898,-32412,-23169, -4807, 15447, 29622, 32138, 22006, 3212,-16845,-30273,-31785,-20787, -1607, 18205, 30853, 31357, 19520, 0,-19519,-31356,-30852,-18204, 1608, 20788, 31786, 30274, 16846, -3211,-22005,-32137,-29621,-15446, 4808, },
+{ 23170, 1608,-20787,-32412,-27245, -7961, 15447, 30853, 30274, 14010, -9511,-28105,-32137,-19519, 3212, 24279, 32767, 24279, 3212,-19519,-32137,-28105, -9511, 14010, 30274, 30853, 15447, -7961,-27245,-32412,-20787, 1608, 23170, 32729, 25330, 4808,-18204,-31785,-28898,-11038, 12540, 29622, 31357, 16846, -6392,-26319,-32609,-22005, 0, 22006, 32610, 26320, 6393,-16845,-31356,-29621,-12539, 11039, 28899, 31786, 18205, -4807,-25329,-32728, },
+{ 23170, 32729, 20788, -4807,-27245,-31785,-15446, 11039, 30274, 29622, 9512,-16845,-32137,-26319, -3211, 22006, 32767, 22006, -3211,-26319,-32137,-16845, 9512, 29622, 30274, 11039,-15446,-31785,-27245, -4807, 20788, 32729, 23170, -1607,-25329,-32412,-18204, 7962, 28899, 30853, 12540,-14009,-31356,-28105, -6392, 19520, 32610, 24279, 0,-24278,-32609,-19519, 6393, 28106, 31357, 14010,-12539,-30852,-28898, -7961, 18205, 32413, 25330, 1608, },
+{ -23169, 4808, 28899, 29622, 6393,-22005,-32609,-16845, 12540, 31786, 25330, -1607,-27245,-30852, -9511, 19520, 32767, 19520, -9511,-30852,-27245, -1607, 25330, 31786, 12540,-16845,-32609,-22005, 6393, 29622, 28899, 4808,-23169,-32412,-15446, 14010, 32138, 24279, -3211,-28105,-30273, -7961, 20788, 32729, 18205,-11038,-31356,-26319, 0, 26320, 31357, 11039,-18204,-32728,-20787, 7962, 30274, 28106, 3212,-24278,-32137,-14009, 15447, 32413, },
+{ -23169,-31785, -9511, 22006, 32138, 11039,-20787,-32412,-12539, 19520, 32610, 14010,-18204,-32728,-15446, 16846, 32767, 16846,-15446,-32728,-18204, 14010, 32610, 19520,-12539,-32412,-20787, 11039, 32138, 22006, -9511,-31785,-23169, 7962, 31357, 24279, -6392,-30852,-25329, 4808, 30274, 26320, -3211,-29621,-27245, 1608, 28899, 28106, 0,-28105,-28898, -1607, 27246, 29622, 3212,-26319,-30273, -4807, 25330, 30853, 6393,-24278,-31356, -7961, },
+{ 23170,-11038,-32609,-16845, 18205, 32413, 9512,-24278,-30273, -1607, 28899, 26320, -6392,-31785,-20787, 14010, 32767, 14010,-20787,-31785, -6392, 26320, 28899, -1607,-30273,-24278, 9512, 32413, 18205,-16845,-32609,-11038, 23170, 30853, 3212,-28105,-27245, 4808, 31357, 22006,-12539,-32728,-15446, 19520, 32138, 7962,-25329,-29621, 0, 29622, 25330, -7961,-32137,-19519, 15447, 32729, 12540,-22005,-31356, -4807, 27246, 28106, -3211,-30852, },
+{ 23170, 29622, -3211,-31785,-18204, 19520, 31357, 1608,-30273,-22005, 15447, 32413, 6393,-28105,-25329, 11039, 32767, 11039,-25329,-28105, 6393, 32413, 15447,-22005,-30273, 1608, 31357, 19520,-18204,-31785, -3211, 29622, 23170,-14009,-32609, -7961, 27246, 26320, -9511,-32728,-12539, 24279, 28899, -4807,-32137,-16845, 20788, 30853, 0,-30852,-20787, 16846, 32138, 4808,-28898,-24278, 12540, 32729, 9512,-26319,-27245, 7962, 32610, 14010, },
+{ -23169, 16846, 31357, -1607,-32137,-14009, 25330, 26320,-12539,-32412, -3211, 30853, 18205,-22005,-28898, 7962, 32767, 7962,-28898,-22005, 18205, 30853, -3211,-32412,-12539, 26320, 25330,-14009,-32137, -1607, 31357, 16846,-23169,-28105, 9512, 32729, 6393,-29621,-20787, 19520, 30274, -4807,-32609,-11038, 27246, 24279,-15446,-31785, 0, 31786, 15447,-24278,-27245, 11039, 32610, 4808,-30273,-19519, 20788, 29622, -6392,-32728, -9511, 28106, },
+{ -23169,-26319, 15447, 30853, -6392,-32728, -3211, 31786, 12540,-28105,-20787, 22006, 27246,-14009,-31356, 4808, 32767, 4808,-31356,-14009, 27246, 22006,-20787,-28105, 12540, 31786, -3211,-32728, -6392, 30853, 15447,-26319,-23169, 19520, 28899,-11038,-32137, 1608, 32610, 7962,-30273,-16845, 25330, 24279,-18204,-29621, 9512, 32413, 0,-32412, -9511, 29622, 18205,-24278,-25329, 16846, 30274, -7961,-32609, -1607, 32138, 11039,-28898,-19519, },
+{ 23170,-22005,-25329, 19520, 27246,-16845,-28898, 14010, 30274,-11038,-31356, 7962, 32138, -4807,-32609, 1608, 32767, 1608,-32609, -4807, 32138, 7962,-31356,-11038, 30274, 14010,-28898,-16845, 27246, 19520,-25329,-22005, 23170, 24279,-20787,-26319, 18205, 28106,-15446,-29621, 12540, 30853, -9511,-31785, 6393, 32413, -3211,-32728, 0, 32729, 3212,-32412, -6392, 31786, 9512,-30852,-12539, 29622, 15447,-28105,-18204, 26320, 20788,-24278, },
+{ 23170, 22006,-25329,-19519, 27246, 16846,-28898,-14009, 30274, 11039,-31356, -7961, 32138, 4808,-32609, -1607, 32767, -1607,-32609, 4808, 32138, -7961,-31356, 11039, 30274,-14009,-28898, 16846, 27246,-19519,-25329, 22006, 23170,-24278,-20787, 26320, 18205,-28105,-15446, 29622, 12540,-30852, -9511, 31786, 6393,-32412, -3211, 32729, 0,-32728, 3212, 32413, -6392,-31785, 9512, 30853,-12539,-29621, 15447, 28106,-18204,-26319, 20788, 24279, },
+{ -23169, 26320, 15447,-30852, -6392, 32729, -3211,-31785, 12540, 28106,-20787,-22005, 27246, 14010,-31356, -4807, 32767, -4807,-31356, 14010, 27246,-22005,-20787, 28106, 12540,-31785, -3211, 32729, -6392,-30852, 15447, 26320,-23169,-19519, 28899, 11039,-32137, -1607, 32610, -7961,-30273, 16846, 25330,-24278,-18204, 29622, 9512,-32412, 0, 32413, -9511,-29621, 18205, 24279,-25329,-16845, 30274, 7962,-32609, 1608, 32138,-11038,-28898, 19520, },
+{ -23169,-16845, 31357, 1608,-32137, 14010, 25330,-26319,-12539, 32413, -3211,-30852, 18205, 22006,-28898, -7961, 32767, -7961,-28898, 22006, 18205,-30852, -3211, 32413,-12539,-26319, 25330, 14010,-32137, 1608, 31357,-16845,-23169, 28106, 9512,-32728, 6393, 29622,-20787,-19519, 30274, 4808,-32609, 11039, 27246,-24278,-15446, 31786, 0,-31785, 15447, 24279,-27245,-11038, 32610, -4807,-30273, 19520, 20788,-29621, -6392, 32729, -9511,-28105, },
+{ 23170,-29621, -3211, 31786,-18204,-19519, 31357, -1607,-30273, 22006, 15447,-32412, 6393, 28106,-25329,-11038, 32767,-11038,-25329, 28106, 6393,-32412, 15447, 22006,-30273, -1607, 31357,-19519,-18204, 31786, -3211,-29621, 23170, 14010,-32609, 7962, 27246,-26319, -9511, 32729,-12539,-24278, 28899, 4808,-32137, 16846, 20788,-30852, 0, 30853,-20787,-16845, 32138, -4807,-28898, 24279, 12540,-32728, 9512, 26320,-27245, -7961, 32610,-14009, },
+{ 23170, 11039,-32609, 16846, 18205,-32412, 9512, 24279,-30273, 1608, 28899,-26319, -6392, 31786,-20787,-14009, 32767,-14009,-20787, 31786, -6392,-26319, 28899, 1608,-30273, 24279, 9512,-32412, 18205, 16846,-32609, 11039, 23170,-30852, 3212, 28106,-27245, -4807, 31357,-22005,-12539, 32729,-15446,-19519, 32138, -7961,-25329, 29622, 0,-29621, 25330, 7962,-32137, 19520, 15447,-32728, 12540, 22006,-31356, 4808, 27246,-28105, -3211, 30853, },
+{ -23169, 31786, -9511,-22005, 32138,-11038,-20787, 32413,-12539,-19519, 32610,-14009,-18204, 32729,-15446,-16845, 32767,-16845,-15446, 32729,-18204,-14009, 32610,-19519,-12539, 32413,-20787,-11038, 32138,-22005, -9511, 31786,-23169, -7961, 31357,-24278, -6392, 30853,-25329, -4807, 30274,-26319, -3211, 29622,-27245, -1607, 28899,-28105, 0, 28106,-28898, 1608, 27246,-29621, 3212, 26320,-30273, 4808, 25330,-30852, 6393, 24279,-31356, 7962, },
+{ -23169, -4807, 28899,-29621, 6393, 22006,-32609, 16846, 12540,-31785, 25330, 1608,-27245, 30853, -9511,-19519, 32767,-19519, -9511, 30853,-27245, 1608, 25330,-31785, 12540, 16846,-32609, 22006, 6393,-29621, 28899, -4807,-23169, 32413,-15446,-14009, 32138,-24278, -3211, 28106,-30273, 7962, 20788,-32728, 18205, 11039,-31356, 26320, 0,-26319, 31357,-11038,-18204, 32729,-20787, -7961, 30274,-28105, 3212, 24279,-32137, 14010, 15447,-32412, },
+{ 23170,-32728, 20788, 4808,-27245, 31786,-15446,-11038, 30274,-29621, 9512, 16846,-32137, 26320, -3211,-22005, 32767,-22005, -3211, 26320,-32137, 16846, 9512,-29621, 30274,-11038,-15446, 31786,-27245, 4808, 20788,-32728, 23170, 1608,-25329, 32413,-18204, -7961, 28899,-30852, 12540, 14010,-31356, 28106, -6392,-19519, 32610,-24278, 0, 24279,-32609, 19520, 6393,-28105, 31357,-14009,-12539, 30853,-28898, 7962, 18205,-32412, 25330, -1607, },
+{ 23170, -1607,-20787, 32413,-27245, 7962, 15447,-30852, 30274,-14009, -9511, 28106,-32137, 19520, 3212,-24278, 32767,-24278, 3212, 19520,-32137, 28106, -9511,-14009, 30274,-30852, 15447, 7962,-27245, 32413,-20787, -1607, 23170,-32728, 25330, -4807,-18204, 31786,-28898, 11039, 12540,-29621, 31357,-16845, -6392, 26320,-32609, 22006, 0,-22005, 32610,-26319, 6393, 16846,-31356, 29622,-12539,-11038, 28899,-31785, 18205, 4808,-25329, 32729, },
+{ -23169, 32413,-28898, 14010, 6393,-24278, 32610,-28105, 12540, 7962,-25329, 32729,-27245, 11039, 9512,-26319, 32767,-26319, 9512, 11039,-27245, 32729,-25329, 7962, 12540,-28105, 32610,-24278, 6393, 14010,-28898, 32413,-23169, 4808, 15447,-29621, 32138,-22005, 3212, 16846,-30273, 31786,-20787, 1608, 18205,-30852, 31357,-19519, 0, 19520,-31356, 30853,-18204, -1607, 20788,-31785, 30274,-16845, -3211, 22006,-32137, 29622,-15446, -4807, },
+{ -23169, 7962, 9512,-24278, 32138,-30852, 20788, -4807,-12539, 26320,-32609, 29622,-18204, 1608, 15447,-28105, 32767,-28105, 15447, 1608,-18204, 29622,-32609, 26320,-12539, -4807, 20788,-30852, 32138,-24278, 9512, 7962,-23169, 31786,-31356, 22006, -6392,-11038, 25330,-32412, 30274,-19519, 3212, 14010,-27245, 32729,-28898, 16846, 0,-16845, 28899,-32728, 27246,-14009, -3211, 19520,-30273, 32413,-25329, 11039, 6393,-22005, 31357,-31785, },
+{ 23170,-30852, 32610,-28105, 18205, -4807, -9511, 22006,-30273, 32729,-28898, 19520, -6392, -7961, 20788,-29621, 32767,-29621, 20788, -7961, -6392, 19520,-28898, 32729,-30273, 22006, -9511, -4807, 18205,-28105, 32610,-30852, 23170,-11038, -3211, 16846,-27245, 32413,-31356, 24279,-12539, -1607, 15447,-26319, 32138,-31785, 25330,-14009, 0, 14010,-25329, 31786,-32137, 26320,-15446, 1608, 12540,-24278, 31357,-32412, 27246,-16845, 3212, 11039, },
+{ 23170,-14009, 3212, 7962,-18204, 26320,-31356, 32729,-30273, 24279,-15446, 4808, 6393,-16845, 25330,-30852, 32767,-30852, 25330,-16845, 6393, 4808,-15446, 24279,-30273, 32729,-31356, 26320,-18204, 7962, 3212,-14009, 23170,-29621, 32610,-31785, 27246,-19519, 9512, 1608,-12539, 22006,-28898, 32413,-32137, 28106,-20787, 11039, 0,-11038, 20788,-28105, 32138,-32412, 28899,-22005, 12540, -1607, -9511, 19520,-27245, 31786,-32609, 29622, },
+{ -23169, 28106,-31356, 32729,-32137, 29622,-25329, 19520,-12539, 4808, 3212,-11038, 18205,-24278, 28899,-31785, 32767,-31785, 28899,-24278, 18205,-11038, 3212, 4808,-12539, 19520,-25329, 29622,-32137, 32729,-31356, 28106,-23169, 16846, -9511, 1608, 6393,-14009, 20788,-26319, 30274,-32412, 32610,-30852, 27246,-22005, 15447, -7961, 0, 7962,-15446, 22006,-27245, 30853,-32609, 32413,-30273, 26320,-20787, 14010, -6392, -1607, 9512,-16845, },
+{ -23169, 19520,-15446, 11039, -6392, 1608, 3212, -7961, 12540,-16845, 20788,-24278, 27246,-29621, 31357,-32412, 32767,-32412, 31357,-29621, 27246,-24278, 20788,-16845, 12540, -7961, 3212, 1608, -6392, 11039,-15446, 19520,-23169, 26320,-28898, 30853,-32137, 32729,-32609, 31786,-30273, 28106,-25329, 22006,-18204, 14010, -9511, 4808, 0, -4807, 9512,-14009, 18205,-22005, 25330,-28105, 30274,-31785, 32610,-32728, 32138,-30852, 28899,-26319, },
+{ 23170,-24278, 25330,-26319, 27246,-28105, 28899,-29621, 30274,-30852, 31357,-31785, 32138,-32412, 32610,-32728, 32767,-32728, 32610,-32412, 32138,-31785, 31357,-30852, 30274,-29621, 28899,-28105, 27246,-26319, 25330,-24278, 23170,-22005, 20788,-19519, 18205,-16845, 15447,-14009, 12540,-11038, 9512, -7961, 6393, -4807, 3212, -1607, 0, 1608, -3211, 4808, -6392, 7962, -9511, 11039,-12539, 14010,-15446, 16846,-18204, 19520,-20787, 22006, } };
+
+static const int sfBand[6][23] =
+{
+/* Table B.2.b: 22.05 kHz */
+{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+/* Table B.2.c: 24 kHz */
+{0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
+/* Table B.2.a: 16 kHz */
+{0,6,12,18,24,30,36,44,45,66,80,96,116,140,168,200,238,248,336,396,464,522,576},
+/* Table B.8.b: 44.1 kHz */
+{0,4, 8,12,16,20,24,30,36,44,52,62, 74, 90,110,134,162,196,238,288,342,418,576},
+/* Table B.8.c: 48 kHz */
+{0,4, 8,12,16,20,24,30,36,42,50,60, 72, 88,106,128,156,190,230,276,330,384,576},
+/* Table B.8.a: 32 kHz */
+{0,4, 8,12,16,20,24,30,36,44,54,66, 82,102,126,156,194,240,296,364,448,550,576} };
+
+static const uint16 enwindow_int_const[512] = {
+0x0000,0x0035,0x01fd,0x066c,0x4948,0x066c,0x01fd,0x0035,0x0000,0x0037,0x01f4,0x05d2,0x493c,0x06f8,0x0204,0x0034,
+0x0000,0x0038,0x01e8,0x052a,0x491a,0x0776,0x0208,0x0032,0x0000,0x0038,0x01d9,0x0474,0x48e1,0x07e7,0x020a,0x0031,
+0x0000,0x0039,0x01c8,0x03b0,0x4892,0x084b,0x0209,0x0030,0x0000,0x0039,0x01b3,0x02de,0x482d,0x08a2,0x0207,0x002e,
+0x0000,0x0039,0x019b,0x01fd,0x47b2,0x08ed,0x0202,0x002c,0x0000,0x0039,0x0180,0x010f,0x4721,0x092b,0x01fc,0x002a,
+0x0000,0x0038,0x0161,0x0011,0x467a,0x095e,0x01f4,0x0028,0x0000,0x0037,0x0140,0xff07,0x45bf,0x0985,0x01eb,0x0026,
+0x0000,0x0036,0x011b,0xfdee,0x44f0,0x09a2,0x01e0,0x0025,0x0000,0x0034,0x00f3,0xfcc8,0x440c,0x09b4,0x01d4,0x0023,
+0x0000,0x0032,0x00c7,0xfb93,0x4315,0x09bb,0x01c6,0x0021,0x0000,0x002f,0x0097,0xfa53,0x420b,0x09ba,0x01b8,0x001f,
+0x0000,0x002c,0x0065,0xf905,0x40f0,0x09af,0x01a9,0x001d,0x0000,0x0029,0x002e,0xf7aa,0x3fc3,0x099b,0x0198,0x001c,
+0x0000,0x0025,0xfff6,0xf643,0x3e85,0x0980,0x0188,0x001a,0xffff,0x0020,0xffb9,0xf4d1,0x3d37,0x095c,0x0176,0x0018,
+0xffff,0x001b,0xff79,0xf354,0x3bda,0x0932,0x0165,0x0017,0xffff,0x0015,0xff36,0xf1cc,0x3a70,0x0901,0x0153,0x0015,
+0xffff,0x000e,0xfeef,0xf03a,0x38f7,0x08ca,0x0141,0x0014,0xffff,0x0007,0xfea6,0xee9f,0x3773,0x088d,0x012f,0x0012,
+0xfffe,0x0000,0xfe5a,0xecfb,0x35e3,0x084b,0x011c,0x0011,0xfffe,0xfff8,0xfe0b,0xeb50,0x3447,0x0804,0x010a,0x0010,
+0xfffe,0xffef,0xfdbb,0xe99d,0x32a3,0x07ba,0x00f8,0x000f,0xfffd,0xffe5,0xfd67,0xe7e4,0x30f6,0x076b,0x00e6,0x000d,
+0xfffd,0xffdb,0xfd12,0xe624,0x2f41,0x071a,0x00d4,0x000c,0xfffd,0xffd0,0xfcbb,0xe461,0x2d86,0x06c6,0x00c3,0x000b,
+0xfffc,0xffc4,0xfc63,0xe299,0x2bc5,0x066f,0x00b2,0x000a,0xfffc,0xffb8,0xfc09,0xe0ce,0x2a00,0x0617,0x00a1,0x0009,
+0xfffb,0xffaa,0xfbaf,0xdf01,0x2836,0x05be,0x0091,0x0009,0xfffb,0xff9d,0xfb54,0xdd33,0x266a,0x0563,0x0081,0x0008,
+0xfffa,0xff8e,0xfaf9,0xdb65,0x249c,0x0508,0x0073,0x0007,0xfff9,0xff80,0xfa9e,0xd997,0x22ce,0x04ad,0x0064,0x0006,
+0xfff8,0xff70,0xfa43,0xd7cb,0x2100,0x0452,0x0057,0x0006,0xfff8,0xff60,0xf9ea,0xd601,0x1f33,0x03f8,0x0049,0x0005,
+0xfff7,0xff4f,0xf992,0xd43c,0x1d68,0x039e,0x003d,0x0005,0xfff6,0xff3e,0xf93b,0xd27b,0x1ba0,0x0346,0x0031,0x0004,
+0xfff5,0xff2d,0xf8e7,0xd0c0,0x19dd,0x02ef,0x0026,0x0004,0xfff4,0xff1b,0xf896,0xcf0b,0x181d,0x029a,0x001c,0x0004,
+0xfff2,0xff09,0xf847,0xcd5e,0x1664,0x0246,0x0012,0x0003,0xfff1,0xfef7,0xf7fd,0xcbba,0x14b1,0x01f6,0x0009,0x0003,
+0xfff0,0xfee5,0xf7b6,0xca1e,0x1306,0x01a7,0x0001,0x0003,0xffef,0xfed2,0xf774,0xc88e,0x1162,0x015b,0xfffa,0x0002,
+0xffed,0xfec0,0xf737,0xc70a,0x0fc7,0x0112,0xfff3,0x0002,0xffec,0xfeae,0xf700,0xc591,0x0e35,0x00cb,0xffec,0x0002,
+0xffea,0xfe9c,0xf6cf,0xc427,0x0cad,0x0088,0xffe6,0x0002,0xffe9,0xfe8b,0xf6a5,0xc2ca,0x0b30,0x0048,0xffe1,0x0002,
+0xffe7,0xfe79,0xf681,0xc17c,0x09be,0x000b,0xffdc,0x0001,0xffe5,0xfe69,0xf666,0xc03e,0x0857,0xffd3,0xffd8,0x0001,
+0xffe4,0xfe58,0xf652,0xbf11,0x06fc,0xff9c,0xffd5,0x0001,0xffe2,0xfe49,0xf647,0xbdf6,0x05ae,0xff6a,0xffd2,0x0001,
+0xffe0,0xfe3b,0xf646,0xbcec,0x046e,0xff3a,0xffcf,0x0001,0xffde,0xfe2d,0xf64d,0xbbf5,0x0339,0xff0e,0xffcd,0x0001,
+0xffdc,0xfe21,0xf65f,0xbb11,0x0213,0xfee6,0xffcb,0x0001,0xffdb,0xfe16,0xf67c,0xba42,0x00fa,0xfec1,0xffca,0x0001,
+0xffd9,0xfe0d,0xf6a3,0xb987,0xfff0,0xfea0,0xffc9,0x0001,0xffd7,0xfe05,0xf6d6,0xb8e0,0xfef2,0xfe81,0xffc8,0x0001,
+0xffd5,0xfdff,0xf714,0xb84f,0xfe04,0xfe66,0xffc8,0x0000,0xffd3,0xfdfa,0xf75f,0xb7d4,0xfd23,0xfe4e,0xffc8,0x0000,
+0xffd1,0xfdf8,0xf7b6,0xb76f,0xfc51,0xfe39,0xffc8,0x0000,0xffd0,0xfdf7,0xf81a,0xb720,0xfb8d,0xfe28,0xffc9,0x0000,
+0xffcf,0xfdf9,0xf88b,0xb6e7,0xfad7,0xfe19,0xffc9,0x0000,0xffcd,0xfdfd,0xf909,0xb6c5,0xfa2f,0xfe0d,0xffca,0x0000,
+};
+
+static const uint8 int2idx_const[5000] = {
+ 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210 };
+
+static const uint16 int3idx[32768] = {
+ 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,256,256,256,256,256,256,256,256,
+256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,
+260,260,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
+262,262,262,262,262,262,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
+263,263,263,263,263,263,263,263,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,
+264,264,264,264,264,264,264,264,264,264,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,
+266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,
+268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,269,269,269,269,269,269,269,269,269,269,269,269,
+269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,270,270,270,270,270,270,270,270,270,270,
+270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,271,271,271,271,271,271,271,
+271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,272,272,272,272,272,
+272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,273,273,
+273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,
+274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,
+274,274,274,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,
+275,275,275,275,275,275,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,
+276,276,276,276,276,276,276,276,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
+278,278,278,278,278,278,278,278,278,278,278,278,278,278,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,
+279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
+280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,281,281,281,281,281,281,281,281,281,281,281,281,
+281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,282,282,282,282,282,282,282,282,282,
+282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,283,283,283,283,283,283,
+283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,284,284,284,
+284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,
+285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
+285,285,285,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
+286,286,286,286,286,286,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,
+287,287,287,287,287,287,287,287,287,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,
+288,288,288,288,288,288,288,288,288,288,288,288,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,
+289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,
+290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,292,292,292,292,292,292,292,292,292,292,
+292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,293,293,293,293,293,293,
+293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,294,294,294,
+294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
+295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,
+295,295,295,295,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,
+296,296,296,296,296,296,296,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,
+297,297,297,297,297,297,297,297,297,297,297,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,
+298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,
+299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,300,300,300,300,300,300,300,300,300,300,300,300,300,300,
+300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,301,301,301,301,301,301,301,301,301,301,
+301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,302,302,302,302,302,302,
+302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,303,303,
+303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
+303,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,
+304,304,304,304,304,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+305,305,305,305,305,305,305,305,305,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
+306,306,306,306,306,306,306,306,306,306,306,306,306,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
+307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
+308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,309,309,309,309,309,309,309,309,309,309,309,
+309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,310,310,310,310,310,310,310,
+310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,311,311,311,
+311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,
+311,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,
+312,312,312,312,312,312,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
+313,313,313,313,313,313,313,313,313,313,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,
+314,314,314,314,314,314,314,314,314,314,314,314,314,314,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
+315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
+316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,317,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,319,
+319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,
+319,319,319,319,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,
+320,320,320,320,320,320,320,320,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,
+321,321,321,321,321,321,321,321,321,321,321,321,321,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,
+322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,324,324,324,324,324,324,324,324,324,324,
+324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,325,325,325,325,325,
+325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,326,
+326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,
+326,326,326,326,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,
+328,328,328,328,328,328,328,328,328,328,328,328,328,328,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,
+329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,331,331,331,331,331,331,331,331,331,
+331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,332,332,332,332,
+332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,
+332,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,
+334,334,334,334,334,334,334,334,334,334,334,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,
+335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337,337,337,337,
+337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,338,338,338,338,338,338,
+338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,
+339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,
+339,339,339,339,339,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,
+340,340,340,340,340,340,340,340,340,340,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,
+341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,
+342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,343,343,343,343,343,343,343,343,343,343,343,343,
+343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,344,344,344,344,344,344,
+344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,
+346,346,346,346,346,346,346,346,346,346,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,
+347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,
+348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,349,349,349,349,349,349,349,349,349,349,349,
+349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,350,350,350,350,350,
+350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,
+351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,
+351,351,351,351,351,351,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,
+352,352,352,352,352,352,352,352,352,352,352,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,
+353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,
+354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,355,355,355,355,355,355,355,355,355,
+355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
+357,357,357,357,357,357,357,357,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+358,358,358,358,358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,361,361,361,361,361,361,
+361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,
+362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,
+362,362,362,362,362,362,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,
+363,363,363,363,363,363,363,363,363,363,363,363,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
+364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,366,366,366,366,366,366,366,366,
+366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,367,367,
+367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
+367,367,367,367,367,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,371,371,371,371,371,371,371,371,371,
+371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,372,372,
+372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,
+372,372,372,372,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,
+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,376,376,376,376,376,376,376,376,376,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,377,377,
+377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,
+377,377,377,377,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,
+378,378,378,378,378,378,378,378,378,378,378,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,
+379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,380,380,380,380,380,380,380,380,380,380,380,380,380,380,
+380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,382,
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,
+382,382,382,382,382,382,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,383,383,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
+384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,385,385,385,385,385,385,385,385,385,385,385,385,385,
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,386,386,386,386,386,386,
+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,
+386,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+387,387,387,387,387,387,387,387,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,
+388,388,388,388,388,388,388,388,388,388,388,388,388,388,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,
+389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,390,390,390,390,390,390,390,390,390,390,390,
+390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,391,391,391,391,
+391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
+391,391,391,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,
+392,392,392,392,392,392,392,392,392,392,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,
+393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,393,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,
+394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,395,395,395,395,395,395,395,
+395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,
+396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
+396,396,396,396,396,396,396,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,397,
+397,397,397,397,397,397,397,397,397,397,397,397,397,397,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,
+398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,399,399,399,399,399,399,399,399,399,399,399,
+399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
+401,401,401,401,401,401,401,401,401,401,401,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
+402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,403,403,403,403,403,403,403,403,403,403,403,403,403,
+403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,
+405,405,405,405,405,405,405,405,405,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,
+406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,
+407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,409,
+409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,
+409,409,409,409,409,409,409,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,
+411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,413,413,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
+413,413,413,413,413,413,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,417,417,417,
+417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,
+417,417,417,417,417,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,421,421,421,
+421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,
+421,421,421,421,421,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,
+423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,424,424,424,424,424,424,424,424,424,424,424,
+424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,425,425,425,
+425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,425,
+425,425,425,425,425,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+426,426,426,426,426,426,426,426,426,426,426,426,426,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,
+427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,429,429,429,
+429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
+429,429,429,429,429,429,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,
+430,430,430,430,430,430,430,430,430,430,430,430,430,430,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,
+431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,433,433,
+433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,433,
+433,433,433,433,433,433,433,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,
+434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,
+435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,436,436,436,436,436,436,436,436,
+436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,440,440,440,440,440,440,
+440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
+440,440,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,441,441,441,441,441,441,441,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,
+442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,443,443,443,443,443,443,443,443,443,443,443,443,443,
+443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,444,444,444,444,
+444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,
+444,444,444,444,444,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,
+445,445,445,445,445,445,445,445,445,445,445,445,445,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,
+446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,447,447,447,447,447,447,447,447,447,447,
+447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,448,
+448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,
+448,448,448,448,448,448,448,448,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,
+449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,451,451,451,451,451,451,451,
+451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
+451,451,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,
+452,452,452,452,452,452,452,452,452,452,452,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,
+453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,453,454,454,454,454,454,454,454,454,454,454,454,454,
+454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,455,455,455,
+455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,
+455,455,455,455,455,455,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
+456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,
+457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,458,458,458,458,458,458,458,458,
+458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,
+458,458,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,
+459,459,459,459,459,459,459,459,459,459,459,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,461,461,461,461,461,461,461,461,461,461,461,461,
+461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,462,462,462,
+462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,
+462,462,462,462,462,462,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
+463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,
+464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,468,468,468,468,468,468,468,468,468,468,468,
+468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,469,469,
+469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
+469,469,469,469,469,469,469,469,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,
+470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,
+471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,472,472,472,472,472,
+472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
+472,472,472,472,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
+474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
+477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,478,478,478,478,478,478,478,478,478,478,478,478,
+478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
+483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+486,486,486,486,486,486,486,486,486,486,486,486,486,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,
+487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,488,
+488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
+488,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
+489,489,489,489,489,489,489,489,489,489,489,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,
+490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,491,491,491,491,491,491,491,491,491,491,491,
+491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,492,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,492,492,492,492,492,492,492,492,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,
+493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,494,494,494,494,494,494,494,494,494,494,494,494,494,
+494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,495,495,495,
+495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
+495,495,495,495,495,495,495,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,497,497,497,497,497,497,497,497,497,497,497,497,497,497,
+497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,
+500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,501,501,501,501,501,
+501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,
+501,501,501,501,501,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
+502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,
+503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,504,504,504,504,504,504,
+504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
+504,504,504,504,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
+505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,
+506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,
+508,508,508,508,508,508,508,508,508,508,508,508,508,508,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
+509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,510,510,510,510,510,510,510,
+510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,
+510,510,510,510,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,
+517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,
+518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,519,519,519,519,519,519,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
+520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,
+523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,
+524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,525,525,525,525,525,
+525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
+526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,
+527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,528,528,528,528,
+528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,
+528,528,528,528,528,528,528,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,531,531,
+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,
+531,531,531,531,531,531,531,531,531,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,
+532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,533,533,533,533,533,533,533,533,533,533,533,533,
+533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,539,539,539,539,539,539,539,539,
+539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
+539,539,539,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,
+540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,
+541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
+543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
+544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,545,545,545,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,545,545,545,545,545,545,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
+546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,547,547,547,547,547,547,547,547,547,547,547,547,
+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,548,548,548,548,548,548,548,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,
+549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,550,550,550,550,550,550,550,550,550,
+550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,
+550,550,550,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,
+551,551,551,551,551,551,551,551,551,551,551,551,551,551,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,553,553,553,553,553,553,
+553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,
+553,553,553,553,553,553,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,558,558,558,558,558,558,558,558,558,558,558,
+558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
+558,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
+559,559,559,559,559,559,559,559,559,559,559,559,559,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
+562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
+563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,564,564,564,
+564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
+564,564,564,564,564,564,564,564,564,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,
+565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,566,566,566,566,566,566,566,566,566,566,566,
+566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
+566,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,
+567,567,567,567,567,567,567,567,567,567,567,567,567,567,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,
+568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,569,569,569,569,569,569,
+569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
+569,569,569,569,569,569,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,
+570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
+571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,572,572,
+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
+572,572,572,572,572,572,572,572,572,572,572,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,574,574,574,574,574,574,574,574,574,
+574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
+574,574,574,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,
+575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
+576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,577,577,577,577,
+577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
+577,577,577,577,577,577,577,577,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,579,579,579,579,579,579,579,579,579,579,579,
+579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,
+579,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,582,582,582,582,582,582,
+582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,
+582,582,582,582,582,582,582,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
+583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
+585,585,585,585,585,585,585,585,585,585,585,585,585,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,
+588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,590,
+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,590,590,590,590,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
+591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,592,592,592,592,592,592,592,
+592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
+592,592,592,592,592,592,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,594,594,594,594,594,594,594,594,594,594,594,594,594,594,
+594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,595,
+595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,
+595,595,595,595,595,595,595,595,595,595,595,595,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,597,597,597,597,597,597,597,
+597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
+597,597,597,597,597,597,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,
+598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,599,599,599,599,599,599,599,599,599,599,599,599,599,
+599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,
+600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
+600,600,600,600,600,600,600,600,600,600,600,600,600,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,602,602,602,602,602,602,
+602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,
+602,602,602,602,602,602,602,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,
+603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,604,604,604,604,604,604,604,604,604,604,604,604,
+604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,
+604,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
+605,605,605,605,605,605,605,605,605,605,605,605,605,605,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,
+606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,607,607,607,607,607,
+607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,
+607,607,607,607,607,607,607,607,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,
+608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,609,609,609,609,609,609,609,609,609,609,609,
+609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,
+609,609,609,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,
+610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,
+611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,612,612,612,
+612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
+612,612,612,612,612,612,612,612,612,612,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,
+613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,614,614,614,614,614,614,614,614,
+614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,
+614,614,614,614,614,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
+616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
+617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
+617,617,617,617,617,617,617,617,617,617,617,617,617,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,619,619,619,619,619,
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,619,619,619,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,621,621,621,621,621,621,621,621,621,621,
+621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
+621,621,621,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,
+622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,
+623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,624,624,
+624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,
+624,624,624,624,624,624,624,624,624,624,624,624,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,
+625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,626,626,626,626,626,626,626,
+626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,
+626,626,626,626,626,626,626,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,
+627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,628,628,628,628,628,628,628,628,628,628,628,
+628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,
+628,628,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
+629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,631,631,
+631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
+631,631,631,631,631,631,631,631,631,631,631,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,
+632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,633,633,633,633,633,633,633,
+633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,
+633,633,633,633,633,633,633,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,
+634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,635,635,635,635,635,635,635,635,635,635,635,
+635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,
+635,635,635,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,
+636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,
+637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,638,638,
+638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,
+638,638,638,638,638,638,638,638,638,638,638,638,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,
+639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,640,640,640,640,640,640,
+640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,
+640,640,640,640,640,640,640,640,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,
+641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,642,642,642,642,642,642,642,642,642,642,
+642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,
+642,642,642,642,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,
+643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,644,644,644,644,644,644,644,644,644,644,644,644,644,644,
+644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,
+645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,
+645,645,645,645,645,645,645,645,645,645,645,645,645,645,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,
+646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,647,647,647,
+647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,
+647,647,647,647,647,647,647,647,647,647,647,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,
+648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,649,649,649,649,649,649,649,
+649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,
+649,649,649,649,649,649,649,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,
+650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,650,651,651,651,651,651,651,651,651,651,651,651,
+651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,651,
+651,651,651,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
+652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,653,653,653,653,653,653,653,653,653,653,653,653,653,653,
+653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,
+654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
+654,654,654,654,654,654,654,654,654,654,654,654,654,654,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,
+655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,656,656,656,
+656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,
+656,656,656,656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,658,658,658,658,658,658,658,
+658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
+658,658,658,658,658,658,658,658,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
+659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,660,660,660,660,660,660,660,660,660,660,
+660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,
+660,660,660,660,660,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,
+661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,662,662,662,662,662,662,662,662,662,662,662,662,662,
+662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,
+662,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,
+663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,
+664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,665,
+665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
+665,665,665,665,665,665,665,665,665,665,665,665,665,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,
+666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,667,667,667,667,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+667,667,667,667,667,667,667,667,667,667,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,
+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,669,669,669,669,669,669,669,
+669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,
+669,669,669,669,669,669,669,669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,
+674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,674,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
+675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
+676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,
+676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,
+677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,677,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,680,680,680,680,680,
+680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,
+680,680,680,680,680,680,680,680,680,680,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,
+681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,682,682,682,682,682,682,682,
+682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
+682,682,682,682,682,682,682,682,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,
+683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,684,684,684,684,684,684,684,684,684,
+684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
+684,684,684,684,684,684,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,686,686,686,686,686,686,686,686,686,686,686,
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+686,686,686,686,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,
+687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,688,688,688,688,688,688,688,688,688,688,688,688,688,
+688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,
+688,688,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
+689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,
+690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,
+691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
+691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,
+692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,693,
+693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,
+693,693,693,693,693,693,693,693,693,693,693,693,693,693,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,
+694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,695,695,695,
+695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
+695,695,695,695,695,695,695,695,695,695,695,695,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,
+696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,697,697,697,697,
+697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
+697,697,697,697,697,697,697,697,697,697,697,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,
+698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,699,699,699,699,699,699,
+699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,
+699,699,699,699,699,699,699,699,699,699,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,701,701,701,701,701,701,701,
+701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,
+701,701,701,701,701,701,701,701,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,703,703,703,703,703,703,703,703,
+703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
+703,703,703,703,703,703,703,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,
+704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,705,705,705,705,705,705,705,705,705,
+705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,
+705,705,705,705,705,705,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,
+706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707,707,707,
+707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
+707,707,707,707,707,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,713,713,713,713,713,713,713,713,713,713,713,713,713,
+713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,
+713,713,713,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,
+714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,715,715,715,715,715,715,715,715,715,715,715,715,715,715,
+715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,
+715,715,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,
+716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,717,717,717,717,717,717,717,717,717,717,717,717,717,717,
+717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,
+717,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,
+718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
+719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
+719,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,
+720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,
+721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,
+721,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,
+722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
+723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
+724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
+724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
+725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
+726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
+726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
+727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
+728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,
+728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
+729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,
+731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,
+732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,
+732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,
+733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,
+734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,
+734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,
+735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,
+735,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
+736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+737,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,
+738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,
+740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
+741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
+741,741,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,
+742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,743,743,743,743,743,743,743,743,743,743,743,743,743,743,
+743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,
+743,743,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
+744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,745,745,745,745,745,745,745,745,745,745,745,745,745,
+745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,
+745,745,745,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,
+746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,747,747,747,747,747,747,747,747,747,747,747,747,747,
+747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,
+747,747,747,747,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,
+748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,749,749,749,749,749,749,749,749,749,749,749,749,
+749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,
+749,749,749,749,749,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,
+750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,751,751,751,751,751,751,751,751,751,751,751,
+751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,
+751,751,751,751,751,751,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,
+752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,753,753,753,753,753,753,753,753,753,753,
+753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
+753,753,753,753,753,753,753,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,755,755,755,755,755,755,755,755,755,
+755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,
+755,755,755,755,755,755,755,755,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,
+756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,757,757,757,757,757,757,757,757,
+757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,
+757,757,757,757,757,757,757,757,757,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,
+758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,759,759,759,759,759,759,
+759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,
+759,759,759,759,759,759,759,759,759,759,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,
+760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,761,761,761,761,761,
+761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,
+761,761,761,761,761,761,761,761,761,761,761,761,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,
+762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,763,763,763,763,
+763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
+763,763,763,763,763,763,763,763,763,763,763,763,763,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,
+764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,765,765,
+765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,
+765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,
+766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,767,
+767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,
+767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,
+768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,
+768,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,
+769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,769,770,770,770,770,770,770,770,770,770,770,770,770,770,770,
+770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,
+770,770,770,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,
+771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,774,774,774,774,774,774,774,774,774,774,
+774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,774,
+774,774,774,774,774,774,774,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,
+777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,778,778,778,778,778,778,
+778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,
+778,778,778,778,778,778,778,778,778,778,778,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,
+779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,780,780,780,780,
+780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,
+780,780,780,780,780,780,780,780,780,780,780,780,780,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,
+781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,782,782,
+782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,
+782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,
+783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,
+784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,
+784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,
+785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,
+785,785,785,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,
+786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,787,787,787,787,787,787,787,787,787,787,787,787,
+787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,
+787,787,787,787,787,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,
+788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,789,789,789,789,789,789,789,789,789,789,
+789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,
+789,789,789,789,789,789,789,789,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,
+790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,791,791,791,791,791,791,791,
+791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,
+791,791,791,791,791,791,791,791,791,791,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,
+792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,793,793,793,793,
+793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
+793,793,793,793,793,793,793,793,793,793,793,793,793,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,
+794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,795,795,
+795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,
+795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,798,798,798,798,798,798,798,798,798,798,798,798,798,
+798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,
+798,798,798,798,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,
+799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,800,800,800,800,800,800,800,800,800,800,
+800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,
+800,800,800,800,800,800,800,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,
+801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,802,802,802,802,802,802,802,
+802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,
+802,802,802,802,802,802,802,802,802,802,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,
+803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,803,804,804,804,804,
+804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,
+804,804,804,804,804,804,804,804,804,804,804,804,804,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,
+805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,806,
+806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,
+806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,
+807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,807,
+807,807,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,809,809,809,809,809,809,809,809,809,809,809,809,
+809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,
+809,809,809,809,809,809,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,
+810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,811,811,811,811,811,811,811,811,811,
+811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,
+811,811,811,811,811,811,811,811,811,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,
+812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,813,813,813,813,813,
+813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,
+813,813,813,813,813,813,813,813,813,813,813,813,813,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,
+814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,815,815,
+815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,
+815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,
+816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,
+816,816,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,
+817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,818,818,818,818,818,818,818,818,818,818,818,818,
+818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
+818,818,818,818,818,818,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
+819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,820,820,820,820,820,820,820,820,
+820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,
+820,820,820,820,820,820,820,820,820,820,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,
+821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,822,822,822,822,
+822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,822,
+822,822,822,822,822,822,822,822,822,822,822,822,822,822,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,
+823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,
+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,825,825,825,825,825,825,825,825,825,825,825,825,825,825,
+825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,
+825,825,825,825,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,
+826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,827,827,827,827,827,827,827,827,827,827,
+827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,
+827,827,827,827,827,827,827,827,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,
+828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,829,829,829,829,829,829,
+829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
+829,829,829,829,829,829,829,829,829,829,829,829,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,
+830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,831,831,
+831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,
+831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,
+832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,
+832,832,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,
+833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,834,834,834,834,834,834,834,834,834,834,834,834,
+834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,
+834,834,834,834,834,834,834,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,
+835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,836,836,836,836,836,836,836,
+836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,
+836,836,836,836,836,836,836,836,836,836,836,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,
+837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,838,838,838,
+838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
+838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
+839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
+839,839,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,
+840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,841,841,841,841,841,841,841,841,841,841,841,841,
+841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,
+841,841,841,841,841,841,841,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,
+842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,843,843,843,843,843,843,843,
+843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,
+843,843,843,843,843,843,843,843,843,843,843,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,
+844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,845,845,
+845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,
+845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
+846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
+846,846,846,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,
+847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,848,848,848,848,848,848,848,848,848,848,848,
+848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,848,
+848,848,848,848,848,848,848,848,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,
+849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,850,850,850,850,850,850,
+850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,
+850,850,850,850,850,850,850,850,850,850,850,850,850,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,
+851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,852,
+852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,
+852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,852,853,853,853,853,853,853,853,853,853,853,853,853,853,853,
+853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,
+853,853,853,853,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,
+854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,855,855,855,855,855,855,855,855,855,
+855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,
+855,855,855,855,855,855,855,855,855,855,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,
+856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,857,857,857,857,
+857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,
+857,857,857,857,857,857,857,857,857,857,857,857,857,857,857,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
+858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
+858,858,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,
+859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,860,860,860,860,860,860,860,860,860,860,860,860,
+860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,
+860,860,860,860,860,860,860,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861 };
+
+/* forward declarations */
+void encodeSideInfo( side_info_t si[2][2] );
+void Huffmancodebits( uint16 *ix, int *xr, side_info_t *gi );
+int HuffmanCode(int table_select, uint16 *ix, int *xr);
+int HuffmanCount1(unsigned tbl, uint16 *ix, int *xr );
+int new_choose_table( uint16 ix[SAMP_PER_FRAME2], uint32 begin, uint32 end );
+void putbits(uint32 val, uint32 nbit);
+int count_bit(uint16 ix[SAMP_PER_FRAME2], uint32 start, uint32 end, uint32 table );
+int bigv_bitcount(uint16 ix[SAMP_PER_FRAME2], side_info_t *gi);
+void bigv_tab_select( uint16 ix[SAMP_PER_FRAME2], side_info_t *cod_info );
+void subdivide(side_info_t *cod_info);
+void mdct_sub_int(int sb_sample[2][3][18][SBLIMIT], int (*mdct_freq)[2][SAMP_PER_FRAME2]);
+void filter_subband(int s[SBLIMIT], int off, int k);
+
+void putbits(uint32 val, uint32 nbit)
+{
+ int new_bitpos = CodedData.bitpos + nbit;
+ int ptrpos = CodedData.bitpos >> 5;
+
+ val = val & (0xffffffff >> (32 - nbit));
+
+ /* data fit in one uint32 */
+ if(((new_bitpos - 1) >> 5) == ptrpos)
+ CodedData.bbuf[ptrpos] |= val << ((32 - new_bitpos) & 31);
+ else
+ {
+ CodedData.bbuf[ptrpos ] |= val >> ((new_bitpos - 32) & 31);
+ CodedData.bbuf[ptrpos+1] = val << ((32 - new_bitpos) & 31);
+ }
+
+ CodedData.bitpos = new_bitpos;
+}
+
+/* This is called after a frame of audio has been quantized and coded.
+ It will write the encoded audio to the bitstream. Note that from a
+ layer3 encoder's perspective the bit stream is primarily a series
+ of main_data() blocks, with header and side information inserted at
+ the proper locations to maintain framing. See Figure A.7 in the IS */
+void format_bitstream( uint16 enc[2][2][SAMP_PER_FRAME2],
+ side_info_t side[2][2], int (*xr)[2][SAMP_PER_FRAME2] )
+{
+ int gr, ch;
+
+ encodeSideInfo( side );
+
+ for(gr=0; gr<2; gr++)
+ for(ch=0; ch<cfg.channels; ch++)
+ Huffmancodebits( &enc[gr][ch][0], &xr[gr][ch][0], &side[gr][ch] );
+}
+
+void encodeSideInfo( side_info_t si[2][2] )
+{
+ int gr, ch, header;
+
+ header = 0xfff00000;
+ header |= cfg.mpg.type << 19; /* mp3 type: 1 */
+ header |= 1 << 17; /* mp3 layer: 1 */
+ header |= 1 << 16; /* mp3 crc: 1 */
+ header |= cfg.mpg.bitrate_index << 12;
+ header |= cfg.mpg.smprate_index << 10;
+ header |= cfg.mpg.padding << 9;
+ header |= cfg.mpg.mode << 6;
+ header |= 1 << 2; /* mp3 original: 1 */
+
+ putbits( header, 32 );
+ putbits( 0, cfg.channels == 2 ? 20 : 18 );
+
+ for(gr=0; gr<2; gr++)
+ for(ch=0; ch<cfg.channels; ch++)
+ {
+ side_info_t *gi = &si[gr][ch];
+
+ putbits( gi->part2_3_length, 12 );
+ putbits( gi->big_values, 9 );
+ putbits( gi->global_gain, 8 );
+ putbits( gi->table_select[0], 10 );
+ putbits( gi->table_select[1], 5 );
+ putbits( gi->table_select[2], 5 );
+ putbits( gi->region0_count, 4 );
+ putbits( gi->region1_count, 3 );
+ putbits( gi->table_select[3], 3 );
+ }
+}
+
+/* Note the discussion of huffmancodebits() on pages 28 and 29 of the IS,
+ as well as the definitions of the side information on pages 26 and 27. */
+void Huffmancodebits( uint16 *ix, int *xr, side_info_t *gi )
+{
+ int region1Start;
+ int region2Start;
+ int i, bigvalues, count1End;
+ int stuffingBits;
+ int bitsWritten = 0;
+ uint32 scalefac_index;
+
+ /* 1: Write the bigvalues */
+ bigvalues = gi->big_values << 1;
+ scalefac_index = gi->region0_count + 1;
+ region1Start = scalefac[ scalefac_index ];
+ scalefac_index += gi->region1_count + 1;
+ region2Start = scalefac[ scalefac_index ];
+
+ for(i=0; i<region1Start; i+=2)
+ bitsWritten += HuffmanCode(gi->table_select[0], ix+i, xr+i);
+
+ for( ; i<region2Start; i+=2)
+ bitsWritten += HuffmanCode(gi->table_select[1], ix+i, xr+i);
+
+ for( ; i<bigvalues; i+=2)
+ bitsWritten += HuffmanCode(gi->table_select[2], ix+i, xr+i);
+
+ /* 2: Write count1 area */
+ count1End = bigvalues + (gi->count1 << 2);
+ for(i=bigvalues; i<count1End; i+=4)
+ bitsWritten += HuffmanCount1(gi->table_select[3], ix+i, xr+i);
+
+ if((stuffingBits = gi->part2_3_length - bitsWritten) != 0)
+ {
+ int stuffingWords = stuffingBits / 32;
+ int remainingBits = stuffingBits % 32;
+
+ if( remainingBits )
+ putbits( ~0, remainingBits );
+
+ /* Due to the nature of the Huffman code tables, we will pad with ones */
+ while( stuffingWords-- )
+ putbits( ~0, 32 );
+
+ bitsWritten += stuffingBits;
+ }
+}
+
+int HuffmanCount1(unsigned tbl, uint16 *ix, int *xr)
+{
+ uint32 dat, p, s;
+ int len, v, w, x, y;
+ #define signv (xr[0] < 0 ? 1 : 0)
+ #define signw (xr[1] < 0 ? 1 : 0)
+ #define signx (xr[2] < 0 ? 1 : 0)
+ #define signy (xr[3] < 0 ? 1 : 0)
+
+ v = ix[0];
+ w = ix[1];
+ x = ix[2];
+ y = ix[3];
+ p = v + (w << 1) + (x << 2) + (y << 3);
+
+ switch(p)
+ {
+ default: len = 0; s = 0; break;
+ case 1: len = 1; s = signv; break;
+ case 2: len = 1; s = signw; break;
+ case 3: len = 2; s = (signv << 1) + signw; break;
+ case 4: len = 1; s = signx; break;
+ case 5: len = 2; s = (signv << 1) + signx; break;
+ case 6: len = 2; s = (signw << 1) + signx; break;
+ case 7: len = 3; s = (signv << 2) + (signw << 1) + signx; break;
+ case 8: len = 1; s = signy; break;
+ case 9: len = 2; s = (signv << 1) + signy; break;
+ case 10: len = 2; s = (signw << 1) + signy; break;
+ case 11: len = 3; s = (signv << 2) + (signw << 1) + signy; break;
+ case 12: len = 2; s = (signx << 1) + signy; break;
+ case 13: len = 3; s = (signv << 2) + (signx << 1) + signy; break;
+ case 14: len = 3; s = (signw << 2) + (signx << 1) + signy; break;
+ case 15: len = 4; s = (signv << 3) + (signw << 2) + (signx << 1) + signy; break;
+ }
+
+ dat = (ht_count1[tbl][0][p] << len) + s;
+ len = ht_count1[tbl][1][p];
+ putbits( dat, len );
+
+ return len;
+}
+
+/* Implements the pseudocode of page 98 of the IS */
+int HuffmanCode(int table_select, uint16 *ix, int *xr)
+{
+ unsigned int linbitsx, linbitsy, linbits, idx;
+ const struct huffcodetab *h;
+ int x, y, bit;
+ uint32 code;
+ #define sign_x (xr[0] < 0 ? 1 : 0)
+ #define sign_y (xr[1] < 0 ? 1 : 0)
+
+ if(table_select == 0)
+ return 0;
+
+ x = ix[0];
+ y = ix[1];
+ h = &ht[table_select];
+ linbits = h->linbits;
+ linbitsx = linbitsy = 0;
+
+ if( table_select > 15 )
+ { /* ESC-table is used */
+ if(x > 14) { linbitsx = x - 15; x = 15; }
+ if(y > 14) { linbitsy = y - 15; y = 15; }
+
+ idx = (x * h->ylen) + y;
+ code = h->table[idx];
+ bit = h->hlen [idx];
+
+ if(x)
+ {
+ if(x > 14)
+ {
+ code = (code << linbits) | linbitsx;
+ bit += linbits;
+ }
+
+ code = (code << 1) | sign_x;
+ bit += 1;
+ }
+
+ if(y)
+ {
+ if(y > 14)
+ {
+ code = (code << linbits) | linbitsy;
+ bit += linbits;
+ }
+
+ code = (code << 1) | sign_y;
+ bit += 1;
+ }
+ }
+ else
+ { /* No ESC-words */
+ idx = (x * h->ylen) + y;
+ code = h->table[idx];
+ bit = h->hlen [idx];
+
+ if(x)
+ {
+ code = (code << 1) | sign_x;
+ bit += 1;
+ }
+
+ if(y)
+ {
+ code = (code << 1) | sign_y;
+ bit += 1;
+ }
+ }
+
+ putbits( code, bit );
+
+ return bit;
+}
+
+/***************************************************************************/
+/* Choose the Huffman table that will encode ix[begin..end] with */
+/* the fewest bits. */
+/* Note: This code contains knowledge about the sizes and characteristic */
+/* of the Huffman tables as defined in the IS (Table B.7), and will not */
+/* work with any arbitrary tables. */
+/***************************************************************************/
+int new_choose_table( uint16 ix[SAMP_PER_FRAME2], uint32 begin, uint32 end )
+{
+ uint32 i;
+ int max, sum0, sum1, table0, table1;
+
+ for(i=begin,max=0; i<end; i++)
+ if(ix[i] > max)
+ max = ix[i];
+
+ if(!max)
+ return 0;
+
+ table0 = 0;
+ table1 = 0;
+
+ if(max <= 15)
+ {
+ /* try tables with no linbits */
+ /* indx: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
+ /* xlen: 0, 2, 3, 3, 0, 4, 4, 6, 6, 6, 8, 8, 8, 16, 0, 16 */
+ for(table0=0; table0<14; table0++)
+ if(ht[table0].xlen > max)
+ break;
+
+ sum0 = count_bit(ix, begin, end, table0);
+
+ switch( table0 )
+ {
+ case 2: sum1 = count_bit( ix, begin, end, 3 );
+ if(sum1 <= sum0) table0 = 3; break;
+
+ case 5: sum1 = count_bit( ix, begin, end, 6 );
+ if(sum1 <= sum0) table0 = 6; break;
+
+ case 7: sum1 = count_bit( ix, begin, end, 8 );
+ if(sum1 <= sum0) { table0 = 8; sum0 = sum1; }
+ sum1 = count_bit( ix, begin, end, 9 );
+ if(sum1 <= sum0) table0 = 9; break;
+
+ case 10: sum1 = count_bit( ix, begin, end, 11 );
+ if(sum1 <= sum0) { table0 =11; sum0 = sum1; }
+ sum1 = count_bit( ix, begin, end, 12);
+ if(sum1 <= sum0) table0 = 12; break;
+
+ case 13: sum1 = count_bit( ix, begin, end, 15 );
+ if(sum1 <= sum0) table0 = 15; break;
+ }
+ }
+ else
+ {
+ /* try tables with linbits */
+ max -= 15;
+
+ /* index : 15 16 17 18 19 20 21 22 23 */
+ /* linmax: 0 1 3 7 15 63 255 1023 8191 */
+ for(table0=15; table0<24; table0++)
+ if(ht[table0].linmax >= max)
+ break;
+
+ /* index : 24 25 26 27 28 29 30 31 */
+ /* linmax: 15 31 63 127 255 511 2047 8191 */
+ for(table1=24; table1<32; table1++)
+ if(ht[table1].linmax >= max)
+ break;
+
+ sum0 = count_bit(ix, begin, end, table0);
+ sum1 = count_bit(ix, begin, end, table1);
+
+ if(sum1 < sum0)
+ table0 = table1;
+ }
+ return table0;
+}
+
+/*************************************************************************/
+/* Function: Count the number of bits necessary to code the subregion. */
+/*************************************************************************/
+int count_bit(uint16 ix[SAMP_PER_FRAME2], uint32 start, uint32 end, uint32 table)
+{
+ uint32 i;
+ int sum;
+ int x, y;
+ unsigned linbits, ylen;
+ const struct huffcodetab *h;
+
+ h = &ht[table];
+ sum = 0;
+ ylen = h->ylen;
+
+ if(table > 15)
+ { // ESC-table is used
+ linbits = h->linbits;
+ for(i=start; i<end; i+=2)
+ {
+ x = ix[i];
+ y = ix[i+1];
+
+ if(x)
+ {
+ if(x > 14) { x = 15; sum += linbits; }
+ sum++;
+ }
+
+ if(y)
+ {
+ if(y > 14) { y = 15; sum += linbits; }
+ sum++;
+ }
+
+ sum += h->hlen[(x * ylen) + y];
+ }
+ }
+ else
+ { /* No ESC-words */
+ for(i=start; i<end; i+=2)
+ {
+ x = ix[i];
+ y = ix[i+1];
+
+ sum += h->hlen[(x * ylen) + y];
+
+ if(x) sum++;
+ if(y) sum++;
+ }
+ }
+
+ return sum;
+}
+
+/*************************************************************************/
+/* Function: Quantization of the vector xr ( -> ix) */
+/*************************************************************************/
+int quantize_int(int xr[SAMP_PER_FRAME2], uint16 ix[SAMP_PER_FRAME2], side_info_t *cod_info)
+{
+ uint32 i, ind, step, frac_pow[] = { 0x80000, 0x6ba28, 0x5a828, 0x4c1c0 };
+
+ step = frac_pow[cod_info->quantizerStepSize & 3] >> cod_info->quantizerStepSize / 4;
+
+ for(i=SAMP_PER_FRAME2; i--; )
+ {
+ ind = (abs(xr[i]) * step + 32768) >> 16;
+
+ if(ind < 5000)
+ ix[i] = int2idx[ind];
+ else
+ if(ind < 32768)
+ ix[i] = int3idx[ind];
+ else
+ return 0;
+ }
+
+ return 1;
+}
+
+/*************************************************************************/
+/* Function: Calculation of rzero, count1, big_values */
+/* (Partitions ix into big values, quadruples and zeros). */
+/*************************************************************************/
+int calc_runlen( uint16 ix[SAMP_PER_FRAME2], side_info_t *cod_info )
+{
+ int p, i, sum0 = 0, sum1 = 0;
+
+ for(i=SAMP_PER_FRAME2; i-=2; )
+ if(ix[i-1] | ix[i-2])
+ break;
+
+ cod_info->count1 = 0;
+
+ for( ; i>3; i-=4)
+ {
+ int v = ix[i-1];
+ int w = ix[i-2];
+ int x = ix[i-3];
+ int y = ix[i-4];
+
+ if((v | w | x | y) <= 1)
+ {
+ p = (y) + (x<<1) + (w<<2) + (v<<3);
+
+ sum0 += ht_count1[0][1][p]; /* add table0 hlength */
+ sum1 += ht_count1[1][1][p]; /* add table1 hlength */
+
+ cod_info->count1++;
+ }
+ else break;
+ }
+
+ cod_info->big_values = i >> 1;
+
+ if(sum0 < sum1)
+ {
+ cod_info->table_select[3] = 0;
+ return sum0;
+ }
+ else
+ {
+ cod_info->table_select[3] = 1;
+ return sum1;
+ }
+}
+
+/*************************************************************************/
+/* presumable subdivides the bigvalue region which will use separate Huffman tables */
+/*************************************************************************/
+void subdivide(side_info_t *cod_info)
+{
+ int scfb_anz = 0;
+ int bigvalues_region;
+ int thiscount, index;
+
+ if( !cod_info->big_values )
+ { /* no big_values region */
+ cod_info->region0_count = 0;
+ cod_info->region1_count = 0;
+ }
+ else
+ {
+ bigvalues_region = 2 * cod_info->big_values;
+
+ /* Calculate scfb_anz */
+ while( scalefac[scfb_anz] < bigvalues_region )
+ scfb_anz++;
+
+ cod_info->region0_count = subdv_table[scfb_anz].region0_count;
+ thiscount = cod_info->region0_count;
+ index = thiscount + 1;
+ while(thiscount && (scalefac[index] > bigvalues_region))
+ {
+ thiscount--;
+ index--;
+ }
+ cod_info->region0_count = thiscount;
+ cod_info->region1_count = subdv_table[scfb_anz].region1_count;
+ index = cod_info->region0_count + cod_info->region1_count + 2;
+ thiscount = cod_info->region1_count;
+ while(thiscount && (scalefac[index] > bigvalues_region))
+ {
+ thiscount--;
+ index--;
+ }
+ cod_info->region1_count = thiscount;
+ cod_info->address1 = scalefac[cod_info->region0_count+1];
+ cod_info->address2 = scalefac[cod_info->region0_count+cod_info->region1_count+2];
+ cod_info->address3 = bigvalues_region;
+ }
+}
+
+/*************************************************************************/
+/* Function: Select huffman code tables for bigvalues regions */
+/*************************************************************************/
+void bigv_tab_select( uint16 ix[SAMP_PER_FRAME2], side_info_t *cod_info )
+{
+ cod_info->table_select[0] = 0;
+ cod_info->table_select[1] = 0;
+ cod_info->table_select[2] = 0;
+
+ if( cod_info->address1 > 0 )
+ cod_info->table_select[0] = new_choose_table(ix, 0 , cod_info->address1);
+
+ if( cod_info->address2 > cod_info->address1 )
+ cod_info->table_select[1] = new_choose_table(ix, cod_info->address1, cod_info->address2);
+
+ if( cod_info->big_values<<1 > cod_info->address2 )
+ cod_info->table_select[2] = new_choose_table(ix, cod_info->address2, cod_info->big_values<<1);
+}
+
+/*************************************************************************/
+/* Function: Count the number of bits necessary to code the bigvalues region */
+/*************************************************************************/
+int bigv_bitcount(uint16 ix[SAMP_PER_FRAME2], side_info_t *gi)
+{
+ int bits = 0;
+ uint32 table;
+
+ if((table=gi->table_select[0])) /* region0 */
+ bits += count_bit(ix, 0 , gi->address1, table);
+
+ if((table=gi->table_select[1])) /* region1 */
+ bits += count_bit(ix, gi->address1, gi->address2, table);
+
+ if((table=gi->table_select[2])) /* region2 */
+ bits += count_bit(ix, gi->address2, gi->address3, table);
+
+ return bits;
+}
+
+int quantcnt;
+
+/* Speed up the outer_loop code which is called by iteration_loop.
+ The outer_loop function precedes the call to the function inner_loop
+ with a call to bin_search gain defined below,
+ which returns a good starting quantizerStepSize. */
+int quantize_and_count_bits(int xr[SAMP_PER_FRAME2], uint16 ix[SAMP_PER_FRAME2], side_info_t *cod_info)
+{
+ int bits = 10000;
+
+ quantcnt++;
+
+ if(quantize_int(xr, ix, cod_info))
+ {
+ bits = calc_runlen(ix, cod_info); /* rzero,count1,big_values*/
+ subdivide(cod_info); /* bigvalues sfb division */
+ bigv_tab_select(ix,cod_info); /* codebook selection*/
+ bits += bigv_bitcount(ix,cod_info); /* bit count */
+ }
+
+ return bits;
+}
+
+/******************************************************************************/
+/* The code selects the best quantizerStepSize for a particular set of scalefacs */
+/******************************************************************************/
+int inner_loop_int(int xr[2][2][SAMP_PER_FRAME2], int max_bits, side_info_t *cod_info, int gr, int ch )
+{
+ int *xrs; /* int[SAMP_PER_FRAME2] *xr; */
+ uint16 *ix; /* int[SAMP_PER_FRAME2] *ix; */
+ int bits;
+
+ xrs = &xr[gr][ch][0];
+ ix = enc_data[gr][ch];
+
+ while((bits=quantize_and_count_bits(xrs, ix, cod_info)) < max_bits-64)
+ {
+ if(cod_info->quantizerStepSize == 0)
+ break;
+
+ if(cod_info->quantizerStepSize <= 2)
+ cod_info->quantizerStepSize = 0;
+ else
+ cod_info->quantizerStepSize -= 2;
+ }
+
+ while(bits > max_bits)
+ {
+ cod_info->quantizerStepSize++;
+ bits = quantize_and_count_bits(xrs, ix, cod_info);
+ }
+
+ return bits;
+}
+
+/************************************************************************/
+/* iteration_loop() */
+/************************************************************************/
+void iteration_loop(int mdct_freq_org[2][2][SAMP_PER_FRAME2], side_info_t cod_info[2][2], int mean_bits)
+{
+ int max_bits;
+ int ch, gr;
+ int ResvSize = 0; /* Layer3 bit reservoir: Described in C.1.5.4.2.2 of the IS */
+
+ for(gr=2; gr--; )
+ {
+ for(ch=cfg.channels; ch--; )
+ {
+ /* calculation of number of available bit( per granule ) */
+ max_bits = mean_bits / cfg.channels;
+
+ cod_info[gr][ch].big_values = 0;
+ cod_info[gr][ch].count1 = 0;
+ cod_info[gr][ch].table_select[0] = 0;
+ cod_info[gr][ch].table_select[1] = 0;
+ cod_info[gr][ch].table_select[2] = 0;
+ cod_info[gr][ch].region0_count = 0;
+ cod_info[gr][ch].region1_count = 0;
+ cod_info[gr][ch].table_select[3] = 0;
+ cod_info[gr][ch].part2_3_length = inner_loop_int(mdct_freq_org, max_bits, &cod_info[gr][ch], gr, ch);
+ cod_info[gr][ch].global_gain = cod_info[gr][ch].quantizerStepSize + 210 - 0x40;
+
+ /* Readjusts the size of the reservoir to reflect the granule's usage */
+ ResvSize += max_bits - cod_info[gr][ch].part2_3_length;
+ }
+ }
+
+/* Makes sure that the reservoir size is within limits, possibly by adding
+ stuffing bits. Note that stuffing bits are added by increasing a granule's
+ part2_3_length */
+ cod_info[0][0].part2_3_length += ResvSize;
+}
+
+/*-------------------------------------------------------------------*/
+/* Function: Calculation of the MDCT */
+/* In the case of long blocks ( block_type 0,1,3 ) there are */
+/* 36 coefficents in the time domain and 18 in the frequency */
+/* domain. */
+/*-------------------------------------------------------------------*/
+
+/* TODO: This MDCT implementation is very crude, and should be replaced by
+ a completely different algorithm. */
+void mdct_int( int *in, int *out )
+{
+ int m, tmp=0;
+
+ for(m=18; m--; )
+ {
+#ifdef CPU_COLDFIRE
+ { int *wint = win_int[m];
+ int *indat = in;
+
+ asm volatile(
+ "movem.l (%[indat]), %%d0-%%d7\n"
+ "move.l (%[wint])+, %%a5\n"
+ "mac.l %%d0, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d1, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d2, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d3, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d4, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d5, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d6, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d7, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "movem.l (32,%[indat]), %%d0-%%d7\n"
+ "mac.l %%d0, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d1, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d2, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d3, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d4, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d5, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d6, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d7, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "movem.l (64,%[indat]), %%d0-%%d7\n"
+ "mac.l %%d0, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d1, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d2, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d3, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d4, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d5, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d6, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d7, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "movem.l (96,%[indat]), %%d0-%%d7\n"
+ "mac.l %%d0, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d1, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d2, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d3, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d4, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d5, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d6, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d7, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "movem.l (128,%[indat]), %%d0-%%d3\n"
+ "mac.l %%d0, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d1, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d2, %%a5, (%[wint])+, %%a5, %%acc0\n"
+ "mac.l %%d3, %%a5, %%acc0\n"
+ "movclr.l %%acc0, %[tmp]"
+ : [wint] "+a" (wint), [tmp] "+r" (tmp) : [indat] "a" (indat)
+ : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
+ }
+#else
+ int k;
+ for(k=36,tmp=0; k--; )
+ tmp += in[k] * win_int[m][k];
+#endif
+ out[m] = (tmp + 16384) >> 15;
+ }
+}
+
+
+void mdct_sub_int(int sb_sample[2][3][18][SBLIMIT], int (*mdct_freq)[2][SAMP_PER_FRAME2])
+{
+ int (*mdct_enc)[2][32][18] = (int (*)[2][32][18]) mdct_freq;
+ int ch, gr, band, k, bu, bd;
+
+ for(gr=0; gr<2; gr++)
+ for(ch=cfg.channels; ch--; )
+ {
+ /* 576=4*16*9: Compensate for inversion in the analysis filter */
+ for(band=33; (band-=2)>0; )
+ for(k=19; (k-=2)>0; )
+ sb_sample[ch][gr+1][k][band] = -sb_sample[ch][gr+1][k][band];
+
+ /* 82944=4*32*648: Perform imdct of 18 previous subband samples + 18 current subband samples */
+ for(band=32; band--; )
+ {
+ for(k=18; k--; )
+ {
+ mdct_in[k] = sb_sample[ch][ gr ][k][band];
+ mdct_in[k+18] = sb_sample[ch][gr+1][k][band];
+ }
+
+ mdct_int(mdct_in, &mdct_enc[gr][ch][band][0]);
+ }
+
+ /* 1024=4*256: Perform aliasing reduction butterfly*/
+ for(band=31; band--; )
+ for(k=8; k--; )
+ {
+ bu = mdct_enc[gr][ch][band][17-k] * cs_int[k] + mdct_enc[gr][ch][band+1][k] * ca_int[k];
+ bd = mdct_enc[gr][ch][band+1][k] * cs_int[k] - mdct_enc[gr][ch][band][17-k] * ca_int[k];
+ mdct_enc[gr][ch][band][17-k] = (bu + 16384) >> 15;
+ mdct_enc[gr][ch][band+1][k] = (bd + 16384) >> 15;
+ }
+ }
+
+ /* Save latest granule's subband samples to be used in the next mdct call */
+ for(ch=cfg.channels ;ch--; )
+ memcpy(sb_sample[ch][0], sb_sample[ch][2], 18 * 32 * sizeof(int));
+}
+
+void fill_subband(long *buffer, int off)
+{
+ long i, t;
+
+ /* replace 32 oldest left/right samples with 32 new samples */
+ if(enc_channels == 2)
+ {
+ for(i=32; i--; )
+ {
+ t = *buffer++;
+ x_int0[i+off] = (short)(t >> 16);
+ x_int1[i+off] = (short)t;
+ }
+ }
+ else
+ {
+ for(i=32; i--; )
+ {
+ t = *buffer++;
+ x_int0[i+off] = (short)((((t<<16)>>16) + (t>>16)) >> 1);
+ }
+ }
+}
+
+void filter_subband(int s[SBLIMIT], int off, int k)
+{
+ short *enwindow = enwindow_int;
+ int i, tmp = 0;
+#ifdef CPU_COLDFIRE
+ int reg_buff[14]; /* register storage buffer */
+#endif
+
+ /* 36864=72*512: shift samples into proper window positions */
+#ifdef CPU_COLDFIRE
+ { short *xint = &x_int[k][off];
+ short *yint = y_int;
+
+ asm volatile ("movem.l %%d0/%%d2-%%d7/%%a2-%%a7,%0\n" : "=m" (*(int*)reg_buff));
+ asm volatile(
+ "moveq.l #32, %%d0\n"
+ "move.l %%d0, %[i]\n" /* set loop counter */
+ "move.l %[xint], %%d0\n" /* d0 = x_int[k] */
+ "or.l #0x3ff, %%d0\n"
+ "move.l %%d0, %%mask\n" /* set address mask */
+ "move.l (%[xint]), %%d4\n" /* d4 = x_int[k][off] */
+
+ "loop_start:\n"
+ "movem.l (%[enwindow]), %%d0-%%d3\n" /* load 4 values */
+ "mac.w %%d0u, %%d4u, (0x080,%[xint])&, %%d5, %%acc0\n"
+ "mac.w %%d0l, %%d5u, (0x100,%[xint])&, %%d6, %%acc0\n"
+ "mac.w %%d1u, %%d6u, (0x180,%[xint])&, %%d7, %%acc0\n"
+ "mac.w %%d1l, %%d7u, (0x200,%[xint])&, %%a2, %%acc0\n"
+ "mac.w %%d2u, %%a2u, (0x280,%[xint])&, %%a3, %%acc0\n"
+ "mac.w %%d2l, %%a3u, (0x300,%[xint])&, %%a4, %%acc0\n"
+ "mac.w %%d3u, %%a4u, (0x380,%[xint])&, %%a5, %%acc0\n"
+ "mac.w %%d3l, %%a5u, %%acc0\n"
+
+ "movem.l (16,%[enwindow]), %%d0-%%d3\n" /* load 8 values */
+ "mac.w %%d0u, %%d4l, %%acc1\n"
+ "mac.w %%d0l, %%d5l, %%acc1\n"
+ "mac.w %%d1u, %%d6l, %%acc1\n"
+ "mac.w %%d1l, %%d7l, %%acc1\n"
+ "mac.w %%d2u, %%a2l, %%acc1\n"
+ "mac.w %%d2l, %%a3l, %%acc1\n"
+ "mac.w %%d3u, %%a4l, %%acc1\n"
+ "addq.l #4, %[xint]\n" /* xint += 2 */
+ "mac.w %%d3l, %%a5l, (%[xint])&, %%d4, %%acc1\n"
+
+ "movclr.l %%acc0, %%d5\n"
+ "movclr.l %%acc1, %%d6\n"
+ "move.l #262144, %%d7\n"
+ "add.l %%d7, %%d5\n"
+ "add.l %%d7, %%d6\n"
+ "moveq.l #19, %%d7\n"
+ "asr.l %%d7, %%d5\n"
+ "asr.l %%d7, %%d6\n"
+ "move.w %%d5, (%[yint])+\n"
+ "move.w %%d6, (%[yint])+\n"
+
+ "add.l #32, %[enwindow]\n" /* enwindow += 16 */
+
+ "sub.l #1, %[i]\n"
+ "jbne loop_start\n"
+
+ : [xint] "+a" (xint), [yint] "+a" (yint), [i] "+m" (i)
+ : [enwindow] "a" (enwindow)
+ : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a2", "a3", "a4", "a5");
+
+ asm volatile ("movem.l %0,%%d0/%%d2-%%d7/%%a2-%%a7\n" : : "m" (*(int*)reg_buff));
+ }
+#else
+ for(i=0; i<64; i++)
+ {
+ for(j=0, tmp=0; j<512; j+=64)
+ tmp += (int)x_int[k][(i+j+off)&(HAN_SIZE-1)] * (int)*(enwindow++);
+ y_int[i] = (short)((tmp + (1<<18)) >> 19);
+ }
+#endif
+
+ /* 147456=72*2048 */
+ for(i=SBLIMIT; i--; ) // SBLIMIT: 32
+ {
+ short *filt = filter_int[i];
+
+#ifdef CPU_COLDFIRE
+ {
+ asm volatile(
+ "move.l (%[yint])+, %%a5\n"
+ "movem.l (%[filt]), %%d0-%%d7\n"
+ "mac.w %%d0u, %%a5u, %%acc0\n"
+ "mac.w %%d0l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d1u, %%a5u, %%acc0\n"
+ "mac.w %%d1l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d2u, %%a5u, %%acc0\n"
+ "mac.w %%d2l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d3u, %%a5u, %%acc0\n"
+ "mac.w %%d3l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d4u, %%a5u, %%acc0\n"
+ "mac.w %%d4l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d5u, %%a5u, %%acc0\n"
+ "mac.w %%d5l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d6u, %%a5u, %%acc0\n"
+ "mac.w %%d6l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d7u, %%a5u, %%acc0\n"
+ "mac.w %%d7l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "movem.l (32,%[filt]), %%d0-%%d7\n"
+ "mac.w %%d0u, %%a5u, %%acc0\n"
+ "mac.w %%d0l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d1u, %%a5u, %%acc0\n"
+ "mac.w %%d1l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d2u, %%a5u, %%acc0\n"
+ "mac.w %%d2l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d3u, %%a5u, %%acc0\n"
+ "mac.w %%d3l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d4u, %%a5u, %%acc0\n"
+ "mac.w %%d4l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d5u, %%a5u, %%acc0\n"
+ "mac.w %%d5l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d6u, %%a5u, %%acc0\n"
+ "mac.w %%d6l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d7u, %%a5u, %%acc0\n"
+ "mac.w %%d7l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "movem.l (64,%[filt]), %%d0-%%d7\n"
+ "mac.w %%d0u, %%a5u, %%acc0\n"
+ "mac.w %%d0l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d1u, %%a5u, %%acc0\n"
+ "mac.w %%d1l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d2u, %%a5u, %%acc0\n"
+ "mac.w %%d2l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d3u, %%a5u, %%acc0\n"
+ "mac.w %%d3l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d4u, %%a5u, %%acc0\n"
+ "mac.w %%d4l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d5u, %%a5u, %%acc0\n"
+ "mac.w %%d5l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d6u, %%a5u, %%acc0\n"
+ "mac.w %%d6l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d7u, %%a5u, %%acc0\n"
+ "mac.w %%d7l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "movem.l (96,%[filt]), %%d0-%%d7\n"
+ "mac.w %%d0u, %%a5u, %%acc0\n"
+ "mac.w %%d0l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d1u, %%a5u, %%acc0\n"
+ "mac.w %%d1l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d2u, %%a5u, %%acc0\n"
+ "mac.w %%d2l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d3u, %%a5u, %%acc0\n"
+ "mac.w %%d3l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d4u, %%a5u, %%acc0\n"
+ "mac.w %%d4l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d5u, %%a5u, %%acc0\n"
+ "mac.w %%d5l, %%a5l, (%[yint])+, %%a5, %%acc0\n"
+ "mac.w %%d6u, %%a5u, %%acc0\n"
+ "mac.w %%d6l, %%a5l, (%[yint]) , %%a5, %%acc0\n"
+ "mac.w %%d7u, %%a5u, %%acc0\n"
+ "mac.w %%d7l, %%a5l, %%acc0\n"
+ "lea.l (-31*4, %[yint]), %[yint]\n" /* wrap yint back to start */
+ "movclr.l %%acc0, %[tmp]"
+ : [tmp] "=r" (tmp) : [filt] "a" (filt), [yint] "a" (y_int)
+ : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5" );
+ }
+#else
+ for(j=64, tmp=0; j--; )
+ tmp += (long)filt[j] * (long)y_int[j];
+#endif
+ s[i] = (tmp + 16384) >> 15;
+ }
+}
+
+static int find_bitrate_index(int bitrate)
+{
+ static long mpeg1[15] = {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320};
+ int i;
+
+ for(i=0; i<15; i++)
+ if(bitrate == mpeg1[i])
+ return i;
+
+ return -1;
+}
+
+static int find_samplerate_index(long freq)
+{
+ static long mpeg1[3] = {44100, 48000, 32000};
+ int i;
+
+ for(i=0; i<3; i++)
+ if(freq == mpeg1[i])
+ return i;
+
+ return -1;
+}
+
+void init_mp3_encoder_engine(bool stereo, int quality)
+{
+ /* keep in sync with rec_quality_info_afmt in id3.h/.c */
+ static int bitr_s[9] = { 64, 96, 128, 160, 192, 224, 320, 64, 64 };
+ static int bitr_m[9] = { 64, 96, 128, 160, 160, 160, 160, 64, 64 };
+ uint32 avg_byte_per_frame;
+
+ cfg.byte_order = order_bigEndian;
+ cfg.mpg.type = 1;
+ cfg.samplerate = 44100;
+ cfg.channels = stereo ? 2 : 1;
+ cfg.mpg.mode = stereo ? 0 : 3; /* 0=stereo, 3=mono */
+ cfg.mpg.bitrate = stereo ? bitr_s[quality] : bitr_m[quality];
+ cfg.mpg.bitrate_index = find_bitrate_index(cfg.mpg.bitrate);
+ cfg.mpg.smprate_index = find_samplerate_index(cfg.samplerate);
+
+ memset(x_int0 , 0 , sizeof(x_int0 ));
+ memset(x_int1 , 0 , sizeof(x_int1 ));
+ memset(y_int , 0 , sizeof(y_int ));
+ memset(mdct_freq , 0 , sizeof(mdct_freq ));
+ memset(enc_data , 0 , sizeof(enc_data ));
+ memset(mdct_in , 0 , sizeof(mdct_in ));
+ memset(sb_sample , 0 , sizeof(sb_sample ));
+ memset(&CodedData , 0 , sizeof(CodedData ));
+ memcpy(scalefac, sfBand[cfg.mpg.smprate_index + 3*cfg.mpg.type], sizeof(scalefac));
+ memcpy(ca_int , ca_int_const , sizeof(ca_int ));
+ memcpy(cs_int , cs_int_const , sizeof(cs_int ));
+ memcpy(win_int , win_int_const , sizeof(win_int ));
+ memcpy(filter_int , filter_int_const , sizeof(filter_int ));
+ memcpy(enwindow_int, enwindow_int_const, sizeof(enwindow_int));
+ memcpy(int2idx , int2idx_const , sizeof(int2idx ));
+ memcpy(ht_count1 , ht_count1_const , sizeof(ht_count1 ));
+ memcpy( t1HB , t1HB_const , sizeof(t1HB ));
+ memcpy( t2HB , t2HB_const , sizeof(t2HB ));
+ memcpy( t3HB , t3HB_const , sizeof(t3HB ));
+ memcpy( t5HB , t5HB_const , sizeof(t5HB ));
+ memcpy( t6HB , t6HB_const , sizeof(t6HB ));
+ memcpy( t7HB , t7HB_const , sizeof(t7HB ));
+ memcpy( t8HB , t8HB_const , sizeof(t8HB ));
+ memcpy( t9HB , t9HB_const , sizeof(t9HB ));
+ memcpy(t10HB , t10HB_const , sizeof(t10HB ));
+ memcpy(t11HB , t11HB_const , sizeof(t11HB ));
+ memcpy(t12HB , t12HB_const , sizeof(t12HB ));
+ memcpy(t13HB , t13HB_const , sizeof(t13HB ));
+ memcpy(t15HB , t15HB_const , sizeof(t15HB ));
+ memcpy(t16HB , t16HB_const , sizeof(t16HB ));
+ memcpy(t24HB , t24HB_const , sizeof(t24HB ));
+ memcpy( t1l , t1l_const , sizeof(t1l ));
+ memcpy( t2l , t2l_const , sizeof(t2l ));
+ memcpy( t3l , t3l_const , sizeof(t3l ));
+ memcpy( t5l , t5l_const , sizeof(t5l ));
+ memcpy( t6l , t6l_const , sizeof(t6l ));
+ memcpy( t7l , t7l_const , sizeof(t7l ));
+ memcpy( t8l , t8l_const , sizeof(t8l ));
+ memcpy( t9l , t9l_const , sizeof(t9l ));
+ memcpy(t10l , t10l_const , sizeof(t10l ));
+ memcpy(t11l , t11l_const , sizeof(t11l ));
+ memcpy(t12l , t12l_const , sizeof(t12l ));
+ memcpy(t13l , t13l_const , sizeof(t13l ));
+ memcpy(t15l , t15l_const , sizeof(t15l ));
+ memcpy(t16l , t16l_const , sizeof(t16l ));
+ memcpy(t24l , t24l_const , sizeof(t24l ));
+ memcpy(ht , ht_const , sizeof(ht ));
+
+ /* I don't know, wether this is really necessary */
+ ht[ 0].table = NULL; ht[ 0].hlen = NULL;// Apparently not used
+ ht[ 1].table = t1HB; ht[ 1].hlen = t1l;
+ ht[ 2].table = t2HB; ht[ 2].hlen = t2l;
+ ht[ 3].table = t3HB; ht[ 3].hlen = t3l;
+ ht[ 4].table = NULL; ht[ 4].hlen = NULL;// Apparently not used
+ ht[ 5].table = t5HB; ht[ 5].hlen = t5l;
+ ht[ 6].table = t6HB; ht[ 6].hlen = t6l;
+ ht[ 7].table = t7HB; ht[ 7].hlen = t7l;
+ ht[ 8].table = t8HB; ht[ 8].hlen = t8l;
+ ht[ 9].table = t9HB; ht[ 9].hlen = t9l;
+ ht[10].table = t10HB; ht[10].hlen = t10l;
+ ht[11].table = t11HB; ht[11].hlen = t11l;
+ ht[12].table = t12HB; ht[12].hlen = t12l;
+ ht[13].table = t13HB; ht[13].hlen = t13l;
+ ht[14].table = NULL; ht[14].hlen = NULL;// Apparently not used
+ ht[15].table = t15HB; ht[15].hlen = t15l;
+ ht[16].table = t16HB; ht[16].hlen = t16l;
+ ht[17].table = t16HB; ht[17].hlen = t16l;
+ ht[18].table = t16HB; ht[18].hlen = t16l;
+ ht[19].table = t16HB; ht[19].hlen = t16l;
+ ht[20].table = t16HB; ht[20].hlen = t16l;
+ ht[21].table = t16HB; ht[21].hlen = t16l;
+ ht[22].table = t16HB; ht[22].hlen = t16l;
+ ht[23].table = t16HB; ht[23].hlen = t16l;
+ ht[24].table = t24HB; ht[24].hlen = t24l;
+ ht[25].table = t24HB; ht[25].hlen = t24l;
+ ht[26].table = t24HB; ht[26].hlen = t24l;
+ ht[27].table = t24HB; ht[27].hlen = t24l;
+ ht[28].table = t24HB; ht[28].hlen = t24l;
+ ht[29].table = t24HB; ht[29].hlen = t24l;
+ ht[30].table = t24HB; ht[30].hlen = t24l;
+ ht[31].table = t24HB; ht[31].hlen = t24l;
+
+ x_int[0] = x_int0;
+ x_int[1] = x_int1;
+
+#ifndef SIMULATOR
+ if(((long)x_int0 | (long)x_int1) & 0x7ff)
+ return; /* both arrays must be aligned to 0x800 boundary */
+#endif
+
+ if(cfg.channels == 1)
+ cfg.sideinfo_len = 32 + 136;
+ else
+ cfg.sideinfo_len = 32 + 256;
+
+ /* Set initial step size */
+ cfg.cod_info[0][0].quantizerStepSize = 0x10;
+ cfg.cod_info[0][1].quantizerStepSize = 0x10;
+ cfg.cod_info[1][0].quantizerStepSize = 0x10;
+ cfg.cod_info[1][1].quantizerStepSize = 0x10;
+
+ /* Figure average number of 'byte' per frame. */
+ avg_byte_per_frame = (uint32)(SAMP_PER_FRAME * 8000 * cfg.mpg.bitrate) / cfg.samplerate;
+ cfg.byte_per_frame = avg_byte_per_frame / 64;
+ cfg.frac_per_frame = avg_byte_per_frame % 64;
+ cfg.slot_lag = 0;
+}
+
+/* this is the codec entry point */
+enum codec_status codec_start(struct codec_api* api)
+{
+ int i, off=0, gr, channel;
+ long *buffer;
+ int chunk_size, num_chunks;
+ int enc_buffer_size;
+ int enc_quality;
+ uint32 *mp3_chunk_ptr;
+ bool cpu_boosted = true; /* start boosted */
+
+ /* Generic codec initialisation */
+ ci = api;
+
+ if(ci->enc_get_inputs == NULL ||
+ ci->enc_set_parameters == NULL ||
+ ci->enc_alloc_chunk == NULL ||
+ ci->enc_free_chunk == NULL ||
+ ci->enc_wavbuf_near_empty == NULL ||
+ ci->enc_get_wav_data == NULL ||
+ ci->enc_set_header_callback == NULL )
+ return CODEC_ERROR;
+
+ ci->cpu_boost(true);
+
+ *ci->enc_set_header_callback = NULL;
+ ci->enc_get_inputs(&enc_buffer_size, &enc_channels, &enc_quality);
+
+ init_mp3_encoder_engine(enc_channels == 2, enc_quality);
+
+ /* must be 4byte aligned */
+ chunk_size = (sizeof(long) + cfg.byte_per_frame + 1 + 3) & ~3;
+ num_chunks = enc_buffer_size / chunk_size;
+
+ /* inform the main program about the buffer dimensions */
+ ci->enc_set_parameters(chunk_size, num_chunks, SAMP_PER_FRAME,
+ NULL, 0, AFMT_MPA_L3);
+
+#ifdef CPU_COLDFIRE
+ asm volatile ("move.l #0, %macsr"); /* integer mode */
+#endif
+
+ /* main application waits for this flag during encoder loading */
+ ci->enc_codec_loaded = true;
+
+ /* main encoding loop */
+ while(!ci->stop_codec)
+ {
+ while((buffer = (long*)ci->enc_get_wav_data(SAMP_PER_FRAME*4)) != NULL)
+ {
+ if(ci->stop_codec)
+ break;
+
+ if(ci->enc_wavbuf_near_empty() == 0)
+ {
+ if(!cpu_boosted)
+ {
+ ci->cpu_boost(true);
+ cpu_boosted = true;
+ }
+ }
+
+ /* encode one mp3 frame in this loop */
+ CodedData.bitpos = 0;
+ memset(CodedData.bbuf, 0, sizeof(CodedData.bbuf));
+
+ if((cfg.slot_lag += cfg.frac_per_frame) >= 64)
+ { /* Padding for this frame */
+ cfg.slot_lag -= 64;
+ cfg.mpg.padding = 1;
+ }
+ else
+ cfg.mpg.padding = 0;
+
+ cfg.mpg.bits_per_frame = 8 * (cfg.byte_per_frame + cfg.mpg.padding);
+ cfg.mean_bits = (cfg.mpg.bits_per_frame - cfg.sideinfo_len) >> 1;
+
+ /* polyphase filtering */
+ for(gr=0; gr<2; gr++)
+ {
+ for(i=0; i<18; i++)
+ {
+ fill_subband(buffer, off);
+
+ for(channel=cfg.channels; channel--; )
+ filter_subband(&sb_sample[channel][gr+1][i][0], off, channel);
+
+ buffer += 32;
+ off = (off + 480) & (HAN_SIZE-1); /* offset is modulo HAN_SIZE */
+ }
+ }
+
+ mdct_sub_int(sb_sample, mdct_freq);
+
+ /* bit and noise allocation */
+ iteration_loop(mdct_freq, cfg.cod_info, cfg.mean_bits);
+
+ /* write the frame to the bitstream */
+ format_bitstream(enc_data, cfg.cod_info, mdct_freq);
+
+ /* allocate mp3 chunk, set chunk size, copy chunk to enc_buffer */
+ mp3_chunk_ptr = (uint32*)ci->enc_alloc_chunk();
+ mp3_chunk_ptr[0] = (CodedData.bitpos + 7) >> 3;
+ memcpy(&mp3_chunk_ptr[1], CodedData.bbuf, mp3_chunk_ptr[0]);
+ ci->enc_free_chunk();
+ ci->yield();
+ }
+
+ if(ci->enc_wavbuf_near_empty())
+ {
+ if(cpu_boosted)
+ {
+ ci->cpu_boost(false);
+ cpu_boosted = false;
+ }
+ }
+ ci->yield();
+ }
+
+ if(cpu_boosted) /* set initial boost state */
+ ci->cpu_boost(false);
+
+ /* reset parameters to initial state */
+ ci->enc_set_parameters(0, 0, 0, 0, 0, 0);
+
+ /* main application waits for this flag during encoder removing */
+ ci->enc_codec_loaded = false;
+
+ return CODEC_OK;
+}
+#endif
diff --git a/apps/codecs/wav_enc.c b/apps/codecs/wav_enc.c
new file mode 100644
index 0000000000..5aabb5d8e8
--- /dev/null
+++ b/apps/codecs/wav_enc.c
@@ -0,0 +1,172 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 Antonius Hellmann
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef SIMULATOR
+
+#include "codeclib.h"
+
+CODEC_HEADER
+
+static struct codec_api *ci;
+static int enc_channels;
+
+#define CHUNK_SIZE 8192
+
+static unsigned char wav_header[44] =
+{'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',16,
+ 0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0,4,0,16,0,'d','a','t','a',0,0,0,0};
+
+static unsigned char wav_header_mono[44] =
+{'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',16,
+ 0,0,0,1,0,1,0,0x44,0xac,0,0,0x88,0x58,1,0,2,0,16,0,'d','a','t','a',0,0,0,0};
+
+/* update file header info callback function (called by main application) */
+void enc_set_header(void *head_buffer, /* ptr to the file header data */
+ int head_size, /* size of this header data */
+ int num_pcm_samples, /* amount of processed pcm samples */
+ bool is_file_header)
+{
+ int num_file_bytes = num_pcm_samples * 2 * enc_channels;
+
+ if(is_file_header)
+ {
+ /* update file header before file closing */
+ if((int)sizeof(wav_header) < head_size)
+ {
+ /* update wave header size entries: special to WAV format */
+ *(long*)(head_buffer+ 4) = htole32(num_file_bytes + 36);
+ *(long*)(head_buffer+40) = htole32(num_file_bytes);
+ }
+ }
+}
+
+/* main codec entry point */
+enum codec_status codec_start(struct codec_api* api)
+{
+ int i;
+ long lr;
+ unsigned long t;
+ unsigned long *src;
+ unsigned long *dst;
+ int chunk_size, num_chunks, samp_per_chunk;
+ int enc_buffer_size;
+ int enc_quality;
+ bool cpu_boosted = true; /* start boosted */
+
+ ci = api; // copy to global api pointer
+
+ if(ci->enc_get_inputs == NULL ||
+ ci->enc_set_parameters == NULL ||
+ ci->enc_alloc_chunk == NULL ||
+ ci->enc_free_chunk == NULL ||
+ ci->enc_wavbuf_near_empty == NULL ||
+ ci->enc_get_wav_data == NULL ||
+ ci->enc_set_header_callback == NULL )
+ return CODEC_ERROR;
+
+ ci->cpu_boost(true);
+
+ *ci->enc_set_header_callback = enc_set_header;
+ ci->enc_get_inputs(&enc_buffer_size, &enc_channels, &enc_quality);
+
+ /* configure the buffer system */
+ chunk_size = sizeof(long) + CHUNK_SIZE * enc_channels / 2;
+ num_chunks = enc_buffer_size / chunk_size;
+ samp_per_chunk = CHUNK_SIZE / 4;
+
+ /* inform the main program about buffer dimensions and other params */
+ ci->enc_set_parameters(chunk_size, num_chunks, samp_per_chunk,
+ (enc_channels == 2) ? wav_header : wav_header_mono,
+ sizeof(wav_header), AFMT_PCM_WAV);
+
+ /* main application waits for this flag during encoder loading */
+ ci->enc_codec_loaded = true;
+
+ /* main encoding loop */
+ while(!ci->stop_codec)
+ {
+ while((src = (unsigned long*)ci->enc_get_wav_data(CHUNK_SIZE)) != NULL)
+ {
+ if(ci->stop_codec)
+ break;
+
+ if(ci->enc_wavbuf_near_empty() == 0)
+ {
+ if(!cpu_boosted)
+ {
+ ci->cpu_boost(true);
+ cpu_boosted = true;
+ }
+ }
+
+ dst = (unsigned long*)ci->enc_alloc_chunk();
+ *dst++ = CHUNK_SIZE * enc_channels / 2; /* set size info */
+
+ if(enc_channels == 2)
+ {
+ /* swap byte order & copy to destination */
+ for (i=0; i<CHUNK_SIZE/4; i++)
+ {
+ t = *src++;
+ *dst++ = ((t >> 8) & 0xff00ff) | ((t << 8) & 0xff00ff00);
+ }
+ }
+ else
+ {
+ /* mix left/right, swap byte order & copy to destination */
+ for (i=0; i<CHUNK_SIZE/8; i++)
+ {
+ lr = (long)*src++;
+ lr = (((lr<<16)>>16) + (lr>>16)) >> 1; /* left+right */
+ t = (lr << 16);
+ lr = (long)*src++;
+ lr = (((lr<<16)>>16) + (lr>>16)) >> 1; /* left+right */
+ t |= lr & 0xffff;
+ *dst++ = ((t >> 8) & 0xff00ff) | ((t << 8) & 0xff00ff00);
+ }
+ }
+
+ ci->enc_free_chunk();
+ ci->yield();
+ }
+
+ if(ci->enc_wavbuf_near_empty())
+ {
+ if(cpu_boosted)
+ {
+ ci->cpu_boost(false);
+ cpu_boosted = false;
+ }
+ }
+
+ ci->yield();
+ }
+
+ if(cpu_boosted) /* set initial boost state */
+ ci->cpu_boost(false);
+
+ /* reset parameters to initial state */
+ ci->enc_set_parameters(0, 0, 0, 0, 0, 0);
+
+ /* main application waits for this flag during encoder removing */
+ ci->enc_codec_loaded = false;
+
+ return CODEC_OK;
+}
+#endif
diff --git a/apps/codecs/wavpack_enc.c b/apps/codecs/wavpack_enc.c
new file mode 100644
index 0000000000..cde208739f
--- /dev/null
+++ b/apps/codecs/wavpack_enc.c
@@ -0,0 +1,230 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 Antonius Hellmann
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef SIMULATOR
+
+#include "codeclib.h"
+#include "libwavpack/wavpack.h"
+
+CODEC_HEADER
+
+typedef unsigned long uint32;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+
+static unsigned char wav_header_ster [46] =
+{33,22,'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',16,
+ 0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0,4,0,16,0,'d','a','t','a',0,0,0,0};
+
+static unsigned char wav_header_mono [46] =
+{33,22,'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',16,
+ 0,0,0,1,0,1,0,0x44,0xac,0,0,0x88,0x58,1,0,2,0,16,0,'d','a','t','a',0,0,0,0};
+
+static struct codec_api *ci;
+static int enc_channels;
+
+#define CHUNK_SIZE 20000
+
+static long input_buffer[CHUNK_SIZE/2] IBSS_ATTR;
+
+void *memset(void *s, int c, size_t n)
+{
+ return(ci->memset(s,c,n));
+}
+
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ return(ci->memcpy(dest,src,n));
+}
+
+/* update file header info callback function */
+void enc_set_header(void *head_buffer, /* ptr to the file header data */
+ int head_size, /* size of this header data */
+ int num_pcm_sampl, /* amount of processed pcm samples */
+ bool is_file_header) /* update file/chunk header */
+{
+ if(is_file_header)
+ {
+ /* update file header before file closing */
+ if(sizeof(WavpackHeader) + sizeof(wav_header_mono) < (unsigned)head_size)
+ {
+ char* riff_header = (char*)head_buffer + sizeof(WavpackHeader);
+ char* wv_header = (char*)head_buffer + sizeof(wav_header_mono);
+ int num_file_bytes = num_pcm_sampl * 2 * enc_channels;
+ unsigned long ckSize;
+
+ /* RIFF header and WVPK header have to be swapped */
+ /* copy wavpack header to file start position */
+ ci->memcpy(head_buffer, wv_header, sizeof(WavpackHeader));
+ wv_header = head_buffer; /* recalc wavpack header position */
+
+ if(enc_channels == 2)
+ ci->memcpy(riff_header, wav_header_ster, sizeof(wav_header_ster));
+ else
+ ci->memcpy(riff_header, wav_header_mono, sizeof(wav_header_mono));
+
+ /* update the Wavpack header first chunk size & total frame count */
+ ckSize = htole32(((WavpackHeader*)wv_header)->ckSize)
+ + sizeof(wav_header_mono);
+ ((WavpackHeader*)wv_header)->total_samples = htole32(num_pcm_sampl);
+ ((WavpackHeader*)wv_header)->ckSize = htole32(ckSize);
+
+ /* update the RIFF WAV header size entries */
+ *(long*)(riff_header+ 6) = htole32(num_file_bytes + 36);
+ *(long*)(riff_header+42) = htole32(num_file_bytes);
+ }
+ }
+ else
+ {
+ /* update timestamp (block_index) */
+ ((WavpackHeader*)head_buffer)->block_index = htole32(num_pcm_sampl);
+ }
+}
+
+
+enum codec_status codec_start(struct codec_api* api)
+{
+ int i;
+ long t;
+ uint32 *src;
+ uint32 *dst;
+ int chunk_size, num_chunks, samp_per_chunk;
+ int enc_buffer_size;
+ int enc_quality;
+ WavpackConfig config;
+ WavpackContext *wpc;
+ bool cpu_boosted = true; /* start boosted */
+
+ ci = api; // copy to global api pointer
+
+ if(ci->enc_get_inputs == NULL ||
+ ci->enc_set_parameters == NULL ||
+ ci->enc_alloc_chunk == NULL ||
+ ci->enc_free_chunk == NULL ||
+ ci->enc_wavbuf_near_empty == NULL ||
+ ci->enc_get_wav_data == NULL ||
+ ci->enc_set_header_callback == NULL )
+ return CODEC_ERROR;
+
+ ci->cpu_boost(true);
+
+ *ci->enc_set_header_callback = enc_set_header;
+ ci->enc_get_inputs(&enc_buffer_size, &enc_channels, &enc_quality);
+
+ /* configure the buffer system */
+ chunk_size = sizeof(long) + CHUNK_SIZE * enc_channels / 2;
+ num_chunks = enc_buffer_size / chunk_size;
+ samp_per_chunk = CHUNK_SIZE / 4;
+
+ /* inform the main program about buffer dimensions and other params */
+ /* add wav_header_mono as place holder to file start position */
+ /* wav header and wvpk header have to be reordered later */
+ ci->enc_set_parameters(chunk_size, num_chunks, samp_per_chunk,
+ wav_header_mono, sizeof(wav_header_mono),
+ AFMT_WAVPACK);
+
+ wpc = WavpackOpenFileOutput ();
+
+ memset (&config, 0, sizeof (config));
+ config.bits_per_sample = 16;
+ config.bytes_per_sample = 2;
+ config.sample_rate = 44100;
+ config.num_channels = enc_channels;
+
+ if (!WavpackSetConfiguration (wpc, &config, 1))
+ return CODEC_ERROR;
+
+ /* main application waits for this flag during encoder loading */
+ ci->enc_codec_loaded = true;
+
+ /* main encoding loop */
+ while(!ci->stop_codec)
+ {
+ while((src = (uint32*)ci->enc_get_wav_data(CHUNK_SIZE)) != NULL)
+ {
+ if(ci->stop_codec)
+ break;
+
+ if(ci->enc_wavbuf_near_empty() == 0)
+ {
+ if(!cpu_boosted)
+ {
+ ci->cpu_boost(true);
+ cpu_boosted = true;
+ }
+ }
+
+ dst = (uint32*)ci->enc_alloc_chunk() + 1;
+
+ WavpackStartBlock (wpc, (uint8*)dst, (uint8*)dst + CHUNK_SIZE);
+
+ if(enc_channels == 2)
+ {
+ for (i=0; i<CHUNK_SIZE/4; i++)
+ {
+ t = (long)*src++;
+
+ input_buffer[2*i + 0] = t >> 16;
+ input_buffer[2*i + 1] = (short)t;
+ }
+ }
+ else
+ {
+ for (i=0; i<CHUNK_SIZE/4; i++)
+ {
+ t = (long)*src++;
+ t = (((t<<16)>>16) + (t>>16)) >> 1; /* left+right */
+
+ input_buffer[i] = t;
+ }
+ }
+
+ if (!WavpackPackSamples (wpc, input_buffer, CHUNK_SIZE/4))
+ return CODEC_ERROR;
+
+ /* finish the chunk and store chunk size info */
+ dst[-1] = WavpackFinishBlock (wpc);
+
+ ci->enc_free_chunk();
+ ci->yield();
+ }
+
+ if(ci->enc_wavbuf_near_empty())
+ {
+ if(cpu_boosted)
+ {
+ ci->cpu_boost(false);
+ cpu_boosted = false;
+ }
+ }
+ ci->yield();
+ }
+
+ if(cpu_boosted) /* set initial boost state */
+ ci->cpu_boost(false);
+
+ /* reset parameters to initial state */
+ ci->enc_set_parameters(0, 0, 0, 0, 0, 0);
+
+ /* main application waits for this flag during encoder removing */
+ ci->enc_codec_loaded = false;
+
+ return CODEC_OK;
+}
+#endif
diff --git a/apps/filetree.c b/apps/filetree.c
index d3ef1e067d..9d5109ceb9 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -445,9 +445,8 @@ int ft_enter(struct tree_context* c)
{
set_file(buf, global_settings.fmr_file, MAX_FILENAME);
radio_load_presets(global_settings.fmr_file);
- if(get_radio_status() != FMRADIO_PLAYING &&
- get_radio_status() != FMRADIO_PAUSED)
- radio_screen();
+ if(!in_radio_screen())
+ radio_screen();
}
/*
* Preset outside default folder, we can choose such only
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 3d87c0cd5d..5687c81e59 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -9661,6 +9661,22 @@
*: "Full Path"
</voice>
</phrase>
+<<<<<<< english.lang
+<phrase>
+ id: VOICE_KBIT_PER_SEC
+ desc: spoken only, for file extension
+ user:
+ <source>
+ *: ""
+ </source>
+ <dest>
+ *: ""
+ </dest>
+ <voice>
+ *: "kilobits per second"
+ </voice>
+</phrase>
+=======
<phrase>
id: LANG_RECORD_AGC_PRESET
desc: automatic gain control in record settings
@@ -9778,3 +9794,4 @@
*: "AGC maximum gain"
</voice>
</phrase>
+>>>>>>> 1.267
diff --git a/apps/main_menu.c b/apps/main_menu.c
index 04527f9329..4348d52f9e 100644
--- a/apps/main_menu.c
+++ b/apps/main_menu.c
@@ -285,9 +285,31 @@ static bool custom_theme_browse(void)
#ifdef HAVE_RECORDING
+static bool rec_menu_recording_screen(void)
+{
+ return recording_screen(false);
+}
+
static bool recording_settings(void)
{
- return recording_menu(false);
+ bool ret;
+#ifdef HAVE_FMRADIO_IN
+ int rec_source = global_settings.rec_source;
+#endif
+
+ ret = recording_menu(false);
+
+#ifdef HAVE_FMRADIO_IN
+ if (rec_source != global_settings.rec_source)
+ {
+ if (rec_source == AUDIO_SRC_FMRADIO)
+ radio_stop();
+ /* If AUDIO_SRC_FMRADIO was selected from something else,
+ the recording screen will start the radio */
+ }
+#endif
+
+ return ret;
}
bool rec_menu(void)
@@ -297,7 +319,7 @@ bool rec_menu(void)
/* recording menu */
static const struct menu_item items[] = {
- { ID2P(LANG_RECORDING_MENU), recording_screen },
+ { ID2P(LANG_RECORDING_MENU), rec_menu_recording_screen },
{ ID2P(LANG_RECORDING_SETTINGS), recording_settings},
};
diff --git a/apps/playback.c b/apps/playback.c
index a37e0ad679..d4f3626f99 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -74,29 +74,18 @@
#include "misc.h"
#include "sound.h"
#include "metadata.h"
+#include "splash.h"
#include "talk.h"
-#ifdef CONFIG_TUNER
-#include "radio.h"
+
+#ifdef HAVE_RECORDING
+#include "recording.h"
#endif
-#include "splash.h"
static volatile bool audio_codec_loaded;
static volatile bool voice_codec_loaded;
static volatile bool playing;
static volatile bool paused;
-#define CODEC_VORBIS "/.rockbox/codecs/vorbis.codec"
-#define CODEC_MPA_L3 "/.rockbox/codecs/mpa.codec"
-#define CODEC_FLAC "/.rockbox/codecs/flac.codec"
-#define CODEC_WAV "/.rockbox/codecs/wav.codec"
-#define CODEC_A52 "/.rockbox/codecs/a52.codec"
-#define CODEC_MPC "/.rockbox/codecs/mpc.codec"
-#define CODEC_WAVPACK "/.rockbox/codecs/wavpack.codec"
-#define CODEC_ALAC "/.rockbox/codecs/alac.codec"
-#define CODEC_AAC "/.rockbox/codecs/aac.codec"
-#define CODEC_SHN "/.rockbox/codecs/shorten.codec"
-#define CODEC_AIFF "/.rockbox/codecs/aiff.codec"
-#define CODEC_SID "/.rockbox/codecs/sid.codec"
/* default point to start buffer refill */
#define AUDIO_DEFAULT_WATERMARK (1024*512)
@@ -133,6 +122,11 @@ enum {
Q_CODEC_LOAD,
Q_CODEC_LOAD_DISK,
+
+#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
+ Q_ENCODER_LOAD_DISK,
+ Q_ENCODER_RECORD,
+#endif
};
/* As defined in plugins/lib/xxx2wav.h */
@@ -382,7 +376,7 @@ static bool voice_pcmbuf_insert_split_callback(
}
return true;
-}
+} /* voice_pcmbuf_insert_split_callback */
static bool codec_pcmbuf_insert_split_callback(
const void *ch1, const void *ch2, size_t length)
@@ -444,7 +438,7 @@ static bool codec_pcmbuf_insert_split_callback(
}
return true;
-}
+} /* codec_pcmbuf_insert_split_callback */
static bool voice_pcmbuf_insert_callback(const char *buf, size_t length)
{
@@ -649,7 +643,7 @@ static size_t codec_filebuf_callback(void *ptr, size_t size)
/* Return the actual amount of data copied to the buffer */
return copy_n;
-}
+} /* codec_filebuf_callback */
static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
{
@@ -664,7 +658,9 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
while (1)
{
if (voice_is_playing)
+ {
queue_wait_w_tmo(&voice_codec_queue, &ev, 0);
+ }
else if (playing)
{
queue_wait_w_tmo(&voice_codec_queue, &ev, 0);
@@ -679,7 +675,11 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
if (playing)
swap_codec();
break;
-
+#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
+ case Q_ENCODER_RECORD:
+ swap_codec();
+ break;
+#endif
case Q_VOICE_STOP:
if (voice_is_playing)
{
@@ -743,7 +743,7 @@ voice_play_clip:
return NULL;
return voicebuf;
-}
+} /* voice_request_buffer_callback */
static void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
{
@@ -794,7 +794,7 @@ static void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
*realsize = copy_n;
return (char *)&filebuf[buf_ridx];
-}
+} /* codec_request_buffer_callback */
static int get_codec_base_type(int type)
{
@@ -1531,52 +1531,24 @@ static void codec_discard_codec_callback(void)
#endif
}
-static const char *get_codec_path(int codectype)
+static const char * get_codec_filename(int enc_spec)
{
- switch (codectype) {
- case AFMT_OGG_VORBIS:
- logf("Codec: Vorbis");
- return CODEC_VORBIS;
- case AFMT_MPA_L1:
- case AFMT_MPA_L2:
- case AFMT_MPA_L3:
- logf("Codec: MPA L1/L2/L3");
- return CODEC_MPA_L3;
- case AFMT_PCM_WAV:
- logf("Codec: PCM WAV");
- return CODEC_WAV;
- case AFMT_FLAC:
- logf("Codec: FLAC");
- return CODEC_FLAC;
- case AFMT_A52:
- logf("Codec: A52");
- return CODEC_A52;
- case AFMT_MPC:
- logf("Codec: Musepack");
- return CODEC_MPC;
- case AFMT_WAVPACK:
- logf("Codec: WAVPACK");
- return CODEC_WAVPACK;
- case AFMT_ALAC:
- logf("Codec: ALAC");
- return CODEC_ALAC;
- case AFMT_AAC:
- logf("Codec: AAC");
- return CODEC_AAC;
- case AFMT_SHN:
- logf("Codec: SHN");
- return CODEC_SHN;
- case AFMT_AIFF:
- logf("Codec: PCM AIFF");
- return CODEC_AIFF;
- case AFMT_SID:
- logf("Codec: SID");
- return CODEC_SID;
- default:
- logf("Codec: Unsupported");
- return NULL;
- }
-}
+ const char *fname;
+ int type = enc_spec & CODEC_TYPE_MASK;
+ int afmt = enc_spec & CODEC_AFMT_MASK;
+
+ if ((unsigned)afmt >= AFMT_NUM_CODECS)
+ type = AFMT_UNKNOWN | (type & CODEC_TYPE_MASK);
+
+ fname = (type == CODEC_TYPE_DECODER) ?
+ audio_formats[afmt].codec_fn : audio_formats[afmt].codec_enc_fn;
+
+ logf("%s: %d - %s",
+ (type == CODEC_TYPE_ENCODER) ? "Encoder" : "Decoder",
+ afmt, fname ? fname : "<unknown>");
+
+ return fname;
+} /* get_codec_filename */
static bool loadcodec(bool start_play)
{
@@ -1585,9 +1557,10 @@ static bool loadcodec(bool start_play)
int rc;
size_t copy_n;
int prev_track;
+ char codec_path[MAX_PATH]; /* Full path to codec */
- const char *codec_path = get_codec_path(tracks[track_widx].id3.codectype);
- if (codec_path == NULL)
+ const char * codec_fn = get_codec_filename(tracks[track_widx].id3.codectype);
+ if (codec_fn == NULL)
return false;
tracks[track_widx].has_codec = false;
@@ -1603,7 +1576,7 @@ static bool loadcodec(bool start_play)
ci.taginfo_ready = &cur_ti->taginfo_ready;
ci.curpos = 0;
playing = true;
- queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_path);
+ queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_fn);
return true;
}
else
@@ -1625,6 +1598,8 @@ static bool loadcodec(bool start_play)
}
}
+ codec_get_full_path(codec_path, codec_fn);
+
fd = open(codec_path, O_RDONLY);
if (fd < 0)
{
@@ -1973,11 +1948,8 @@ static void audio_stop_playback(void)
(playlist_end && ci.stop_codec)?NULL:audio_current_track());
}
- if (voice_is_playing)
- {
- while (voice_is_playing && !queue_empty(&voice_codec_queue))
- yield();
- }
+ while (voice_is_playing && !queue_empty(&voice_codec_queue))
+ yield();
filebufused = 0;
playing = false;
@@ -1998,10 +1970,8 @@ static void audio_stop_playback(void)
static void audio_play_start(size_t offset)
{
-#ifdef CONFIG_TUNER
- /* check if radio is playing */
- if (get_radio_status() != FMRADIO_OFF)
- radio_stop();
+#if defined(HAVE_RECORDING) || defined(CONFIG_TUNER)
+ rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
#endif
/* Wait for any previously playing audio to flush - TODO: Not necessary? */
@@ -2483,6 +2453,20 @@ static void codec_thread(void)
mutex_unlock(&mutex_codecthread);
break ;
+#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
+ case Q_ENCODER_LOAD_DISK:
+ logf("Encoder load disk");
+ audio_codec_loaded = false;
+ if (voice_codec_loaded && current_codec == CODEC_IDX_VOICE)
+ queue_post(&voice_codec_queue, Q_ENCODER_RECORD, NULL);
+ mutex_lock(&mutex_codecthread);
+ current_codec = CODEC_IDX_AUDIO;
+ ci.stop_codec = false;
+ status = codec_load_file((const char *)ev.data, &ci);
+ mutex_unlock(&mutex_codecthread);
+ break;
+#endif
+
#ifndef SIMULATOR
case SYS_USB_CONNECTED:
queue_clear(&codec_queue);
@@ -2511,8 +2495,6 @@ static void codec_thread(void)
case Q_CODEC_LOAD:
if (playing)
{
- const char *codec_path;
-
if (ci.new_track || status != CODEC_OK)
{
if (!ci.new_track)
@@ -2523,7 +2505,8 @@ static void codec_thread(void)
if (!load_next_track())
{
- queue_post(&codec_queue, Q_AUDIO_STOP, 0);
+ // queue_post(&codec_queue, Q_AUDIO_STOP, 0);
+ queue_post(&audio_queue, Q_AUDIO_STOP, 0);
break;
}
}
@@ -2545,12 +2528,12 @@ static void codec_thread(void)
queue_post(&codec_queue, Q_CODEC_LOAD, 0);
else
{
- codec_path = get_codec_path(cur_ti->id3.codectype);
- queue_post(&codec_queue,
- Q_CODEC_LOAD_DISK, (void *)codec_path);
+ const char *codec_fn = get_codec_filename(cur_ti->id3.codectype);
+ queue_post(&codec_queue, Q_CODEC_LOAD_DISK,
+ (void *)codec_fn);
}
}
- }
+ } /* end switch */
}
}
@@ -2596,6 +2579,37 @@ static void reset_buffer(void)
filebuflen &= ~3;
}
+void audio_load_encoder(int enc_id)
+{
+#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
+ const char *enc_fn = get_codec_filename(enc_id | CODEC_TYPE_ENCODER);
+ if (!enc_fn)
+ return;
+
+ audio_remove_encoder();
+
+ queue_post(&codec_queue, Q_ENCODER_LOAD_DISK, (void *)enc_fn);
+
+ while (!ci.enc_codec_loaded)
+ yield();
+#endif
+ return;
+ (void)enc_id;
+} /* audio_load_encoder */
+
+void audio_remove_encoder(void)
+{
+#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
+ /* force encoder codec unload (if previously loaded) */
+ if (!ci.enc_codec_loaded)
+ return;
+
+ ci.stop_codec = true;
+ while (ci.enc_codec_loaded)
+ yield();
+#endif
+} /* audio_remove_encoder */
+
static void voice_codec_thread(void)
{
while (1)
@@ -2608,13 +2622,13 @@ static void voice_codec_thread(void)
voice_remaining = 0;
voice_getmore = NULL;
- codec_load_file(CODEC_MPA_L3, &ci_voice);
+ codec_load_file(get_codec_filename(AFMT_MPA_L3), &ci_voice);
logf("Voice codec finished");
- mutex_unlock(&mutex_codecthread);
voice_codec_loaded = false;
+ mutex_unlock(&mutex_codecthread);
}
-}
+} /* voice_codec_thread */
void voice_init(void)
{
@@ -2642,7 +2656,20 @@ void voice_init(void)
while (!voice_codec_loaded)
yield();
-}
+} /* voice_init */
+
+void voice_stop(void)
+{
+ /* Messages should not be posted to voice codec queue unless it is the
+ current codec or deadlocks happen. This will be addressed globally soon.
+ -- jhMikeS */
+ if (current_codec != CODEC_IDX_VOICE)
+ return;
+
+ mp3_play_stop();
+ while (voice_is_playing && !queue_empty(&voice_codec_queue))
+ yield();
+} /* voice_stop */
struct mp3entry* audio_current_track(void)
{
@@ -2803,9 +2830,19 @@ int audio_status(void)
if (paused)
ret |= AUDIO_STATUS_PAUSE;
+#ifdef HAVE_RECORDING
+ /* Do this here for constitency with mpeg.c version */
+ ret |= pcm_rec_status();
+#endif
+
return ret;
}
+bool audio_query_poweroff(void)
+{
+ return !(playing && paused);
+}
+
int audio_get_file_pos(void)
{
return 0;
diff --git a/apps/playback.h b/apps/playback.h
index 3e501333c1..73cd0ccfaf 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -27,8 +27,8 @@
#include "id3.h"
#include "mp3data.h"
-#define CODEC_IDX_AUDIO 0
-#define CODEC_IDX_VOICE 1
+#define CODEC_IDX_AUDIO 0
+#define CODEC_IDX_VOICE 1
/* Not yet implemented. */
#define CODEC_SET_AUDIOBUF_WATERMARK 4
@@ -66,6 +66,7 @@ void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3,
bool last_track));
void audio_invalidate_tracks(void);
void voice_init(void);
+void voice_stop(void);
#if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */
extern void audio_next_dir(void);
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
index c292909b33..208e7b67fa 100644
--- a/apps/recorder/radio.c
+++ b/apps/recorder/radio.c
@@ -24,7 +24,6 @@
#include "mas.h"
#include "settings.h"
#include "button.h"
-#include "fmradio.h"
#include "status.h"
#include "kernel.h"
#include "mpeg.h"
@@ -63,17 +62,6 @@
#ifdef CONFIG_TUNER
-#if CONFIG_CODEC == SWCODEC
-#ifdef HAVE_UDA1380
-#include "uda1380.h"
-#endif
-#ifdef HAVE_TLV320
-#include "tlv320.h"
-#endif
-
-#include "pcm_record.h"
-#endif
-
#if CONFIG_KEYPAD == RECORDER_PAD
#define FM_MENU BUTTON_F1
#define FM_PRESET BUTTON_F2
@@ -165,6 +153,7 @@ static int curr_freq;
static int radio_mode = RADIO_SCAN_MODE;
static int radio_status = FMRADIO_OFF;
+static bool in_screen = false;
#define MAX_PRESETS 64
static bool presets_loaded = false, presets_changed = false;
@@ -239,22 +228,87 @@ int get_radio_status(void)
return radio_status;
}
+bool in_radio_screen(void)
+{
+ return in_screen;
+}
+
+/* secret flag for starting paused - prevents unmute */
+#define FMRADIO_START_PAUSED 0x8000
+void radio_start(void)
+{
+ bool start_paused;
+ int mute_timeout;
+
+ if(radio_status == FMRADIO_PLAYING)
+ return;
+
+ start_paused = radio_status & FMRADIO_START_PAUSED;
+ /* clear flag before any yielding */
+ radio_status &= ~FMRADIO_START_PAUSED;
+
+ if(radio_status == FMRADIO_OFF)
+ radio_power(true);
+
+ curr_freq = global_settings.last_frequency * FREQ_STEP + MIN_FREQ;
+
+ radio_set(RADIO_SLEEP, 0); /* wake up the tuner */
+ radio_set(RADIO_FREQUENCY, curr_freq);
+
+ if(radio_status == FMRADIO_OFF)
+ {
+ radio_set(RADIO_IF_MEASUREMENT, 0);
+ radio_set(RADIO_SENSITIVITY, 0);
+ radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
+ mute_timeout = current_tick + 1*HZ;
+ }
+ else
+ {
+ /* paused */
+ mute_timeout = current_tick + 2*HZ;
+ }
+
+ while(!radio_get(RADIO_STEREO) && !radio_get(RADIO_TUNED))
+ {
+ if(TIME_AFTER(current_tick, mute_timeout))
+ break;
+ yield();
+ }
+
+ /* keep radio from sounding initially */
+ if(!start_paused)
+ radio_set(RADIO_MUTE, 0);
+
+ radio_status = FMRADIO_PLAYING;
+} /* radio_start */
+
+void radio_pause(void)
+{
+ if(radio_status == FMRADIO_PAUSED)
+ return;
+
+ if(radio_status == FMRADIO_OFF)
+ {
+ radio_status |= FMRADIO_START_PAUSED;
+ radio_start();
+ }
+
+ radio_set(RADIO_MUTE, 1);
+ radio_set(RADIO_SLEEP, 1);
+
+ radio_status = FMRADIO_PAUSED;
+} /* radio_pause */
+
void radio_stop(void)
-{
+{
+ if(radio_status == FMRADIO_OFF)
+ return;
+
radio_set(RADIO_MUTE, 1);
radio_set(RADIO_SLEEP, 1); /* low power mode, if available */
radio_status = FMRADIO_OFF;
radio_power(false); /* status update, power off if avail. */
-
-#ifndef SIMULATOR /* SIMULATOR. Catch FMRADIO_OFF status for the sim. */
-#if CONFIG_CODEC == SWCODEC
-#ifdef HAVE_TLV320
- tlv320_set_monitor(false);
-#endif
- pcm_rec_mux(0); /* Line In */
-#endif
-#endif /* SIMULATOR */
-}
+} /* radio_stop */
bool radio_hardware_present(void)
{
@@ -297,18 +351,16 @@ static int find_closest_preset(int freq)
return i;
if(diff < 0)
diff = -diff;
- if(diff < min_diff)
+ if(diff < min_diff)
{
preset = i;
- min_diff = diff;
+ min_diff = diff;
}
}
return preset;
}
-
-
static void remember_frequency(void)
{
global_settings.last_frequency = (curr_freq - MIN_FREQ) / FREQ_STEP;
@@ -366,13 +418,15 @@ bool radio_screen(void)
#endif
bool keep_playing = false;
bool statusbar = global_settings.statusbar;
- int mute_timeout = current_tick;
int button_timeout = current_tick + (2*HZ);
#ifdef HAS_BUTTONBAR
struct gui_buttonbar buttonbar;
gui_buttonbar_init(&buttonbar);
gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) );
#endif
+ /* change status to "in screen" */
+ in_screen = true;
+
/* always display status bar in radio screen for now */
global_settings.statusbar = true;
FOR_NB_SCREENS(i)
@@ -396,80 +450,44 @@ bool radio_screen(void)
}
#ifndef SIMULATOR
+ if(radio_status == FMRADIO_OFF)
+ audio_stop();
+
#if CONFIG_CODEC != SWCODEC
if(rec_create_directory() > 0)
have_recorded = true;
-#endif
- if(radio_status == FMRADIO_PLAYING_OUT)
- radio_status = FMRADIO_PLAYING;
- else if(radio_status == FMRADIO_PAUSED_OUT)
- radio_status = FMRADIO_PAUSED;
-
- if(radio_status == FMRADIO_OFF)
- audio_stop();
-
-#if CONFIG_CODEC != SWCODEC
audio_init_recording(talk_get_bufsize());
sound_settings_apply();
/* Yes, we use the D/A for monitoring */
peak_meter_playback(true);
-
- peak_meter_enabled = true;
- if (global_settings.rec_prerecord_time)
- talk_buffer_steal(); /* will use the mp3 buffer */
+ peak_meter_enabled = true;
- audio_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- 1, /* Line In */
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
+ rec_set_recording_options(global_settings.rec_frequency,
+ global_settings.rec_quality,
+ AUDIO_SRC_LINEIN, 0,
+ global_settings.rec_channels,
+ global_settings.rec_editable,
+ global_settings.rec_prerecord_time);
-
-#else
- peak_meter_enabled = false;
+ audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
+ sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
-#ifdef HAVE_UDA1380
- uda1380_enable_recording(false);
- uda1380_set_monitor(true);
-#elif defined(HAVE_TLV320)
- //tlv320_enable_recording(false);
- tlv320_set_recvol(23, 23, AUDIO_GAIN_LINEIN); /* 0dB */
- tlv320_set_monitor(true);
-#endif
+#endif /* CONFIG_CODEC != SWCODEC */
+#endif /* ndef SIMULATOR */
- /* Set the input multiplexer to FM */
- pcm_rec_mux(1);
-#endif
- audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
- sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
+ /* turn on radio */
+#if CONFIG_CODEC == SWCODEC
+ rec_set_source(AUDIO_SRC_FMRADIO, (radio_status == FMRADIO_PAUSED) ?
+ SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
+#else
+ if (radio_status == FMRADIO_OFF)
+ radio_start();
#endif
- curr_freq = global_settings.last_frequency * FREQ_STEP + MIN_FREQ;
-
- if(radio_status == FMRADIO_OFF)
- {
- radio_power(true);
- radio_set(RADIO_SLEEP, 0); /* wake up the tuner */
- radio_set(RADIO_FREQUENCY, curr_freq);
- radio_set(RADIO_IF_MEASUREMENT, 0);
- radio_set(RADIO_SENSITIVITY, 0);
- radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
- mute_timeout = current_tick + (1*HZ);
- while( !radio_get(RADIO_STEREO)
- &&!radio_get(RADIO_TUNED) )
- {
- if(TIME_AFTER(current_tick, mute_timeout))
- break;
- yield();
- }
- radio_set(RADIO_MUTE, 0);
- radio_status = FMRADIO_PLAYING;
- }
-
+ /* I hate this thing with vehement passion (jhMikeS): */
if(num_presets == 0 && yesno_pop(str(LANG_FM_FIRST_AUTOSCAN)))
scan_presets();
@@ -478,8 +496,8 @@ bool radio_screen(void)
radio_mode = RADIO_PRESET_MODE;
#ifdef HAS_BUTTONBAR
- gui_buttonbar_set(&buttonbar, str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS),
- str(LANG_FM_BUTTONBAR_RECORD));
+ gui_buttonbar_set(&buttonbar, str(LANG_BUTTONBAR_MENU),
+ str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_RECORD));
#endif
cpu_idle_mode(true);
@@ -535,7 +553,7 @@ bool radio_screen(void)
if (lastbutton != FM_STOP_PRE)
break;
#endif
-#ifndef SIMULATOR
+#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
if(audio_status() == AUDIO_STATUS_RECORD)
{
audio_stop();
@@ -548,7 +566,7 @@ bool radio_screen(void)
{
if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
{
- if(filepreset[0] == '\0')
+ if(filepreset[0] == '\0')
save_preset_list();
else
radio_save_presets();
@@ -577,14 +595,13 @@ bool radio_screen(void)
#ifndef SIMULATOR
if(audio_status() == AUDIO_STATUS_RECORD)
{
- audio_new_file(rec_create_filename(buf));
+ rec_new_file();
update_screen = true;
}
else
{
have_recorded = true;
- talk_buffer_steal(); /* we use the mp3 buffer */
- audio_record(rec_create_filename(buf));
+ rec_record();
update_screen = true;
}
#endif
@@ -604,7 +621,7 @@ bool radio_screen(void)
)
break;
#endif
-#ifndef SIMULATOR
+#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
if(audio_status() == AUDIO_STATUS_RECORD)
audio_stop();
#endif
@@ -615,7 +632,7 @@ bool radio_screen(void)
{
if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
{
- if(filepreset[0] == '\0')
+ if(filepreset[0] == '\0')
save_preset_list();
else
radio_save_presets();
@@ -734,27 +751,11 @@ bool radio_screen(void)
)
break;
#endif
- if(radio_status != FMRADIO_PLAYING)
- {
- radio_set(RADIO_SLEEP, 0);
- radio_set(RADIO_FREQUENCY, curr_freq);
- mute_timeout = current_tick + (2*HZ);
- while( !radio_get(RADIO_STEREO)
- &&!radio_get(RADIO_TUNED) )
- {
- if(TIME_AFTER(current_tick, mute_timeout))
- break;
- yield();
- }
- radio_set(RADIO_MUTE, 0);
- radio_status = FMRADIO_PLAYING;
- }
+ if (radio_status == FMRADIO_PLAYING)
+ radio_pause();
else
- {
- radio_set(RADIO_MUTE, 1);
- radio_set(RADIO_SLEEP, 1);
- radio_status = FMRADIO_PAUSED;
- }
+ radio_start();
+
update_screen = true;
break;
#endif
@@ -917,13 +918,17 @@ bool radio_screen(void)
if(TIME_AFTER(current_tick, timeout))
{
timeout = current_tick + HZ;
-
- stereo = radio_get(RADIO_STEREO) &&
- !global_settings.fm_force_mono;
- if(stereo != last_stereo_status)
+
+ /* keep "mono" from always being displayed when paused */
+ if (radio_status != FMRADIO_PAUSED)
{
- update_screen = true;
- last_stereo_status = stereo;
+ stereo = radio_get(RADIO_STEREO) &&
+ !global_settings.fm_force_mono;
+ if(stereo != last_stereo_status)
+ {
+ update_screen = true;
+ last_stereo_status = stereo;
+ }
}
}
@@ -952,9 +957,6 @@ bool radio_screen(void)
FOR_NB_SCREENS(i)
screens[i].puts_scroll(0, top_of_screen + 1, buf);
- strcat(buf, stereo?str(LANG_CHANNEL_STEREO):
- str(LANG_CHANNEL_MONO));
-
snprintf(buf, 128, stereo?str(LANG_CHANNEL_STEREO):
str(LANG_CHANNEL_MONO));
FOR_NB_SCREENS(i)
@@ -1005,9 +1007,9 @@ bool radio_screen(void)
done = true;
}
if (TIME_AFTER(current_tick, button_timeout))
- {
- cpu_idle_mode(true);
- }
+ {
+ cpu_idle_mode(true);
+ }
} /*while(!done)*/
#ifndef SIMULATOR
@@ -1033,28 +1035,26 @@ bool radio_screen(void)
sound_settings_apply();
#endif /* SIMULATOR */
+
if(keep_playing)
{
-/* Catch FMRADIO_PLAYING_OUT status for the sim. */
+/* Catch FMRADIO_PLAYING status for the sim. */
#ifndef SIMULATOR
#if CONFIG_CODEC != SWCODEC
/* Enable the Left and right A/D Converter */
audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
- sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
+ sound_default(SOUND_RIGHT_GAIN),
+ AUDIO_GAIN_LINEIN);
mas_codec_writereg(6, 0x4000);
#endif
#endif
- if(radio_status == FMRADIO_PAUSED)
- radio_status = FMRADIO_PAUSED_OUT;
- else
- radio_status = FMRADIO_PLAYING_OUT;
-
}
else
{
- radio_stop();
#if CONFIG_CODEC == SWCODEC
- peak_meter_enabled = true;
+ rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
+#else
+ radio_stop();
#endif
}
@@ -1062,9 +1062,11 @@ bool radio_screen(void)
/* restore status bar settings */
global_settings.statusbar = statusbar;
+
+ in_screen = false;
return have_recorded;
-}
+} /* radio_screen */
void radio_save_presets(void)
{
@@ -1106,16 +1108,16 @@ void radio_load_presets(char *filename)
/* No Preset in configuration. */
if(filename[0] == '\0')
- {
+ {
filepreset[0] = '\0';
return;
- }
+ }
/* Temporary preset, loaded until player shuts down. */
else if(filename[0] == '/')
strncpy(filepreset, filename, sizeof(filepreset));
/* Preset from default directory. */
else
- snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr",
+ snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr",
FMPRESET_PATH, filename);
fd = open(filepreset, O_RDONLY);
@@ -1466,30 +1468,6 @@ bool handle_radio_presets(void)
return reload_dir;
}
-#ifndef SIMULATOR
-#if CONFIG_CODEC != SWCODEC
-static bool fm_recording_settings(void)
-{
- bool ret;
-
- ret = recording_menu(true);
- if(!ret)
- {
- if (global_settings.rec_prerecord_time)
- talk_buffer_steal(); /* will use the mp3 buffer */
-
- audio_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- 1, /* Line In */
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
- }
- return ret;
-}
-#endif
-#endif
-
char monomode_menu_string[32];
static void create_monomode_menu(void)
@@ -1628,6 +1606,55 @@ int radio_menu_cb(int key, int m)
return key;
}
+#ifndef SIMULATOR
+#if defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC
+static bool fm_recording_screen(void)
+{
+ bool ret;
+
+#ifdef HAVE_FMRADIO_IN
+ /* switch recording source to FMRADIO for the duration */
+ int rec_source = global_settings.rec_source;
+ global_settings.rec_source = AUDIO_SRC_FMRADIO;
+
+ /* clearing queue seems to cure a spontaneous abort during record */
+ while (button_get(false) != BUTTON_NONE);
+#endif
+
+ ret = recording_screen(true);
+
+#ifdef HAVE_FMRADIO_IN
+ /* safe to reset as changing sources is prohibited here */
+ global_settings.rec_source = rec_source;
+#endif
+
+ return ret;
+}
+
+static bool fm_recording_settings(void)
+{
+ bool ret = recording_menu(true);
+
+ if (!ret)
+ {
+ rec_set_recording_options(global_settings.rec_frequency,
+ global_settings.rec_quality,
+#if CONFIG_CODEC == SWCODEC
+ AUDIO_SRC_FMRADIO, SRCF_FMRADIO_PLAYING,
+#else
+ AUDIO_SRC_LINEIN, 0,
+#endif
+ global_settings.rec_channels,
+ global_settings.rec_editable,
+ global_settings.rec_prerecord_time);
+ }
+
+ return ret;
+}
+#endif
+#endif /* SIMULATOR */
+
+
/* main menu of the radio screen */
bool radio_menu(void)
{
@@ -1637,24 +1664,27 @@ bool radio_menu(void)
static const struct menu_item items[] = {
/* Add functions not accessible via buttons */
#ifndef FM_PRESET
- { ID2P(LANG_FM_BUTTONBAR_PRESETS), handle_radio_presets },
+ { ID2P(LANG_FM_BUTTONBAR_PRESETS), handle_radio_presets },
#endif
#ifndef FM_PRESET_ADD
- { ID2P(LANG_FM_ADD_PRESET) , radio_add_preset },
+ { ID2P(LANG_FM_ADD_PRESET) , radio_add_preset },
#endif
- { ID2P(LANG_FM_PRESET_LOAD) , load_preset_list },
- { ID2P(LANG_FM_PRESET_SAVE) , save_preset_list },
- { ID2P(LANG_FM_PRESET_CLEAR) , clear_preset_list },
+ { ID2P(LANG_FM_PRESET_LOAD) , load_preset_list },
+ { ID2P(LANG_FM_PRESET_SAVE) , save_preset_list },
+ { ID2P(LANG_FM_PRESET_CLEAR) , clear_preset_list },
- { monomode_menu_string , toggle_mono_mode },
+ { monomode_menu_string , toggle_mono_mode },
#ifndef FM_MODE
- { radiomode_menu_string , toggle_radio_mode },
+ { radiomode_menu_string , toggle_radio_mode },
+#endif
+ { ID2P(LANG_SOUND_SETTINGS) , sound_menu },
+#ifndef SIMULATOR
+#if defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC
+ { ID2P(LANG_RECORDING_MENU) , fm_recording_screen },
+ { ID2P(LANG_RECORDING_SETTINGS) , fm_recording_settings },
#endif
- { ID2P(LANG_SOUND_SETTINGS) , sound_menu },
-#if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
- { ID2P(LANG_RECORDING_SETTINGS) , fm_recording_settings},
#endif
- { ID2P(LANG_FM_SCAN_PRESETS) , scan_presets },
+ { ID2P(LANG_FM_SCAN_PRESETS) , scan_presets },
};
create_monomode_menu();
diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h
index 86ce04c4b9..fdf446dc0a 100644
--- a/apps/recorder/radio.h
+++ b/apps/recorder/radio.h
@@ -20,19 +20,19 @@
#define RADIO_H
#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
-#define FMRADIO_OFF 0
-#define FMRADIO_PLAYING 1
-#define FMRADIO_PLAYING_OUT 2
-#define FMRADIO_PAUSED 3
-#define FMRADIO_PAUSED_OUT 4
+#ifndef FMRADIO_H
+#include "fmradio.h"
+#endif
#ifdef CONFIG_TUNER
void radio_load_presets(char *filename);
void radio_init(void);
bool radio_screen(void);
+void radio_start(void);
+void radio_pause(void);
void radio_stop(void);
bool radio_hardware_present(void);
-int get_radio_status(void);
+bool in_radio_screen(void);
#define MAX_FMPRESET_LEN 27
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index e6b06d56dc..080cafcf2f 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -24,12 +24,14 @@
#include <stdlib.h>
#include "system.h"
+#include "power.h"
#include "lcd.h"
#include "led.h"
#include "mpeg.h"
#include "audio.h"
#if CONFIG_CODEC == SWCODEC
#include "pcm_record.h"
+#include "playback.h"
#endif
#ifdef HAVE_UDA1380
#include "uda1380.h"
@@ -37,7 +39,7 @@
#ifdef HAVE_TLV320
#include "tlv320.h"
#endif
-
+#include "recording.h"
#include "mp3_playback.h"
#include "mas.h"
#include "button.h"
@@ -66,6 +68,7 @@
#include "splash.h"
#include "screen_access.h"
#include "action.h"
+#include "radio.h"
#ifdef HAVE_RECORDING
#define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1)
@@ -73,21 +76,6 @@
bool f2_rec_screen(void);
bool f3_rec_screen(void);
-#define SOURCE_MIC 0
-#define SOURCE_LINE 1
-#ifdef HAVE_SPDIF_IN
-#define SOURCE_SPDIF 2
-#define MAX_SOURCE SOURCE_SPDIF
-#else
-#define MAX_SOURCE SOURCE_LINE
-#endif
-
-#if CONFIG_CODEC == SWCODEC
-#define REC_FILE_ENDING ".wav"
-#else
-#define REC_FILE_ENDING ".mp3"
-#endif
-
#define MAX_FILE_SIZE 0x7F800000 /* 2 GB - 4 MB */
int screen_update = NB_SCREENS;
@@ -102,6 +90,19 @@ const char* const freq_str[6] =
"16kHz"
};
+#if CONFIG_CODEC == SWCODEC
+#define REC_ENCODER_ID(q) \
+ rec_quality_info_afmt[q]
+#define REC_QUALITY_LABEL(q) \
+ (audio_formats[REC_ENCODER_ID(q)].label)
+#define REC_FILE_ENDING(q) \
+ (audio_formats[REC_ENCODER_ID(q)].ext)
+#else
+/* default record file extension for HWCODEC */
+#define REC_QUALITY_LABEL(q) "MP3"
+#define REC_FILE_ENDING(q) ".mp3"
+#endif
+
#ifdef HAVE_AGC
/* Timing counters:
* peak_time is incremented every 0.2s, every 2nd run of record screen loop.
@@ -161,13 +162,14 @@ static short agc_maxgain;
static void set_gain(void)
{
- if(global_settings.rec_source == SOURCE_MIC)
+ if(global_settings.rec_source == AUDIO_SRC_MIC)
{
audio_set_recording_gain(global_settings.rec_mic_gain,
0, AUDIO_GAIN_MIC);
}
else
{
+ /* AUDIO_SRC_LINEIN, AUDIO_SRC_SPDIF, AUDIO_SRC_FMRADIO */
audio_set_recording_gain(global_settings.rec_left_gain,
global_settings.rec_right_gain,
AUDIO_GAIN_LINEIN);
@@ -217,12 +219,16 @@ bool agc_gain_is_max(bool left, bool right)
if (agc_preset == 0)
return false;
- if (global_settings.rec_source == SOURCE_LINE)
+ switch (global_settings.rec_source)
{
+ case AUDIO_SRC_LINEIN:
+#ifdef HAVE_FMRADIO_IN
+ case AUDIO_SRC_FMRADIO:
+#endif
gain_current_l = global_settings.rec_left_gain;
gain_current_r = global_settings.rec_right_gain;
- } else
- {
+ break;
+ default:
gain_current_l = global_settings.rec_mic_gain;
gain_current_r = global_settings.rec_mic_gain;
}
@@ -235,13 +241,16 @@ void change_recording_gain(bool increment, bool left, bool right)
{
int factor = (increment ? 1 : -1);
- if (global_settings.rec_source == SOURCE_LINE)
+ switch (global_settings.rec_source)
{
+ case AUDIO_SRC_LINEIN:
+#ifdef HAVE_FMRADIO_IN
+ case AUDIO_SRC_FMRADIO:
+#endif
if(left) global_settings.rec_left_gain += factor;
if (right) global_settings.rec_right_gain += factor;
- }
- else
- {
+ break;
+ default:
global_settings.rec_mic_gain += factor;
}
}
@@ -443,12 +452,15 @@ void adjust_cursor(void)
#ifdef HAVE_AGC
switch(global_settings.rec_source)
{
- case SOURCE_MIC:
+ case AUDIO_SRC_MIC:
if(cursor == 2)
cursor = 4;
else if(cursor == 3)
cursor = 1;
- case SOURCE_LINE:
+ case AUDIO_SRC_LINEIN:
+#ifdef HAVE_FMRADIO_IN
+ case AUDIO_SRC_FMRADIO:
+#endif
max_cursor = 5;
break;
default:
@@ -458,10 +470,13 @@ void adjust_cursor(void)
#else
switch(global_settings.rec_source)
{
- case SOURCE_MIC:
+ case AUDIO_SRC_MIC:
max_cursor = 1;
break;
- case SOURCE_LINE:
+ case AUDIO_SRC_LINEIN:
+#ifdef HAVE_FMRADIO_IN
+ case AUDIO_SRC_FMRADIO:
+#endif
max_cursor = 3;
break;
default:
@@ -481,10 +496,13 @@ char *rec_create_filename(char *buffer)
else
strncpy(buffer, rec_base_directory, MAX_PATH);
+
#ifdef CONFIG_RTC
- create_datetime_filename(buffer, buffer, "R", REC_FILE_ENDING);
+ create_datetime_filename(buffer, buffer, "R",
+ REC_FILE_ENDING(global_settings.rec_quality));
#else
- create_numbered_filename(buffer, buffer, "rec_", REC_FILE_ENDING, 4);
+ create_numbered_filename(buffer, buffer, "rec_",
+ REC_FILE_ENDING(global_settings.rec_quality), 4);
#endif
return buffer;
}
@@ -515,8 +533,190 @@ int rec_create_directory(void)
return 0;
}
+#if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR)
+/**
+ * Selects an audio source for recording or playback
+ * powers/unpowers related devices.
+ * Here because it calls app code and used only for HAVE_RECORDING atm.
+ * Would like it in pcm_record.c.
+ */
+#if defined(HAVE_UDA1380)
+#define ac_disable_recording uda1380_disable_recording
+#define ac_enable_recording uda1380_enable_recording
+#define ac_set_monitor uda1380_set_monitor
+#elif defined(HAVE_TLV320)
+#define ac_disable_recording tlv320_disable_recording
+#define ac_enable_recording tlv320_enable_recording
+#define ac_set_monitor tlv320_set_monitor
+#endif
+
+void rec_set_source(int source, int flags)
+{
+ /* Prevent pops from unneeded switching */
+ static int last_source = AUDIO_SRC_PLAYBACK;
+#ifdef HAVE_TLV320
+ static bool last_recording = false;
+#endif
+
+ bool recording = flags & SRCF_RECORDING;
+ /* Default to peakmeter record. */
+ bool pm_playback = false;
+ bool pm_enabled = true;
+
+ /** Do power up/down of associated device(s) **/
+
+#ifdef HAVE_SPDIF_IN
+ if ((source == AUDIO_SRC_SPDIF) != (source == last_source))
+ cpu_boost(source == AUDIO_SRC_SPDIF);
+
+#ifdef HAVE_SPDIF_POWER
+ /* Check if S/PDIF output power should be switched off or on. NOTE: assumes
+ both optical in and out is controlled by the same power source, which is
+ the case on H1x0. */
+ spdif_power_enable((source == AUDIO_SRC_SPDIF) ||
+ global_settings.spdif_enable);
+#endif
+#endif
+
+#ifdef CONFIG_TUNER
+ /* Switch radio off or on per source and flags. */
+ if (source != AUDIO_SRC_FMRADIO)
+ radio_stop();
+ else if (flags & SRCF_FMRADIO_PAUSED)
+ radio_pause();
+ else
+ radio_start();
+#endif
+
+ switch (source)
+ {
+ default: /* playback - no recording */
+ pm_playback = true;
+ if (source == last_source)
+ break;
+ ac_disable_recording();
+ ac_set_monitor(false);
+ pcm_rec_mux(0); /* line in */
+ break;
+
+ case AUDIO_SRC_MIC: /* recording only */
+ if (source == last_source)
+ break;
+ ac_enable_recording(true); /* source mic */
+ pcm_rec_mux(0); /* line in */
+ break;
+
+ case AUDIO_SRC_LINEIN: /* recording only */
+ if (source == last_source)
+ break;
+ pcm_rec_mux(0); /* line in */
+ ac_enable_recording(false); /* source line */
+ break;
+
+#ifdef HAVE_SPDIF_IN
+ case AUDIO_SRC_SPDIF: /* recording only */
+ if (recording)
+ {
+ /* This was originally done in audio_set_recording_options only */
+#ifdef HAVE_SPDIF_POWER
+ EBU1CONFIG = global_settings.spdif_enable ? (1 << 2) : 0;
+ /* Input source is EBUin1, Feed-through monitoring if desired */
+#else
+ EBU1CONFIG = (1 << 2);
+ /* Input source is EBUin1, Feed-through monitoring */
+#endif
+ }
+
+ if (source != last_source)
+ uda1380_disable_recording();
+ break;
+#endif /* HAVE_SPDIF_IN */
+
+#ifdef HAVE_FMRADIO_IN
+ case AUDIO_SRC_FMRADIO:
+ if (!recording)
+ {
+ audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
+ sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
+ pm_playback = true;
+ pm_enabled = false;
+ }
+
+ pcm_rec_mux(1); /* fm radio */
+
+#ifdef HAVE_UDA1380
+ if (source == last_source)
+ break;
+ /* I2S recording and playback */
+ uda1380_enable_recording(false); /* source line */
+ uda1380_set_monitor(true);
+#endif
+#ifdef HAVE_TLV320
+ /* I2S recording and analog playback */
+ if (source == last_source && recording == last_recording)
+ break;
+
+ last_recording = recording;
+
+ if (recording)
+ tlv320_enable_recording(false); /* source line */
+ else
+ {
+ tlv320_disable_recording();
+ tlv320_set_monitor(true); /* analog bypass */
+ }
+#endif
+ break;
+/* #elif defined(CONFIG_TUNER) */
+/* Have radio but cannot record it */
+/* case AUDIO_SRC_FMRADIO: */
+/* break; */
+#endif /* HAVE_FMRADIO_IN */
+ } /* end switch */
+
+ peak_meter_playback(pm_playback);
+ peak_meter_enabled = pm_enabled;
+
+ last_source = source;
+} /* rec_set_source */
+#endif /* CONFIG_CODEC == SWCODEC && !defined(SIMULATOR) */
+
+/* steal the mp3 buffer then actually set options */
+void rec_set_recording_options(int frequency, int quality,
+ int source, int source_flags,
+ int channel_mode, bool editable,
+ int prerecord_time)
+{
+#if CONFIG_CODEC != SWCODEC
+ if (global_settings.rec_prerecord_time)
+#endif
+ talk_buffer_steal(); /* will use the mp3 buffer */
+
+#if CONFIG_CODEC == SWCODEC
+ rec_set_source(source, source_flags | SRCF_RECORDING);
+#else
+ (void)source_flags;
+#endif
+
+ audio_set_recording_options(frequency, quality, source,
+ channel_mode, editable, prerecord_time);
+}
+
static char path_buffer[MAX_PATH];
+/* steals mp3 buffer, creates unique filename and starts recording */
+void rec_record(void)
+{
+ talk_buffer_steal(); /* we use the mp3 buffer */
+ audio_record(rec_create_filename(path_buffer));
+}
+
+/* creates unique filename and starts recording */
+void rec_new_file(void)
+{
+ audio_new_file(rec_create_filename(path_buffer));
+}
+
/* used in trigger_listerner and recording_screen */
static unsigned int last_seconds = 0;
@@ -533,16 +733,16 @@ static void trigger_listener(int trigger_status)
if((audio_status() & AUDIO_STATUS_RECORD) != AUDIO_STATUS_RECORD)
{
talk_buffer_steal(); /* we use the mp3 buffer */
- audio_record(rec_create_filename(path_buffer));
-
- /* give control to mpeg thread so that it can start recording*/
+ rec_record();
+ /* give control to mpeg thread so that it can start
+ recording */
yield(); yield(); yield();
}
/* if we're already recording this is a retrigger */
else
{
- audio_new_file(rec_create_filename(path_buffer));
+ rec_new_file();
/* tell recording_screen to reset the time */
last_seconds = 0;
}
@@ -563,10 +763,9 @@ static void trigger_listener(int trigger_status)
}
}
-bool recording_screen(void)
+bool recording_screen(bool no_source)
{
long button;
- long lastbutton = BUTTON_NONE;
bool done = false;
char buf[32];
char buf2[32];
@@ -575,11 +774,19 @@ bool recording_screen(void)
bool have_recorded = false;
unsigned int seconds;
int hours, minutes;
- char path_buffer[MAX_PATH];
char filename[13];
bool been_in_usb_mode = false;
int last_audio_stat = -1;
int audio_stat;
+#ifdef HAVE_FMRADIO_IN
+ /* Radio is left on if:
+ * 1) Is was on at the start and the initial source is FM Radio
+ * 2) 1) and the source was never changed to something else
+ */
+ int radio_status = (global_settings.rec_source != AUDIO_SRC_FMRADIO) ?
+ FMRADIO_OFF : get_radio_status();
+#endif
+ int talk_menu = global_settings.talk_menu;
#if CONFIG_LED == LED_REAL
bool led_state = false;
int led_countdown = 2;
@@ -608,6 +815,18 @@ bool recording_screen(void)
ata_set_led_enabled(false);
#endif
+#if CONFIG_CODEC == SWCODEC
+ audio_stop();
+ voice_stop();
+ /* recording_menu gets messed up: so reset talk_menu */
+ talk_menu = global_settings.talk_menu;
+ global_settings.talk_menu = 0;
+#else
+ /* Yes, we use the D/A for monitoring */
+ peak_meter_enabled = true;
+ peak_meter_playback(true);
+#endif
+
#ifndef SIMULATOR
audio_init_recording(talk_get_bufsize());
#else
@@ -616,44 +835,19 @@ bool recording_screen(void)
sound_set_volume(global_settings.volume);
-#if CONFIG_CODEC == SWCODEC
- audio_stop();
- /* Set peak meter to recording mode */
- peak_meter_playback(false);
-
-#if defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
- if (global_settings.rec_source == SOURCE_SPDIF)
- cpu_boost(true);
-#endif
-
-#else
- /* Yes, we use the D/A for monitoring */
- peak_meter_playback(true);
-#endif
- peak_meter_enabled = true;
#ifdef HAVE_AGC
peak_meter_get_peakhold(&peak_l, &peak_r);
#endif
-#if CONFIG_CODEC != SWCODEC
- if (global_settings.rec_prerecord_time)
-#endif
- talk_buffer_steal(); /* will use the mp3 buffer */
-
-#if defined(HAVE_SPDIF_POWER) && !defined(SIMULATOR)
- /* Tell recording whether we want S/PDIF power enabled at all times */
- audio_set_spdif_power_setting(global_settings.spdif_enable);
-#endif
-
- audio_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- global_settings.rec_source,
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
+ rec_set_recording_options(global_settings.rec_frequency,
+ global_settings.rec_quality,
+ global_settings.rec_source,
+ 0,
+ global_settings.rec_channels,
+ global_settings.rec_editable,
+ global_settings.rec_prerecord_time);
set_gain();
-
settings_apply_trigger();
#ifdef HAVE_AGC
@@ -663,7 +857,7 @@ bool recording_screen(void)
agc_preset_str[3] = str(LANG_AGC_DJSET);
agc_preset_str[4] = str(LANG_AGC_MEDIUM);
agc_preset_str[5] = str(LANG_AGC_VOICE);
- if (global_settings.rec_source == SOURCE_MIC) {
+ if (global_settings.rec_source == AUDIO_SRC_MIC) {
agc_preset = global_settings.rec_agc_preset_mic;
agc_maxgain = global_settings.rec_agc_maxgain_mic;
}
@@ -697,11 +891,7 @@ bool recording_screen(void)
while(!done)
{
-#if CONFIG_CODEC == SWCODEC
- audio_stat = pcm_rec_status();
-#else
audio_stat = audio_status();
-#endif
#if CONFIG_LED == LED_REAL
@@ -794,8 +984,8 @@ bool recording_screen(void)
}
else
{
- peak_meter_playback(true);
#if CONFIG_CODEC != SWCODEC
+ peak_meter_playback(true);
peak_meter_enabled = false;
#endif
done = true;
@@ -815,14 +1005,13 @@ bool recording_screen(void)
/* manual recording */
have_recorded = true;
talk_buffer_steal(); /* we use the mp3 buffer */
- audio_record(rec_create_filename(path_buffer));
+ rec_record();
last_seconds = 0;
- if (global_settings.talk_menu)
+ if (talk_menu)
{ /* no voice possible here, but a beep */
audio_beep(HZ/2); /* longer beep on start */
}
}
-
/* this is triggered recording */
else
{
@@ -838,7 +1027,7 @@ bool recording_screen(void)
/*if new file button pressed, start new file */
if (button == ACTION_REC_NEWFILE)
{
- audio_new_file(rec_create_filename(path_buffer));
+ rec_new_file();
last_seconds = 0;
}
else
@@ -847,7 +1036,7 @@ bool recording_screen(void)
if(audio_stat & AUDIO_STATUS_PAUSE)
{
audio_resume_recording();
- if (global_settings.talk_menu)
+ if (talk_menu)
{ /* no voice possible here, but a beep */
audio_beep(HZ/4); /* short beep on resume */
}
@@ -883,7 +1072,7 @@ bool recording_screen(void)
sound_set_volume(global_settings.volume);
break;
case 1:
- if(global_settings.rec_source == SOURCE_MIC)
+ if(global_settings.rec_source == AUDIO_SRC_MIC)
{
if(global_settings.rec_mic_gain <
sound_max(SOUND_MIC_GAIN))
@@ -913,7 +1102,7 @@ bool recording_screen(void)
case 4:
agc_preset = MIN(agc_preset + 1, AGC_MODE_SIZE);
agc_enable = (agc_preset != 0);
- if (global_settings.rec_source == SOURCE_MIC) {
+ if (global_settings.rec_source == AUDIO_SRC_MIC) {
global_settings.rec_agc_preset_mic = agc_preset;
agc_maxgain = global_settings.rec_agc_maxgain_mic;
} else {
@@ -922,7 +1111,7 @@ bool recording_screen(void)
}
break;
case 5:
- if (global_settings.rec_source == SOURCE_MIC)
+ if (global_settings.rec_source == AUDIO_SRC_MIC)
{
agc_maxgain = MIN(agc_maxgain + 1,
sound_max(SOUND_MIC_GAIN));
@@ -951,7 +1140,7 @@ bool recording_screen(void)
sound_set_volume(global_settings.volume);
break;
case 1:
- if(global_settings.rec_source == SOURCE_MIC)
+ if(global_settings.rec_source == AUDIO_SRC_MIC)
{
if(global_settings.rec_mic_gain >
sound_min(SOUND_MIC_GAIN))
@@ -981,7 +1170,7 @@ bool recording_screen(void)
case 4:
agc_preset = MAX(agc_preset - 1, 0);
agc_enable = (agc_preset != 0);
- if (global_settings.rec_source == SOURCE_MIC) {
+ if (global_settings.rec_source == AUDIO_SRC_MIC) {
global_settings.rec_agc_preset_mic = agc_preset;
agc_maxgain = global_settings.rec_agc_maxgain_mic;
} else {
@@ -990,7 +1179,7 @@ bool recording_screen(void)
}
break;
case 5:
- if (global_settings.rec_source == SOURCE_MIC)
+ if (global_settings.rec_source == AUDIO_SRC_MIC)
{
agc_maxgain = MAX(agc_maxgain - 1,
sound_min(SOUND_MIC_GAIN));
@@ -1012,49 +1201,73 @@ bool recording_screen(void)
case ACTION_STD_MENU:
if(audio_stat != AUDIO_STATUS_RECORD)
{
+#ifdef HAVE_FMRADIO_IN
+ const int prev_rec_source = global_settings.rec_source;
+#endif
+
#if CONFIG_LED == LED_REAL
/* led is restored at begin of loop / end of function */
led(false);
#endif
- if (recording_menu(false))
+ if (recording_menu(no_source))
{
- return SYS_USB_CONNECTED;
+ done = true;
+ been_in_usb_mode = true;
+#ifdef HAVE_FMRADIO_IN
+ radio_status = FMRADIO_OFF;
+#endif
}
- settings_save();
+ else
+ {
+ settings_save();
+
+#ifdef HAVE_FMRADIO_IN
+ /* If input changes away from FM Radio, radio will
+ remain off when recording screen closes. */
+ if (global_settings.rec_source != prev_rec_source
+ && prev_rec_source == AUDIO_SRC_FMRADIO)
+ radio_status = FMRADIO_OFF;
+#endif
-#if CONFIG_CODEC != SWCODEC
- if (global_settings.rec_prerecord_time)
+#if CONFIG_CODEC == SWCODEC
+ /* reinit after submenu exit */
+ audio_close_recording();
+ audio_init_recording(talk_get_bufsize());
#endif
- talk_buffer_steal(); /* will use the mp3 buffer */
-
- audio_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- global_settings.rec_source,
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
+ rec_set_recording_options(
+ global_settings.rec_frequency,
+ global_settings.rec_quality,
+ global_settings.rec_source,
+ 0,
+ global_settings.rec_channels,
+ global_settings.rec_editable,
+ global_settings.rec_prerecord_time);
+
#ifdef HAVE_AGC
- if (global_settings.rec_source == SOURCE_MIC) {
- agc_preset = global_settings.rec_agc_preset_mic;
- agc_maxgain = global_settings.rec_agc_maxgain_mic;
- }
- else {
- agc_preset = global_settings.rec_agc_preset_line;
- agc_maxgain = global_settings.rec_agc_maxgain_line;
- }
+ if (global_settings.rec_source == AUDIO_SRC_MIC) {
+ agc_preset = global_settings.rec_agc_preset_mic;
+ agc_maxgain = global_settings.rec_agc_maxgain_mic;
+ }
+ else {
+ agc_preset = global_settings.rec_agc_preset_line;
+ agc_maxgain = global_settings.rec_agc_maxgain_line;
+ }
#endif
- adjust_cursor();
- set_gain();
- update_countdown = 1; /* Update immediately */
+ adjust_cursor();
+ set_gain();
+ update_countdown = 1; /* Update immediately */
- FOR_NB_SCREENS(i)
- {
- screens[i].setfont(FONT_SYSFIXED);
- screens[i].setmargins(global_settings.invert_cursor ? 0 : w, 8);
+ FOR_NB_SCREENS(i)
+ {
+ screens[i].setfont(FONT_SYSFIXED);
+ screens[i].setmargins(
+ global_settings.invert_cursor ? 0 : w, 8);
+ }
}
}
break;
+
#if CONFIG_KEYPAD == RECORDER_PAD
case ACTION_REC_F2:
if(audio_stat != AUDIO_STATUS_RECORD)
@@ -1076,7 +1289,7 @@ bool recording_screen(void)
case ACTION_REC_F3:
if(audio_stat & AUDIO_STATUS_RECORD)
{
- audio_new_file(rec_create_filename(path_buffer));
+ rec_new_file();
last_seconds = 0;
}
else
@@ -1097,7 +1310,7 @@ bool recording_screen(void)
}
}
break;
-#endif
+#endif /* CONFIG_KEYPAD == RECORDER_PAD */
case SYS_USB_CONNECTED:
/* Only accept USB connection when not recording */
@@ -1106,6 +1319,9 @@ bool recording_screen(void)
default_event_handler(SYS_USB_CONNECTED);
done = true;
been_in_usb_mode = true;
+#ifdef HAVE_FMRADIO_IN
+ radio_status = FMRADIO_OFF;
+#endif
}
break;
@@ -1113,8 +1329,6 @@ bool recording_screen(void)
default_event_handler(button);
break;
}
- if (button != BUTTON_NONE)
- lastbutton = button;
#ifdef HAVE_AGC
peak_read = !peak_read;
@@ -1230,7 +1444,7 @@ bool recording_screen(void)
if (!(global_settings.rec_split_type)
|| (num_recorded_bytes >= MAX_FILE_SIZE))
{
- audio_new_file(rec_create_filename(path_buffer));
+ rec_new_file();
last_seconds = 0;
}
else
@@ -1259,8 +1473,9 @@ bool recording_screen(void)
screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 2, buf);
}
- if(global_settings.rec_source == SOURCE_MIC)
- {
+ if(global_settings.rec_source == AUDIO_SRC_MIC)
+ {
+ /* Draw MIC recording gain */
snprintf(buf, 32, "%s:%s", str(LANG_SYSFONT_RECORDING_GAIN),
fmt_gain(SOUND_MIC_GAIN,
global_settings.rec_mic_gain,
@@ -1278,8 +1493,13 @@ bool recording_screen(void)
PM_HEIGHT + 3, buf);
}
}
- else if(global_settings.rec_source == SOURCE_LINE)
+ else if(global_settings.rec_source == AUDIO_SRC_LINEIN
+#ifdef HAVE_FMRADIO_IN
+ || global_settings.rec_source == AUDIO_SRC_FMRADIO
+#endif
+ )
{
+ /* Draw LINE or FMRADIO recording gain */
snprintf(buf, 32, "%s:%s",
str(LANG_SYSFONT_RECORDING_LEFT),
fmt_gain(SOUND_LEFT_GAIN,
@@ -1319,14 +1539,23 @@ bool recording_screen(void)
FOR_NB_SCREENS(i)
{
- if (global_settings.rec_source == SOURCE_LINE)
+ switch (global_settings.rec_source)
+ {
+ case AUDIO_SRC_LINEIN:
+#ifdef HAVE_FMRADIO_IN
+ case AUDIO_SRC_FMRADIO:
+#endif
line[i] = 5;
- else if (global_settings.rec_source == SOURCE_MIC)
+ break;
+ case AUDIO_SRC_MIC:
line[i] = 4;
+ break;
#ifdef HAVE_SPDIF_IN
- else if (global_settings.rec_source == SOURCE_SPDIF)
+ case AUDIO_SRC_SPDIF:
line[i] = 3;
+ break;
#endif
+ } /* end switch */
#ifdef HAVE_AGC
if (screens[i].height < h * (2 + filename_offset[i] + PM_HEIGHT + line[i]))
{
@@ -1358,7 +1587,7 @@ bool recording_screen(void)
snprintf(buf, 32, "%s: %s",
str(LANG_RECORDING_AGC_PRESET),
agc_preset_str[agc_preset]);
- else if (global_settings.rec_source == SOURCE_MIC)
+ else if (global_settings.rec_source == AUDIO_SRC_MIC)
snprintf(buf, 32, "%s: %s%s",
str(LANG_RECORDING_AGC_PRESET),
agc_preset_str[agc_preset],
@@ -1382,8 +1611,12 @@ bool recording_screen(void)
screens[i].puts_style_offset(0, filename_offset[i] +
PM_HEIGHT + line[i], buf, STYLE_INVERT,0);
}
- else if ((global_settings.rec_source == SOURCE_MIC)
- || (global_settings.rec_source == SOURCE_LINE))
+ else if (global_settings.rec_source == AUDIO_SRC_MIC
+ || global_settings.rec_source == AUDIO_SRC_LINEIN
+#ifdef HAVE_FMRADIO_IN
+ || global_settings.rec_source == AUDIO_SRC_FMRADIO
+#endif
+ )
{
for(i = 0; i < screen_update; i++) {
if (display_agc[i]) {
@@ -1393,7 +1626,7 @@ bool recording_screen(void)
}
}
- if (global_settings.rec_source == SOURCE_MIC)
+ if (global_settings.rec_source == AUDIO_SRC_MIC)
{
if(agc_maxgain < (global_settings.rec_mic_gain))
change_recording_gain(false, true, true);
@@ -1418,7 +1651,7 @@ bool recording_screen(void)
filename_offset[i] +
PM_HEIGHT + 3, true);
- if(global_settings.rec_source != SOURCE_MIC)
+ if(global_settings.rec_source != AUDIO_SRC_MIC)
{
for(i = 0; i < screen_update; i++)
screen_put_cursorxy(&screens[i], 0,
@@ -1456,14 +1689,14 @@ bool recording_screen(void)
}
/* Can't measure S/PDIF sample rate on Archos yet */
#if (CONFIG_CODEC != MAS3587F) && defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
- if (global_settings.rec_source == SOURCE_SPDIF)
+ if (global_settings.rec_source == AUDIO_SRC_SPDIF)
snprintf(spdif_sfreq, 8, "%dHz", audio_get_spdif_sample_rate());
#else
(void)spdif_sfreq;
#endif
snprintf(buf, 32, "%s %s",
#if (CONFIG_CODEC != MAS3587F) && defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
- global_settings.rec_source == SOURCE_SPDIF ?
+ global_settings.rec_source == AUDIO_SRC_SPDIF ?
spdif_sfreq :
#endif
freq_str[global_settings.rec_frequency],
@@ -1473,8 +1706,8 @@ bool recording_screen(void)
for(i = 0; i < screen_update; i++) {
#ifdef HAVE_AGC
- if ((global_settings.rec_source == SOURCE_MIC)
- || (global_settings.rec_source == SOURCE_LINE))
+ if ((global_settings.rec_source == AUDIO_SRC_MIC)
+ || (global_settings.rec_source == AUDIO_SRC_LINEIN))
screens[i].puts(0, filename_offset[i] + PM_HEIGHT + line[i] + 1, buf);
else
#endif
@@ -1484,6 +1717,14 @@ bool recording_screen(void)
#ifdef HAVE_AGC
hist_time++;
#endif
+
+#if CONFIG_CODEC == SWCODEC
+ snprintf(buf, 32, "%s",
+ REC_QUALITY_LABEL(global_settings.rec_quality));
+ for(i = 0; i < screen_update; i++)
+ screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 6, buf);
+#endif
+
for(i = 0; i < screen_update; i++)
{
gui_statusbar_draw(&(statusbars.statusbars[i]), true);
@@ -1506,7 +1747,7 @@ bool recording_screen(void)
{
done = true;
}
- }
+ } /* end while(!done) */
#if CONFIG_CODEC == SWCODEC
@@ -1531,18 +1772,26 @@ bool recording_screen(void)
}
}
-#if CONFIG_CODEC == SWCODEC
+#if CONFIG_CODEC == SWCODEC
audio_stop_recording();
audio_close_recording();
-#if defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
- if (global_settings.rec_source == SOURCE_SPDIF)
- cpu_boost(false);
+#ifdef HAVE_FMRADIO_IN
+ if (radio_status != FMRADIO_OFF)
+ /* Restore radio playback - radio_status should be unchanged if started
+ through fm radio screen (barring usb connect) */
+ rec_set_source(AUDIO_SRC_FMRADIO, (radio_status & FMRADIO_PAUSED) ?
+ SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
+ else
#endif
+ /* Go back to playback mode */
+ rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
-#else
+ /* restore talk_menu setting */
+ global_settings.talk_menu = talk_menu;
+#else /* !SWCODEC */
audio_init_playback();
-#endif
+#endif /* CONFIG_CODEC == SWCODEC */
/* make sure the trigger is really turned off */
peak_meter_trigger(false);
@@ -1560,7 +1809,7 @@ bool recording_screen(void)
ata_set_led_enabled(true);
#endif
return been_in_usb_mode;
-}
+} /* recording_screen */
#if CONFIG_KEYPAD == RECORDER_PAD
bool f2_rec_screen(void)
@@ -1680,15 +1929,13 @@ bool f2_rec_screen(void)
}
}
- if (global_settings.rec_prerecord_time)
- talk_buffer_steal(); /* will use the mp3 buffer */
-
- audio_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- global_settings.rec_source,
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
+ rec_set_recording_options(global_settings.rec_frequency,
+ global_settings.rec_quality,
+ global_settings.rec_source,
+ 0,
+ global_settings.rec_channels,
+ global_settings.rec_editable,
+ global_settings.rec_prerecord_time);
set_gain();
@@ -1760,7 +2007,7 @@ bool f3_rec_screen(void)
case BUTTON_LEFT:
case BUTTON_F3 | BUTTON_LEFT:
global_settings.rec_source++;
- if(global_settings.rec_source > MAX_SOURCE)
+ if(global_settings.rec_source > AUDIO_SRC_MAX)
global_settings.rec_source = 0;
used = true;
break;
@@ -1782,16 +2029,13 @@ bool f3_rec_screen(void)
}
}
- if (global_settings.rec_prerecord_time)
- talk_buffer_steal(); /* will use the mp3 buffer */
-
- audio_set_recording_options(global_settings.rec_frequency,
- global_settings.rec_quality,
- global_settings.rec_source,
- global_settings.rec_channels,
- global_settings.rec_editable,
- global_settings.rec_prerecord_time);
-
+ rec_set_recording_options(global_settings.rec_frequency,
+ global_settings.rec_quality,
+ global_settings.rec_source,
+ 0,
+ global_settings.rec_channels,
+ global_settings.rec_editable,
+ global_settings.rec_prerecord_time);
set_gain();
@@ -1801,7 +2045,7 @@ bool f3_rec_screen(void)
return false;
}
-#endif /* #ifdef RECORDER_PAD */
+#endif /* CONFIG_KEYPAD == RECORDER_PAD */
#if CONFIG_CODEC == SWCODEC
void audio_beep(int duration)
@@ -1831,6 +2075,14 @@ unsigned long audio_num_recorded_bytes(void)
return 5 * 1024 * 1024;
}
+#if CONFIG_CODEC == SWCODEC
+void rec_set_source(int source, int flags)
+{
+ source = source;
+ flags = flags;
+}
+#endif
+
void audio_set_recording_options(int frequency, int quality,
int source, int channel_mode,
bool editable, int prerecord_time)
diff --git a/apps/recorder/recording.h b/apps/recorder/recording.h
index 384b34f5bf..aa216e757f 100644
--- a/apps/recorder/recording.h
+++ b/apps/recorder/recording.h
@@ -19,8 +19,33 @@
#ifndef RECORDING_H
#define RECORDING_H
-bool recording_screen(void);
+bool recording_screen(bool no_source);
char *rec_create_filename(char *buf);
int rec_create_directory(void);
+#if CONFIG_CODEC == SWCODEC
+/* selects an audio source for recording or playback */
+#define SRCF_PLAYBACK 0x0000 /* default */
+#define SRCF_RECORDING 0x1000
+#ifdef CONFIG_TUNER
+/* for AUDIO_SRC_FMRADIO */
+#define SRCF_FMRADIO_PLAYING 0x0000 /* default */
+#define SRCF_FMRADIO_PAUSED 0x2000
+#endif
+void rec_set_source(int source, int flags);
+#endif /* CONFIG_CODEC == SW_CODEC */
+
+/* steals mp3 buffer, sets source and then options */
+/* SRCF_RECORDING is implied */
+void rec_set_recording_options(int frequency, int quality,
+ int source, int source_flags,
+ int channel_mode, bool editable,
+ int prerecord_time);
+
+/* steals mp3 buffer, creates unique filename and starts recording */
+void rec_record(void);
+
+/* creates unique filename and starts recording */
+void rec_new_file(void);
+
#endif
diff --git a/apps/settings.c b/apps/settings.c
index 49b8f9826b..acaeedcbd9 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -92,7 +92,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
#include "dsp.h"
#endif
-#define CONFIG_BLOCK_VERSION 50
+#define CONFIG_BLOCK_VERSION 51
#define CONFIG_BLOCK_SIZE 512
#define RTC_BLOCK_SIZE 44
@@ -473,11 +473,21 @@ static const struct bit_entry hd_bits[] =
{1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" },
{1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" },
-#ifdef HAVE_SPDIF_IN
- {2, S_O(rec_source), 0 /* 0=mic */, "rec source", "mic,line,spdif" },
+ {
+#if defined(HAVE_SPDIF_IN) || defined(HAVE_FMRADIO_IN)
+ 2,
#else
- {1, S_O(rec_source), 0 /* 0=mic */, "rec source", "mic,line" },
+ 1,
+#endif
+ S_O(rec_source), 0 /* 0=mic */, "rec source",
+ "mic,line"
+#ifdef HAVE_SPDIF_IN
+ ",spdif"
#endif
+#ifdef HAVE_FMRADIO_IN
+ ",fmradio"
+#endif
+ },
{5, S_O(rec_prerecord_time), 0, "prerecording time", NULL }, /* 0...30 */
{1, S_O(rec_directory), 0, /* rec_base_directory */
"rec directory", REC_BASE_DIR ",current" },
@@ -490,14 +500,21 @@ static const struct bit_entry hd_bits[] =
{4, S_O(rec_right_gain), 2 /* 0dB */, "rec right gain", NULL }, /* 0...15 */
{3, S_O(rec_frequency), 0, /* 0=44.1kHz */
"rec frequency", "44,48,32,22,24,16" },
+ {3, S_O(rec_quality), 5 /* 192 kBit/s max */, "rec quality", NULL },
{1, S_O(rec_editable), false, "editable recordings", off_on },
- {3, S_O(rec_quality), 5, "rec quality", NULL },
-#elif defined(HAVE_UDA1380)
+#elif defined(HAVE_UDA1380) || defined(HAVE_TLV320)
+#ifdef HAVE_UDA1380
{8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
+#endif
+#ifdef HAVE_TLV320
+ /* TLV320 only has no mic boost or 20db mic boost */
+ {1, S_O(rec_mic_gain), 0 /* 0 dB */, "rec mic gain", NULL }, /* 0db or 20db */
+#endif
{8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
{8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
{3, S_O(rec_frequency), 0, /* 0=44.1kHz */
"rec frequency", "44,48,32,22,24,16" },
+ {4, S_O(rec_quality), 4 /* MP3 L3 192 kBit/s */, "rec quality", NULL },
#endif
/* values for the trigger */
diff --git a/apps/settings.h b/apps/settings.h
index d87bc5ee06..af0eef57b1 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -42,6 +42,7 @@
#define BACKDROP_DIR ROCKBOX_DIR"/backdrops"
#define REC_BASE_DIR "/recordings"
#define EQS_DIR ROCKBOX_DIR "/eqs"
+#define CODECS_DIR "/codecs"
#define MAX_FILENAME 20
diff --git a/apps/sound_menu.c b/apps/sound_menu.c
index 34ed9af000..179951a17d 100644
--- a/apps/sound_menu.c
+++ b/apps/sound_menu.c
@@ -39,6 +39,12 @@
#include "talk.h"
#include "misc.h"
#include "sound.h"
+#ifdef HAVE_RECORDING
+#include "audio.h"
+#ifdef CONFIG_TUNER
+#include "radio.h"
+#endif
+#endif
#if CONFIG_CODEC == MAS3587F
#include "peakmeter.h"
#include "mas.h"
@@ -290,19 +296,68 @@ static bool avc(void)
#ifdef HAVE_RECORDING
static bool recsource(void)
{
- static const struct opt_items names[] = {
+ int n_opts = AUDIO_NUM_SOURCES;
+
+ struct opt_items names[AUDIO_NUM_SOURCES] = {
{ STR(LANG_RECORDING_SRC_MIC) },
{ STR(LANG_RECORDING_SRC_LINE) },
#ifdef HAVE_SPDIF_IN
{ STR(LANG_RECORDING_SRC_DIGITAL) },
#endif
};
+
+ /* caveat: assumes it's the last item! */
+#ifdef HAVE_FMRADIO_IN
+ if (radio_hardware_present())
+ {
+ names[AUDIO_SRC_FMRADIO].string = ID2P(LANG_FM_RADIO);
+ names[AUDIO_SRC_FMRADIO].voice_id = LANG_FM_RADIO;
+ }
+ else
+ n_opts--;
+#endif
+
return set_option(str(LANG_RECORDING_SOURCE),
&global_settings.rec_source, INT, names,
- sizeof(names)/sizeof(struct opt_items), NULL );
+ n_opts, NULL );
}
/* To be removed when we add support for sample rates and channel settings */
+#if CONFIG_CODEC == SWCODEC
+static bool recquality(void)
+{
+ static const struct opt_items names[] = {
+ { "MP3 64 kBit/s", TALK_ID( 64, UNIT_KBIT) },
+ { "MP3 96 kBit/s", TALK_ID( 96, UNIT_KBIT) },
+ { "MP3 128 kBit/s", TALK_ID( 128, UNIT_KBIT) },
+ { "MP3 160 kBit/s", TALK_ID( 160, UNIT_KBIT) },
+ { "MP3 192 kBit/s", TALK_ID( 192, UNIT_KBIT) },
+ { "MP3 224 kBit/s", TALK_ID( 224, UNIT_KBIT) },
+ { "MP3 320 kBit/s", TALK_ID( 320, UNIT_KBIT) },
+ { "WV 900 kBit/s", TALK_ID( 900, UNIT_KBIT) },
+ { "WAV 1411 kBit/s", TALK_ID(1411, UNIT_KBIT) }
+ };
+
+ return set_option(str(LANG_RECORDING_QUALITY),
+ &global_settings.rec_quality, INT,
+ names, sizeof (names)/sizeof(struct opt_items),
+ NULL );
+}
+#elif CONFIG_CODEC == MAS3587F
+static bool recquality(void)
+{
+ return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT,
+ &global_settings.rec_quality,
+ NULL, 1, 0, 7, NULL );
+}
+
+static bool receditable(void)
+{
+ return set_bool(str(LANG_RECORDING_EDITABLE),
+ &global_settings.rec_editable);
+}
+#endif
+
#ifndef HAVE_UDA1380
static bool recfrequency(void)
{
@@ -331,21 +386,6 @@ static bool recchannels(void)
}
#endif
-#if CONFIG_CODEC == MAS3587F
-static bool recquality(void)
-{
- return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT,
- &global_settings.rec_quality,
- NULL, 1, 0, 7, NULL );
-}
-
-static bool receditable(void)
-{
- return set_bool(str(LANG_RECORDING_EDITABLE),
- &global_settings.rec_editable);
-}
-#endif
-
static bool rectimesplit(void)
{
static const struct opt_items names[] = {
@@ -1011,13 +1051,13 @@ bool recording_menu(bool no_source)
struct menu_item items[13];
bool result;
-#if CONFIG_CODEC == MAS3587F
+#if CONFIG_CODEC == MAS3587F || CONFIG_CODEC == SWCODEC
items[i].desc = ID2P(LANG_RECORDING_QUALITY);
items[i++].function = recquality;
#endif
+#ifndef HAVE_UDA1380
/* We don't support frequency selection for UDA1380 yet. Let it just stay at
the default 44100 Hz. */
-#ifndef HAVE_UDA1380
items[i].desc = ID2P(LANG_RECORDING_FREQUENCY);
items[i++].function = recfrequency;
#endif
diff --git a/apps/status.c b/apps/status.c
index ad4cb7232b..2a57db0f89 100644
--- a/apps/status.c
+++ b/apps/status.c
@@ -103,10 +103,10 @@ int current_playmode(void)
#ifdef CONFIG_TUNER
audio_stat = get_radio_status();
- if(audio_stat == FMRADIO_PLAYING)
+ if(audio_stat & FMRADIO_PLAYING)
return STATUS_RADIO;
- if(audio_stat == FMRADIO_PAUSED)
+ if(audio_stat & FMRADIO_PAUSED)
return STATUS_RADIO_PAUSE;
#endif
diff --git a/apps/talk.c b/apps/talk.c
index cf68cdf021..21c6f4bb1a 100644
--- a/apps/talk.c
+++ b/apps/talk.c
@@ -554,6 +554,7 @@ int talk_buffer_steal(void)
}
#endif
reset_state();
+
return 0;
}
@@ -728,6 +729,7 @@ int talk_value(long n, int unit, bool enqueue)
VOICE_PIXEL,
VOICE_PER_SEC,
VOICE_HERTZ,
+ VOICE_KBIT_PER_SEC,
};
#if CONFIG_CODEC != SWCODEC
diff --git a/apps/talk.h b/apps/talk.h
index 0dc6996f39..2f2099a8c4 100644
--- a/apps/talk.h
+++ b/apps/talk.h
@@ -41,6 +41,7 @@ enum {
UNIT_PER_SEC, /* per second */
UNIT_HERTZ, /* hertz */
UNIT_MB, /* Megabytes */
+ UNIT_KBIT, /* kilobits per sec */
UNIT_LAST /* END MARKER */
};
diff --git a/apps/tree.c b/apps/tree.c
index 4558cd59a4..2d9b1bf7b4 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -577,7 +577,7 @@ static bool dirbrowse(void)
if (global_settings.rec_startup) {
/* We fake being in the menu structure by calling
the appropriate parent when we drop out of each screen */
- recording_screen();
+ recording_screen(false);
rec_menu();
main_menu();
}
diff --git a/firmware/drivers/power.c b/firmware/drivers/power.c
index 67f34e2f30..d5b75a130d 100644
--- a/firmware/drivers/power.c
+++ b/firmware/drivers/power.c
@@ -38,7 +38,7 @@ bool charger_enabled;
static bool powered = false;
-bool radio_powered()
+bool radio_powered(void)
{
return powered;
}
diff --git a/firmware/export/audio.h b/firmware/export/audio.h
index 9e3499e81f..2ee7f89dbd 100644
--- a/firmware/export/audio.h
+++ b/firmware/export/audio.h
@@ -31,6 +31,9 @@
#define AUDIO_STATUS_PRERECORD 8
#define AUDIO_STATUS_ERROR 16
+#define AUDIO_STATUS_STAYON_FLAGS \
+ (AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE | AUDIO_STATUS_RECORD | AUDIO_)
+
#define AUDIOERR_DISK_FULL 1
#define AUDIO_GAIN_LINEIN 0
@@ -69,6 +72,7 @@ void audio_resume(void);
void audio_next(void);
void audio_prev(void);
int audio_status(void);
+bool audio_query_poweroff(void);
int audio_track_count(void); /* SWCODEC only */
void audio_pre_ff_rewind(void); /* SWCODEC only */
void audio_ff_rewind(long newtime);
@@ -93,14 +97,56 @@ void audio_stop_recording(void);
void audio_pause_recording(void);
void audio_resume_recording(void);
void audio_new_file(const char *filename);
+
+/* audio sources */
+enum
+{
+ AUDIO_SRC_PLAYBACK = -1, /* for audio playback (default) */
+ AUDIO_SRC_MIC, /* monitor mic */
+ AUDIO_SRC_LINEIN, /* monitor line in */
+#ifdef HAVE_SPDIF_IN
+ AUDIO_SRC_SPDIF, /* monitor spdif */
+#endif
+#if defined(HAVE_FMRADIO_IN) || defined(CONFIG_TUNER)
+ AUDIO_SRC_FMRADIO, /* monitor fm radio */
+#endif
+ /* define new audio sources above this line */
+ AUDIO_SOURCE_LIST_END,
+ /* AUDIO_SRC_FMRADIO must be declared #ifdef CONFIG_TUNER but is not in
+ the list of recordable sources. HAVE_FMRADIO_IN implies CONFIG_TUNER. */
+#if defined(HAVE_FMRADIO_IN) || !defined(CONFIG_TUNER)
+ AUDIO_NUM_SOURCES = AUDIO_SOURCE_LIST_END,
+#else
+ AUDIO_NUM_SOURCES = AUDIO_SOURCE_LIST_END-1,
+#endif
+ AUDIO_SRC_MAX = AUDIO_NUM_SOURCES-1
+};
+
+/* channel modes */
+enum
+{
+ CHN_MODE_MONO = 1,
+ CHN_MODE_STEREO,
+};
void audio_set_recording_options(int frequency, int quality,
int source, int channel_mode,
bool editable, int prerecord_time);
void audio_set_recording_gain(int left, int right, int type);
unsigned long audio_recorded_time(void);
unsigned long audio_num_recorded_bytes(void);
+#if 0
+#ifdef HAVE_SPDIF_POWER
void audio_set_spdif_power_setting(bool on);
+#endif
+#endif
unsigned long audio_get_spdif_sample_rate(void);
+#if CONFIG_CODEC == SWCODEC
+/* audio encoder functions (defined in playback.c) */
+int audio_get_encoder_id(void);
+void audio_load_encoder(int enc_id);
+void audio_remove_encoder(void);
+#endif /* CONFIG_CODEC == SWCODEC */
+
diff --git a/firmware/export/config-h100.h b/firmware/export/config-h100.h
index c21c8a1dcd..8f936866cc 100644
--- a/firmware/export/config-h100.h
+++ b/firmware/export/config-h100.h
@@ -135,6 +135,9 @@
/* Someone with H100 and BDM, please verify if this works. */
/* #define HAVE_EEPROM */
+/* Define this for FM radio input available (not for SIMULATOR) */
+#define HAVE_FMRADIO_IN
+
#endif /* !SIMULATOR */
/* Define this for S/PDIF input available */
diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h
index 5ff567cae4..4ac4b2b699 100644
--- a/firmware/export/config-h120.h
+++ b/firmware/export/config-h120.h
@@ -132,6 +132,9 @@
/* Define this if the EEPROM chip is used */
#define HAVE_EEPROM_SETTINGS
+/* Define this for FM radio input available (not for SIMULATOR) */
+#define HAVE_FMRADIO_IN
+
#endif /* !SIMULATOR */
/* Define this for S/PDIF input available */
diff --git a/firmware/export/config-h300.h b/firmware/export/config-h300.h
index d5c54d858f..c9c0b04bcb 100644
--- a/firmware/export/config-h300.h
+++ b/firmware/export/config-h300.h
@@ -140,4 +140,7 @@
/* Define this if there is an EEPROM chip */
#define HAVE_EEPROM
+/* Define this for FM radio input available (not for SIMULATOR) */
+#define HAVE_FMRADIO_IN
+
#endif /* SIMULATOR */
diff --git a/firmware/export/config-iaudiox5.h b/firmware/export/config-iaudiox5.h
index 8a2ed7a29d..d5c67c0a1c 100644
--- a/firmware/export/config-iaudiox5.h
+++ b/firmware/export/config-iaudiox5.h
@@ -17,6 +17,7 @@
/* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN
+
/* define this if you have access to the pitchscreen */
#define HAVE_PITCHSCREEN
@@ -81,6 +82,9 @@
should be defined as well. */
#define HAVE_LCD_SLEEP
+/* Define this for FM radio input available (not for SIMULATOR) */
+#define HAVE_FMRADIO_IN
+
/* Define this if you have a Motorola SCF5250 */
#define CONFIG_CPU MCF5250
diff --git a/firmware/export/fmradio.h b/firmware/export/fmradio.h
index 3c55fb7672..73113237c0 100644
--- a/firmware/export/fmradio.h
+++ b/firmware/export/fmradio.h
@@ -20,6 +20,22 @@
#ifndef FMRADIO_H
#define FMRADIO_H
+/** declare some stuff here so powermgmt.c can properly tell if the radio is
+ actually playing and not just paused. This break in heirarchy is allowed
+ for audio_status(). **/
+
+/* set when radio is playing or paused within fm radio screen */
+#define FMRADIO_OFF 0x0
+#define FMRADIO_PLAYING 0x1
+#define FMRADIO_PAUSED 0x2
+
+/* returns the IN flag */
+#define FMRADIO_IN_SCREEN(s) ((s) & FMRADIO_IN_FLAG)
+#define FMRADIO_STATUS_PLAYING(s) ((s) & FMRADIO_PLAYING_OUT)
+#define FMRADIO_STATUS_PAUSED(s) ((s) & FMRADIO_PAUSED_OUT)
+
+extern int get_radio_status(void);
+
extern int fmradio_read(int addr);
extern void fmradio_set(int addr, int data);
diff --git a/firmware/export/id3.h b/firmware/export/id3.h
index 7930cd9b70..dc58178d50 100644
--- a/firmware/export/id3.h
+++ b/firmware/export/id3.h
@@ -24,7 +24,6 @@
#include "file.h"
/* Audio file types. */
-/* NOTE: When adding new audio types, also add to codec_labels[] in id3.c */
enum {
AFMT_UNKNOWN = 0, /* Unknown file format */
@@ -46,9 +45,48 @@ enum {
/* New formats must be added to the end of this list */
- AFMT_NUM_CODECS
+ AFMT_NUM_CODECS,
+
+#if CONFIG_CODEC == SWCODEC
+ /* masks to decompose parts */
+ CODEC_AFMT_MASK = 0x0fff,
+ CODEC_TYPE_MASK = 0x7000,
+
+ /* switch for specifying codec type when requesting a filename */
+ CODEC_TYPE_DECODER = (0 << 12), /* default */
+ CODEC_TYPE_ENCODER = (1 << 12)
+#endif
};
+#if CONFIG_CODEC == SWCODEC
+#define AFMT_ENTRY(label, codec_fname, codec_enc_fname, enc_ext) \
+ { label, codec_fname, codec_enc_fname, enc_ext }
+#else
+#define AFMT_ENTRY(label, codec_fname, codec_enc_fname, enc_ext) \
+ { label }
+#endif
+
+/* record describing the audio format */
+struct afmt_entry
+{
+#if CONFIG_CODEC == SWCODEC
+ char label[8]; /* format label */
+ char *codec_fn; /* filename of decoder codec */
+ char *codec_enc_fn; /* filename of encoder codec */
+ char *ext; /* default extension for file (enc only for now) */
+#else
+ char label[4];
+#endif
+};
+
+/* database of labels and codecs. add formats per above enum */
+extern const struct afmt_entry audio_formats[AFMT_NUM_CODECS];
+
+#if CONFIG_CODEC == SWCODEC
+/* recording quality to AFMT_* */
+extern const int rec_quality_info_afmt[9];
+#endif
+
struct mp3entry {
char path[MAX_PATH];
char* title;
diff --git a/firmware/export/pcm_record.h b/firmware/export/pcm_record.h
index 5e2d7b7929..b217335340 100644
--- a/firmware/export/pcm_record.h
+++ b/firmware/export/pcm_record.h
@@ -20,10 +20,22 @@
#ifndef PCM_RECORD_H
#define PCM_RECORD_H
+void enc_set_parameters(int chunk_size, int num_chunks,
+ int samp_per_chunk, char *head_ptr, int head_size,
+ int enc_id);
+void enc_get_inputs(int *buffer_size, int *channels, int *quality);
+unsigned int* enc_alloc_chunk(void);
+void enc_free_chunk(void);
+int enc_wavbuf_near_empty(void);
+char* enc_get_wav_data(int size);
+extern void (*enc_set_header_callback)(void *head_buffer, int head_size,
+ int num_pcm_samples, bool is_file_header);
+
unsigned long pcm_rec_status(void);
void pcm_rec_init(void);
void pcm_rec_mux(int source);
-
+int pcm_rec_current_bitrate(void);
+int pcm_get_num_unprocessed(void);
void pcm_rec_get_peaks(int *left, int *right);
/* audio.h contains audio recording functions */
diff --git a/firmware/id3.c b/firmware/id3.c
index 35e0517769..3f2ba23684 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -85,28 +85,59 @@ static const char* const genres[] = {
"Synthpop"
};
-static const char* const codec_labels[] = {
- "???", /* Unknown file format */
-
- "MP1", /* MPEG Audio layer 1 */
- "MP2", /* MPEG Audio layer 2 */
- "MP3", /* MPEG Audio layer 3 */
-
+/* database of audio formats */
+const struct afmt_entry audio_formats[AFMT_NUM_CODECS] =
+{
+ /* Unknown file format */
+ AFMT_ENTRY("???", NULL, NULL, NULL ),
+ /* MPEG Audio layer 1 */
+ AFMT_ENTRY("MP1", "mpa.codec", NULL, NULL ),
+ /* MPEG Audio layer 2 */
+ AFMT_ENTRY("MP2", "mpa.codec", NULL, NULL ),
+ /* MPEG Audio layer 3 */
+ AFMT_ENTRY("MP3", "mpa.codec", "mp3_enc.codec", ".mp3"),
#if CONFIG_CODEC == SWCODEC
- "WAV", /* Uncompressed PCM in a WAV file */
- "Ogg", /* Ogg Vorbis */
- "FLAC", /* FLAC */
- "MPC", /* Musepack */
- "AC3", /* A/52 (aka AC3) audio */
- "WV", /* WavPack */
- "ALAC", /* Apple Lossless Audio Codec */
- "AAC", /* Advanced Audio Coding in M4A container */
- "SHN", /* Shorten */
- "AIFF", /* Audio Interchange File Format */
- "SID", /* SID File Format */
+ /* Uncompressed PCM in a WAV file */
+ AFMT_ENTRY("WAV", "wav.codec", "wav_enc.codec", ".wav"),
+ /* Ogg Vorbis */
+ AFMT_ENTRY("Ogg", "vorbis.codec", NULL, NULL ),
+ /* FLAC */
+ AFMT_ENTRY("FLAC", "flac.codec", NULL, NULL ),
+ /* Musepack */
+ AFMT_ENTRY("MPC", "mpc.codec", NULL, NULL ),
+ /* A/52 (aka AC3) audio */
+ AFMT_ENTRY("AC3", "a52.codec", NULL, NULL ),
+ /* WavPack */
+ AFMT_ENTRY("WV", "wavpack.codec", "wavpack_enc.codec", ".wv" ),
+ /* Apple Lossless Audio Codec */
+ AFMT_ENTRY("ALAC", "alac.codec", NULL, NULL ),
+ /* Advanced Audio Coding in M4A container */
+ AFMT_ENTRY("AAC", "aac.codec", NULL, NULL ),
+ /* Shorten */
+ AFMT_ENTRY("SHN", "shorten.codec", NULL, NULL ),
+ /* Audio Interchange File Format */
+ AFMT_ENTRY("AIFF", "aiff.codec", NULL, NULL ),
+ /* SID File Format */
+ AFMT_ENTRY("SID", "sid.codec", NULL, NULL ),
#endif
};
+#if CONFIG_CODEC == SWCODEC
+/* recording quality to AFMT_* */
+const int rec_quality_info_afmt[9] =
+{
+ AFMT_MPA_L3, /* MPEG L3 64 kBit/s */
+ AFMT_MPA_L3, /* MPEG L3 96 kBit/s */
+ AFMT_MPA_L3, /* MPEG L3 128 kBit/s */
+ AFMT_MPA_L3, /* MPEG L3 160 kBit/s */
+ AFMT_MPA_L3, /* MPEG L3 192 kBit/s */
+ AFMT_MPA_L3, /* MPEG L3 224 kBit/s */
+ AFMT_MPA_L3, /* MPEG L3 320 kBit/s */
+ AFMT_WAVPACK, /* WavPack 909 kBit/s */
+ AFMT_PCM_WAV, /* PCM Wav 1411 kBit/s */
+};
+#endif /* SWCODEC */
+
char* id3_get_genre(const struct mp3entry* id3)
{
if( id3->genre_string )
@@ -119,8 +150,8 @@ char* id3_get_genre(const struct mp3entry* id3)
char* id3_get_codec(const struct mp3entry* id3)
{
- if (id3->codectype < sizeof(codec_labels)/sizeof(char*)) {
- return (char*)codec_labels[id3->codectype];
+ if (id3->codectype < AFMT_NUM_CODECS) {
+ return (char*)audio_formats[id3->codectype].label;
} else {
return NULL;
}
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 7034f3896b..df0cbbad12 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -2484,7 +2484,7 @@ void audio_set_recording_options(int frequency, int quality,
DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
- if(source == 0) /* Mic */
+ if(source == AUDIO_SRC_MIC)
{
/* Copy left channel to right (mono mode) */
mas_codec_writereg(8, 0x8000);
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index fee2bbd35b..4e4d5f25a0 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -50,6 +50,8 @@
#include "lcd.h"
#include "lcd-remote.h"
#include "pcm_playback.h"
+#include "sound.h"
+#include "id3.h"
#include "pcm_record.h"
extern int boost_counter; /* used for boost check */
@@ -57,43 +59,26 @@ extern int boost_counter; /* used for boost check */
/***************************************************************************/
static bool is_recording; /* We are recording */
-static bool is_stopping; /* Are we going to stop */
static bool is_paused; /* We have paused */
static bool is_error; /* An error has occured */
static unsigned long num_rec_bytes; /* Num bytes recorded */
static unsigned long num_file_bytes; /* Num bytes written to current file */
static int error_count; /* Number of DMA errors */
+static unsigned long num_pcm_samples; /* Num pcm samples written to current file */
-static long record_start_time; /* Value of current_tick when recording was started */
-static long pause_start_time; /* Value of current_tick when pause was started */
-static volatile int buffered_chunks; /* number of valid chunks in buffer */
-static unsigned int sample_rate; /* Sample rate at time of recording start */
-static int rec_source; /* Current recording source */
+static long record_start_time; /* current_tick when recording was started */
+static long pause_start_time; /* current_tick when pause was started */
+static unsigned int sample_rate; /* Sample rate at time of recording start */
+static int rec_source; /* Current recording source */
static int wav_file;
static char recording_filename[MAX_PATH];
-static bool init_done, close_done, record_done, stop_done, pause_done, resume_done, new_file_done;
+static volatile bool init_done, close_done, record_done;
+static volatile bool stop_done, pause_done, resume_done, new_file_done;
-static short peak_left, peak_right;
-
-/***************************************************************************/
-
-/*
- Some estimates:
- Normal recording rate: 44100 HZ * 4 = 176 KB/s
- Total buffer size: 32 MB / 176 KB/s = 181s before writing to disk
-*/
-
-#define CHUNK_SIZE 8192 /* Multiple of 4 */
-#define WRITE_THRESHOLD 250 /* (2 MB) Write when this many chunks (or less) until buffer full */
-
-#define GET_CHUNK(x) (short*)(&rec_buffer[CHUNK_SIZE*(x)])
-
-static unsigned int rec_buffer_offset;
-static unsigned char *rec_buffer; /* Circular recording buffer */
-static int num_chunks; /* Number of chunks available in rec_buffer */
+static int peak_left, peak_right;
#ifdef IAUDIO_X5
#define SET_IIS_PLAY(x) IIS1CONFIG = (x);
@@ -103,27 +88,71 @@ static int num_chunks; /* Number of chunks available in rec_buffer *
#define SET_IIS_REC(x) IIS1CONFIG = (x);
#endif
-/*
- Overrun occures when DMA needs to write a new chunk and write_index == read_index
- Solution to this is to optimize pcmrec_callback, use cpu_boost or save to disk
- more often.
-*/
-
-static int write_index; /* Current chunk the DMA is writing to */
-static int read_index; /* Oldest chunk that is not written to disk */
-static int read2_index; /* Latest chunk that has not been converted to little endian */
-static long pre_record_ticks; /* pre-record time expressed in ticks */
-static int pre_record_chunks; /* pre-record time expressed in chunks */
+/****************************************************************************
+ use 2 circular buffers of same size:
+ rec_buffer=DMA output buffer: chunks (8192 Bytes) of raw pcm audio data
+ enc_buffer=encoded audio buffer: storage for encoder output data
+
+ Flow:
+ 1. when entering recording_screen DMA feeds the ringbuffer rec_buffer
+ 2. if enough pcm data are available the encoder codec does encoding of pcm
+ chunks (4-8192 Bytes) into ringbuffer enc_buffer in codec_thread
+ 3. pcmrec_callback detects enc_buffer 'near full' and writes data to disk
+
+ Functions calls:
+ 1.main: codec_load_encoder(); start the encoder
+ 2.encoder: enc_get_inputs(); get encoder buffsize, mono/stereo, quality
+ 3.encoder: enc_set_parameters(); set the encoder parameters (max.chunksize)
+ 4.encoder: enc_get_wav_data(); get n bytes of unprocessed pcm data
+ 5.encoder: enc_wavbuf_near_empty();if true: reduce cpu_boost
+ 6.encoder: enc_alloc_chunk(); get a ptr to next enc chunk
+ 7.encoder: <process enc chunk> compress and store data to enc chunk
+ 8.encoder: enc_free_chunk(); inform main about chunk process finished
+ 9.encoder: repeat 4. to 8.
+ A.main: enc_set_header_callback(); create the current format header (file)
+****************************************************************************/
+#define NUM_CHUNKS 256 /* Power of 2 */
+#define CHUNK_SIZE 8192 /* Power of 2 */
+#define MAX_FEED_SIZE 20000 /* max pcm size passed to encoder */
+#define CHUNK_MASK (NUM_CHUNKS * CHUNK_SIZE - 1)
+#define WRITE_THRESHOLD (44100 * 5 / enc_samp_per_chunk) /* 5sec */
+#define GET_CHUNK(x) (long*)(&rec_buffer[x])
+#define GET_ENC_CHUNK(x) (long*)(&enc_buffer[enc_chunk_size*(x)])
+
+static int audio_enc_id; /* current encoder id */
+static unsigned char *rec_buffer; /* Circular recording buffer */
+static unsigned char *enc_buffer; /* Circular encoding buffer */
+static unsigned char *enc_head_buffer; /* encoder header buffer */
+static int enc_head_size; /* used size in header buffer */
+static int write_pos; /* Current chunk pos for DMA writing */
+static int read_pos; /* Current chunk pos for encoding */
+static long pre_record_ticks;/* pre-record time expressed in ticks */
+static int enc_wr_index; /* Current encoding chunk write index */
+static int enc_rd_index; /* Current encoding chunk read index */
+static int enc_chunk_size; /* maximum encoder chunk size */
+static int enc_num_chunks; /* number of chunks in ringbuffer */
+static int enc_buffer_size; /* encode buffer size */
+static int enc_channels; /* 1=mono 2=stereo */
+static int enc_quality; /* mp3: 64,96,128,160,192,320 kBit */
+static int enc_samp_per_chunk;/* pcm samples per encoder chunk */
+static bool wav_queue_empty; /* all wav chunks processed? */
+static unsigned long avrg_bit_rate; /* average bit rates from chunks */
+static unsigned long curr_bit_rate; /* cumulated bit rates from chunks */
+static unsigned long curr_chunk_cnt; /* number of processed chunks */
+
+void (*enc_set_header_callback)(void *head_buffer, int head_size,
+ int num_pcm_samples, bool is_file_header);
/***************************************************************************/
static struct event_queue pcmrec_queue;
-static long pcmrec_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
+static long pcmrec_stack[2*DEFAULT_STACK_SIZE/sizeof(long)];
static const char pcmrec_thread_name[] = "pcmrec";
static void pcmrec_thread(void);
static void pcmrec_dma_start(void);
static void pcmrec_dma_stop(void);
+static void close_wave(void);
/* Event IDs */
#define PCMREC_INIT 1 /* Enable recording */
@@ -144,10 +173,16 @@ static void pcmrec_dma_stop(void);
void pcm_rec_init(void)
{
queue_init(&pcmrec_queue);
- create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), pcmrec_thread_name);
+ create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack),
+ pcmrec_thread_name);
}
+int audio_get_encoder_id(void)
+{
+ return audio_enc_id;
+}
+
/* Initializes recording:
* - Set up the UDA1380/TLV320 for recording
* - Prepare for DMA transfers
@@ -155,13 +190,14 @@ void pcm_rec_init(void)
void audio_init_recording(unsigned int buffer_offset)
{
- rec_buffer_offset = buffer_offset;
+ (void)buffer_offset;
+
init_done = false;
queue_post(&pcmrec_queue, PCMREC_INIT, 0);
while(!init_done)
sleep_thread();
- wake_up_thread();
+ wake_up_thread();
}
void audio_close_recording(void)
@@ -171,7 +207,9 @@ void audio_close_recording(void)
while(!close_done)
sleep_thread();
- wake_up_thread();
+ wake_up_thread();
+
+ audio_remove_encoder();
}
unsigned long pcm_rec_status(void)
@@ -184,10 +222,17 @@ unsigned long pcm_rec_status(void)
ret |= AUDIO_STATUS_PAUSE;
if (is_error)
ret |= AUDIO_STATUS_ERROR;
+ if (!is_recording && pre_record_ticks && init_done && !close_done)
+ ret |= AUDIO_STATUS_PRERECORD;
return ret;
}
+int pcm_rec_current_bitrate(void)
+{
+ return avrg_bit_rate;
+}
+
unsigned long audio_recorded_time(void)
{
if (is_recording)
@@ -248,6 +293,8 @@ unsigned long audio_get_spdif_sample_rate(void)
}
#endif
+#if 0
+/* not needed atm */
#ifdef HAVE_SPDIF_POWER
static bool spdif_power_setting;
@@ -256,21 +303,18 @@ void audio_set_spdif_power_setting(bool on)
spdif_power_setting = on;
}
#endif
+#endif
/**
- * Sets the audio source
+ * Sets recording parameters
*
* This functions starts feeding the CPU with audio data over the I2S bus
- *
- * @param source 0=mic, 1=line-in, 2=spdif
*/
void audio_set_recording_options(int frequency, int quality,
int source, int channel_mode,
bool editable, int prerecord_time)
{
/* TODO: */
- (void)quality;
- (void)channel_mode;
(void)editable;
/* NOTE: Coldfire UDA based recording does not yet support anything other
@@ -278,69 +322,30 @@ void audio_set_recording_options(int frequency, int quality,
* based recording will overwrite this value with the proper sample rate in
* audio_record(), and will not be affected by this.
*/
- frequency = 44100;
+ frequency = 44100;
+ enc_quality = quality;
+ rec_source = source;
+ enc_channels = channel_mode == CHN_MODE_MONO ? 1 : 2;
pre_record_ticks = prerecord_time * HZ;
- pre_record_chunks = ((frequency * prerecord_time * 4)/CHUNK_SIZE)+1;
- if(pre_record_chunks >= (num_chunks-250))
- {
- /* we can't prerecord more than our buffersize minus treshold to write to disk! */
- pre_record_chunks = num_chunks-250;
- /* don't forget to recalculate that time! */
- pre_record_ticks = ((pre_record_chunks * CHUNK_SIZE)/(4*frequency)) * HZ;
- }
-
- //logf("pcmrec: src=%d", source);
- rec_source = source;
-#ifdef HAVE_SPDIF_POWER
- /* Check if S/PDIF output power should be switched off or on. NOTE: assumes
- both optical in and out is controlled by the same power source, which is
- the case on H1x0. */
- spdif_power_enable((source == 2) || spdif_power_setting);
-#endif
switch (source)
{
- /* mic */
- case 0:
- /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */
- DATAINCONTROL = 0xc020;
-
-#ifdef HAVE_UDA1380
- uda1380_enable_recording(true);
+ case AUDIO_SRC_MIC:
+ case AUDIO_SRC_LINEIN:
+#ifdef HAVE_FMRADIO_IN
+ case AUDIO_SRC_FMRADIO:
#endif
-#ifdef HAVE_TLV320
- tlv320_enable_recording(true);
-#endif
- break;
-
- /* line-in */
- case 1:
/* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */
DATAINCONTROL = 0xc020;
-
-#ifdef HAVE_UDA1380
- uda1380_enable_recording(false);
-#endif
-#ifdef HAVE_TLV320
- tlv320_enable_recording(false);
-#endif
break;
-#ifdef HAVE_SPDIF_IN
- /* SPDIF */
- case 2:
+
+#ifdef HAVE_SPDIF_IN
+ case AUDIO_SRC_SPDIF:
/* Int. when 6 samples in FIFO. PDIR2 source = ebu1RcvData */
DATAINCONTROL = 0xc038;
-#ifdef HAVE_SPDIF_POWER
- EBU1CONFIG = spdif_power_setting ? (1 << 2) : 0;
- /* Input source is EBUin1, Feed-through monitoring if desired */
-#else
- EBU1CONFIG = (1 << 2);
- /* Input source is EBUin1, Feed-through monitoring */
-#endif
- uda1380_disable_recording();
break;
-#endif
- }
+#endif /* HAVE_SPDIF_IN */
+ }
sample_rate = frequency;
@@ -349,7 +354,8 @@ void audio_set_recording_options(int frequency, int quality,
SET_IIS_PLAY(0x800); /* Reset before reprogram */
#ifdef HAVE_SPDIF_IN
- if (source == 2) {
+ if (source == AUDIO_SRC_SPDIF)
+ {
/* SCLK2 = Audioclk/4 (can't use EBUin clock), TXSRC = EBU1rcv, 64 bclk/wclk */
IIS2CONFIG = (6 << 12) | (7 << 8) | (4 << 2);
/* S/PDIF feed-through already configured */
@@ -367,6 +373,8 @@ void audio_set_recording_options(int frequency, int quality,
/* SCLK2 follow IIS1 (UDA clock), TXSRC = IIS1rcv, 64 bclk/wclk */
SET_IIS_PLAY( (8 << 12) | (4 << 8) | (4 << 2) );
#endif
+
+ audio_load_encoder(rec_quality_info_afmt[quality]);
}
@@ -380,10 +388,9 @@ void audio_set_recording_options(int frequency, int quality,
void audio_set_recording_gain(int left, int right, int type)
{
//logf("rcmrec: t=%d l=%d r=%d", type, left, right);
-#ifdef HAVE_UDA1380
+#if defined(HAVE_UDA1380)
uda1380_set_recvol(left, right, type);
-#endif
-#ifdef HAVE_TLV320
+#elif defined (HAVE_TLV320)
tlv320_set_recvol(left, right, type);
#endif
}
@@ -406,7 +413,7 @@ void audio_record(const char *filename)
recording_filename[MAX_PATH - 1] = 0;
#ifdef HAVE_SPDIF_IN
- if (rec_source == 2)
+ if (rec_source == AUDIO_SRC_SPDIF)
sample_rate = audio_get_spdif_sample_rate();
#endif
@@ -447,6 +454,7 @@ void audio_stop_recording(void)
logf("pcm_stop");
+ is_paused = true; /* fix pcm write ptr at current position */
stop_done = false;
queue_post(&pcmrec_queue, PCMREC_STOP, 0);
@@ -499,9 +507,9 @@ void audio_resume_recording(void)
void pcm_rec_get_peaks(int *left, int *right)
{
if (left)
- *left = (int)peak_left;
+ *left = peak_left;
if (right)
- *right = (int)peak_right;
+ *right = peak_right;
peak_left = 0;
peak_right = 0;
}
@@ -511,7 +519,7 @@ void pcm_rec_get_peaks(int *left, int *right)
/***************************************************************************/
/**
- * Process the chunks using read_index and write_index.
+ * Process the chunks
*
* This function is called when queue_get_w_tmo times out.
*
@@ -519,70 +527,24 @@ void pcm_rec_get_peaks(int *left, int *right)
* they want to save everything in the buffers to disk.
*
*/
-
-static void pcmrec_callback(bool flush) ICODE_ATTR;
static void pcmrec_callback(bool flush)
{
- int num_ready, num_free, num_new;
- short *ptr;
- short value;
- int i, j, w;
-
- w = write_index;
-
- num_new = w - read2_index;
- if (num_new < 0)
- num_new += num_chunks;
-
- for (i=0; i<num_new; i++)
- {
- /* Convert the samples to little-endian so we only have to write later
- (Less hd-spinning time), also do peak detection while we're at it
- */
- ptr = GET_CHUNK(read2_index);
- for (j=0; j<CHUNK_SIZE/4; j++)
- {
- value = *ptr;
- if(value > peak_left)
- peak_left = value;
- else if (-value > peak_left)
- peak_left = -value;
-
- *ptr = htole16(value);
- ptr++;
-
- value = *ptr;
- if(value > peak_right)
- peak_right = value;
- else if (-value > peak_right)
- peak_right = -value;
-
- *ptr = htole16(value);
- ptr++;
- }
+ int i, num_ready, size_yield;
+ long *enc_chunk, chunk_size;
- if(is_recording && !is_paused)
- num_rec_bytes += CHUNK_SIZE;
-
- read2_index++;
- if (read2_index >= num_chunks)
- read2_index = 0;
- }
-
- if ((!is_recording || is_paused) && !flush)
- {
- /* not recording = no saving to disk, fake buffer clearing */
- read_index = write_index;
+ if (!is_recording && !flush)
return;
- }
- num_ready = w - read_index;
+ num_ready = enc_wr_index - enc_rd_index;
if (num_ready < 0)
- num_ready += num_chunks;
+ num_ready += enc_num_chunks;
- num_free = num_chunks - num_ready;
-
- if (num_free <= WRITE_THRESHOLD || flush)
+ /* calculate an estimate of recorded bytes */
+ num_rec_bytes = num_file_bytes + num_ready * /* enc_chunk_size */
+ ((avrg_bit_rate * 1000 / 8 * enc_samp_per_chunk + 22050) / 44100);
+
+ /* near full state reached: less than 5sec remaining space */
+ if (enc_num_chunks - num_ready < WRITE_THRESHOLD || flush)
{
bool must_boost = (boost_counter ? false : true);
@@ -591,23 +553,41 @@ static void pcmrec_callback(bool flush)
if(must_boost)
cpu_boost(true);
+ size_yield = 0;
for (i=0; i<num_ready; i++)
{
- if (write(wav_file, GET_CHUNK(read_index), CHUNK_SIZE) != CHUNK_SIZE)
+ enc_chunk = GET_ENC_CHUNK(enc_rd_index);
+ chunk_size = *enc_chunk++;
+
+ /* safety net: if size entry got corrupted => limit */
+ if (chunk_size > (long)(enc_chunk_size - sizeof(long)))
+ chunk_size = enc_chunk_size - sizeof(long);
+
+ if (enc_set_header_callback != NULL)
+ enc_set_header_callback(enc_chunk, enc_chunk_size,
+ num_pcm_samples, false);
+
+ if (write(wav_file, enc_chunk, chunk_size) != chunk_size)
{
+ close_wave();
if(must_boost)
cpu_boost(false);
logf("pcmrec: write err");
- pcmrec_dma_stop();
- return;
+ is_error = true;
+ break;
}
-
- num_file_bytes += CHUNK_SIZE;
-
- read_index++;
- if (read_index >= num_chunks)
- read_index = 0;
- yield();
+
+ num_file_bytes += chunk_size;
+ num_pcm_samples += enc_samp_per_chunk;
+ size_yield += chunk_size;
+
+ if (size_yield >= 32768)
+ { /* yield when 32kB written */
+ size_yield = 0;
+ yield();
+ }
+
+ enc_rd_index = (enc_rd_index + 1) % enc_num_chunks;
}
if(must_boost)
@@ -623,36 +603,33 @@ static void pcmrec_callback(bool flush)
/* Abort dma transfer */
static void pcmrec_dma_stop(void)
{
- DCR1 = 0;
-
- is_error = true;
- is_recording = false;
-
+ DCR1 = 0;
+
error_count++;
-
+
+ DSR1 = 1; /* Clear interrupt */
+ IPR |= (1<<15); /* Clear pending interrupt request */
+
logf("dma1 stopped");
}
static void pcmrec_dma_start(void)
{
- DAR1 = (unsigned long)GET_CHUNK(write_index); /* Destination address */
- SAR1 = (unsigned long)&PDIR2; /* Source address */
- BCR1 = CHUNK_SIZE; /* Bytes to transfer */
+ DAR1 = (unsigned long)GET_CHUNK(write_pos); /* Destination address */
+ SAR1 = (unsigned long)&PDIR2; /* Source address */
+ BCR1 = CHUNK_SIZE; /* Bytes to transfer */
/* Start the DMA transfer.. */
- DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
-
#ifdef HAVE_SPDIF_IN
INTERRUPTCLEAR = 0x03c00000;
#endif
- /* pre-recording: buffer count */
- buffered_chunks = 0;
+ /* 16Byte transfers prevents from sporadic errors during cpu_boost() */
+ DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_DSIZE(3) | DMA_START;
logf("dma1 started");
}
-
/* DMA1 Interrupt is called when the DMA has finished transfering a chunk */
void DMA1(void) __attribute__ ((interrupt_handler, section(".icode")));
void DMA1(void)
@@ -668,62 +645,64 @@ void DMA1(void)
logf("dma1 err: 0x%x", res);
- DAR1 = (unsigned long)GET_CHUNK(write_index); /* Destination address */
+ DAR1 = (unsigned long)GET_CHUNK(write_pos); /* Destination address */
BCR1 = CHUNK_SIZE;
DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
+
+ /* Flush recorded data to disk and stop recording */
+ queue_post(&pcmrec_queue, PCMREC_STOP, NULL);
}
#ifdef HAVE_SPDIF_IN
- else if ((rec_source == 2) && (INTERRUPTSTAT & 0x01c00000)) /* valnogood, symbolerr, parityerr */
+ else if ((rec_source == AUDIO_SRC_SPDIF) &&
+ (INTERRUPTSTAT & 0x01c00000)) /* valnogood, symbolerr, parityerr */
{
INTERRUPTCLEAR = 0x03c00000;
error_count++;
logf("spdif err");
- if (is_stopping)
- {
- DCR1 = 0; /* Stop DMA transfer */
- is_stopping = false;
-
- logf("dma1 stopping");
- }
- else
- {
- DAR1 = (unsigned long)GET_CHUNK(write_index); /* Destination address */
- BCR1 = CHUNK_SIZE;
- }
+ DAR1 = (unsigned long)GET_CHUNK(write_pos); /* Destination address */
+ BCR1 = CHUNK_SIZE;
}
#endif
else
{
- write_index++;
- if (write_index >= num_chunks)
- write_index = 0;
+ long peak_l, peak_r;
+ long *ptr, j;
- /* update number of valid chunks for pre-recording */
- if(buffered_chunks < num_chunks)
- buffered_chunks++;
+ ptr = GET_CHUNK(write_pos);
- if (is_stopping)
- {
- DCR1 = 0; /* Stop DMA transfer */
- is_stopping = false;
+ if (!is_paused) /* advance write position */
+ write_pos = (write_pos + CHUNK_SIZE) & CHUNK_MASK;
- logf("dma1 stopping");
- }
- else if (write_index == read_index)
- {
- DCR1 = 0; /* Stop DMA transfer */
- is_recording = false;
+ DAR1 = (unsigned long)GET_CHUNK(write_pos); /* Destination address */
+ BCR1 = CHUNK_SIZE;
- logf("dma1 overrun");
+ peak_l = peak_r = 0;
- }
- else
+ /* only peak every 4th sample */
+ for (j=0; j<CHUNK_SIZE/4; j+=4)
{
- DAR1 = (unsigned long)GET_CHUNK(write_index); /* Destination address */
- BCR1 = CHUNK_SIZE;
+ long value = ptr[j];
+#ifdef ROCKBOX_BIG_ENDIAN
+ if (value > peak_l) peak_l = value;
+ else if (-value > peak_l) peak_l = -value;
+
+ value <<= 16;
+ if (value > peak_r) peak_r = value;
+ else if (-value > peak_r) peak_r = -value;
+#else
+ if (value > peak_r) peak_r = value;
+ else if (-value > peak_r) peak_r = -value;
+
+ value <<= 16;
+ if (value > peak_l) peak_l = value;
+ else if (-value > peak_l) peak_l = -value;
+#endif
}
+
+ peak_left = (int)(peak_l >> 16);
+ peak_right = (int)(peak_r >> 16);
}
IPR |= (1<<15); /* Clear pending interrupt request */
@@ -733,15 +712,8 @@ void DMA1(void)
/* Sets returns 0 if success, -1 on failure */
static int start_wave(void)
{
- unsigned char header[44] =
- {
- 'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',
- 0x10,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,
- 4,0,0x10,0,'d','a','t','a',0,0,0,0
- };
- unsigned long avg_bytes_per_sec;
-
wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC);
+
if (wav_file < 0)
{
wav_file = -1;
@@ -749,19 +721,9 @@ static int start_wave(void)
is_error = true;
return -1;
}
- /* Now set the sample rate field of the WAV header to what it should be */
- header[24] = (unsigned char)(sample_rate & 0xff);
- header[25] = (unsigned char)(sample_rate >> 8);
- header[26] = (unsigned char)(sample_rate >> 16);
- header[27] = (unsigned char)(sample_rate >> 24);
- /* And then the average bytes per second field */
- avg_bytes_per_sec = sample_rate*4; /* Hard coded to 16 bit stereo */
- header[28] = (unsigned char)(avg_bytes_per_sec & 0xff);
- header[29] = (unsigned char)(avg_bytes_per_sec >> 8);
- header[30] = (unsigned char)(avg_bytes_per_sec >> 16);
- header[31] = (unsigned char)(avg_bytes_per_sec >> 24);
- if (sizeof(header) != write(wav_file, header, sizeof(header)))
+ /* add main file header (enc_head_size=0 for encoders without) */
+ if (enc_head_size != write(wav_file, enc_head_buffer, enc_head_size))
{
close(wav_file);
wav_file = -1;
@@ -776,18 +738,22 @@ static int start_wave(void)
/* Update header and set correct length values */
static void close_wave(void)
{
- long l;
+ unsigned char head[100]; /* assume maximum 100 bytes for file header */
+ int size_read;
if (wav_file != -1)
{
- l = htole32(num_file_bytes + 36);
- lseek(wav_file, 4, SEEK_SET);
- write(wav_file, &l, 4);
-
- l = htole32(num_file_bytes);
- lseek(wav_file, 40, SEEK_SET);
- write(wav_file, &l, 4);
-
+ /* update header before closing the file (wav+wv encoder will do) */
+ if (enc_set_header_callback != NULL)
+ {
+ lseek(wav_file, 0, SEEK_SET);
+ /* try to read the head size (but we'll accept less) */
+ size_read = read(wav_file, head, sizeof(head));
+
+ enc_set_header_callback(head, size_read, num_pcm_samples, true);
+ lseek(wav_file, 0, SEEK_SET);
+ write(wav_file, head, size_read);
+ }
close(wav_file);
wav_file = -1;
}
@@ -795,8 +761,7 @@ static void close_wave(void)
static void pcmrec_start(void)
{
- int pre_chunks = pre_record_chunks; /* recalculate every time! */
- long pre_ticks = pre_record_ticks; /* recalculate every time! */
+ long max_pre_chunks, pre_ticks, max_pre_ticks;
logf("pcmrec_start");
@@ -808,7 +773,7 @@ static void pcmrec_start(void)
}
if (wav_file != -1)
- close(wav_file);
+ close_wave();
if (start_wave() != 0)
{
@@ -817,32 +782,29 @@ static void pcmrec_start(void)
return;
}
- /* pre-recording calculation */
- if(buffered_chunks < pre_chunks)
- {
- /* not enough good chunks available - limit pre-record time */
- pre_chunks = buffered_chunks;
- pre_ticks = ((buffered_chunks * CHUNK_SIZE)/(4*sample_rate)) * HZ;
- }
- record_start_time = current_tick - pre_ticks;
+ /* calculate maximum available chunks & resulting ticks */
+ max_pre_chunks = (enc_wr_index - enc_rd_index +
+ enc_num_chunks) % enc_num_chunks;
+ if (max_pre_chunks > enc_num_chunks - WRITE_THRESHOLD)
+ max_pre_chunks = enc_num_chunks - WRITE_THRESHOLD;
+ max_pre_ticks = max_pre_chunks * HZ * enc_samp_per_chunk / 44100;
- read_index = write_index - pre_chunks;
- if(read_index < 0)
- {
- read_index += num_chunks;
- }
+ /* limit prerecord if not enough data available */
+ pre_ticks = pre_record_ticks > max_pre_ticks ?
+ max_pre_ticks : pre_record_ticks;
+ max_pre_chunks = 44100 * pre_ticks / HZ / enc_samp_per_chunk;
+ enc_rd_index = (enc_wr_index - max_pre_chunks +
+ enc_num_chunks) % enc_num_chunks;
- peak_left = 0;
- peak_right = 0;
-
- num_rec_bytes = pre_chunks * CHUNK_SIZE;
+ record_start_time = current_tick - pre_ticks;
+
+ num_rec_bytes = enc_num_chunks * CHUNK_SIZE;
num_file_bytes = 0;
+ num_pcm_samples = 0;
pause_start_time = 0;
- is_stopping = false;
is_paused = false;
is_recording = true;
-
record_done = true;
}
@@ -850,36 +812,24 @@ static void pcmrec_stop(void)
{
logf("pcmrec_stop");
- if (!is_recording)
+ if (is_recording)
{
- stop_done = true;
- return;
- }
-
- if (!is_paused)
- {
- /* wait for recording to finish */
- is_stopping = true;
-
- while (is_stopping && is_recording)
+ /* wait for encoding finish */
+ is_paused = true;
+ while(!wav_queue_empty)
sleep_thread();
- wake_up_thread();
-
- is_stopping = false;
- }
-
- is_recording = false;
-
- /* Flush buffers to file */
- pcmrec_callback(true);
- close_wave();
+ wake_up_thread();
+ is_recording = false;
+ /* Flush buffers to file */
+ pcmrec_callback(true);
+ close_wave();
+ }
+
+ is_paused = false;
stop_done = true;
-
- /* Finally start dma again for peakmeters and pre-recoding to work. */
- pcmrec_dma_start();
-
+
logf("pcmrec_stop done");
}
@@ -898,7 +848,6 @@ static void pcmrec_new_file(void)
here is a good approximation when recording to the new file starts
*/
record_start_time = current_tick;
- num_rec_bytes = 0;
if (is_paused)
pause_start_time = record_start_time;
@@ -908,7 +857,9 @@ static void pcmrec_new_file(void)
close_wave();
+ num_rec_bytes = 0;
num_file_bytes = 0;
+ num_pcm_samples = 0;
/* start the new file */
if (start_wave() != 0)
@@ -932,20 +883,8 @@ static void pcmrec_pause(void)
return;
}
- /* Abort DMA transfer and flush to file? */
-
- is_stopping = true;
-
- while (is_stopping && is_recording)
- sleep_thread();
- wake_up_thread();
-
pause_start_time = current_tick;
- is_paused = true;
-
- /* Flush what we got in buffers to file */
- pcmrec_callback(true);
-
+ is_paused = true;
pause_done = true;
logf("pcmrec_pause done");
@@ -973,10 +912,7 @@ static void pcmrec_resume(void)
pause_start_time = 0;
}
- pcmrec_dma_start();
-
resume_done = true;
-
logf("pcmrec_resume done");
}
@@ -986,50 +922,47 @@ static void pcmrec_resume(void)
*/
static void pcmrec_init(void)
{
- unsigned long buffer_size;
-
wav_file = -1;
- read_index = 0;
- read2_index = 0;
- write_index = 0;
- pre_record_chunks = 0;
- pre_record_ticks = 0;
+ read_pos = 0;
+ write_pos = 0;
+ enc_wr_index = 0;
+ enc_rd_index = 0;
+
+ avrg_bit_rate = 0;
+ curr_bit_rate = 0;
+ curr_chunk_cnt = 0;
peak_left = 0;
peak_right = 0;
num_rec_bytes = 0;
num_file_bytes = 0;
+ num_pcm_samples = 0;
record_start_time = 0;
pause_start_time = 0;
- buffered_chunks = 0;
-
+
+ close_done = false;
is_recording = false;
- is_stopping = false;
is_paused = false;
is_error = false;
- rec_buffer = (unsigned char*)(((unsigned long)audiobuf + rec_buffer_offset) & ~3);
- buffer_size = (long)audiobufend - (long)audiobuf - rec_buffer_offset - 16;
-
- logf("buf size: %d kb", buffer_size/1024);
-
- num_chunks = buffer_size / CHUNK_SIZE;
-
- logf("num_chunks: %d", num_chunks);
+ rec_buffer = (unsigned char*)(((long)audiobuf + 15) & ~15);
+ enc_buffer = rec_buffer + NUM_CHUNKS * CHUNK_SIZE + MAX_FEED_SIZE;
+ /* 8000Bytes at audiobufend */
+ enc_buffer_size = audiobufend - enc_buffer - 8000;
- SET_IIS_PLAY(0x800); /* Stop any playback */
- AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */
- DATAINCONTROL = 0xc000; /* Generate Interrupt when 6 samples in fifo */
+ SET_IIS_PLAY(0x800); /* Stop any playback */
+ AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */
+ DATAINCONTROL = 0xc000; /* Generate Interrupt when 6 samples in fifo */
- DIVR1 = 55; /* DMA1 is mapped into vector 55 in system.c */
- DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */
+ DIVR1 = 55; /* DMA1 is mapped into vector 55 in system.c */
+ DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */
DMAROUTE = (DMAROUTE & 0xffff00ff) | DMA1_REQ_AUDIO_2;
- ICR7 = 0x1c; /* Enable interrupt at level 7, priority 0 */
- IMR &= ~(1<<15); /* bit 15 is DMA1 */
+ ICR7 = 0x1c; /* Enable interrupt at level 7, priority 0 */
+ IMR &= ~(1<<15); /* bit 15 is DMA1 */
#ifdef HAVE_SPDIF_IN
- PHASECONFIG = 0x34; /* Gain = 3*2^13, source = EBUIN */
+ PHASECONFIG = 0x34; /* Gain = 3*2^13, source = EBUIN */
#endif
pcmrec_dma_start();
@@ -1038,23 +971,16 @@ static void pcmrec_init(void)
static void pcmrec_close(void)
{
-#ifdef HAVE_UDA1380
- uda1380_disable_recording();
-#endif
-#ifdef HAVE_TLV320
- tlv320_disable_recording();
-#endif
-
-#ifdef HAVE_SPDIF_POWER
- spdif_power_enable(spdif_power_setting);
-#endif
DMAROUTE = (DMAROUTE & 0xffff00ff);
ICR7 = 0x00; /* Disable interrupt */
IMR |= (1<<15); /* bit 15 is DMA1 */
+ pcmrec_dma_stop();
+
/* Reset PDIR2 data flow */
DATAINCONTROL = 0x200;
close_done = true;
+ init_done = false;
}
static void pcmrec_thread(void)
@@ -1064,10 +990,10 @@ static void pcmrec_thread(void)
logf("thread pcmrec start");
error_count = 0;
-
- while (1)
+
+ while(1)
{
- queue_wait_w_tmo(&pcmrec_queue, &ev, HZ / 40);
+ queue_wait_w_tmo(&pcmrec_queue, &ev, HZ / 4);
switch (ev.id)
{
@@ -1104,8 +1030,9 @@ static void pcmrec_thread(void)
break;
case SYS_USB_CONNECTED:
- if (!is_recording && !is_stopping)
+ if (!is_recording)
{
+ pcmrec_close();
usb_acknowledge(SYS_USB_CONNECTED_ACK);
usb_wait_for_disconnect(&pcmrec_queue);
}
@@ -1148,3 +1075,102 @@ void pcm_rec_mux(int source)
/* iAudio x5 */
#endif
}
+
+
+/****************************************************************************/
+/* */
+/* following functions will be called by the encoder codec */
+/* */
+/****************************************************************************/
+
+/* pass the encoder buffer pointer/size, mono/stereo, quality to the encoder */
+void enc_get_inputs(int *buffer_size, int *channels, int *quality)
+{
+ *buffer_size = enc_buffer_size;
+ *channels = enc_channels;
+ *quality = enc_quality;
+}
+
+/* set the encoder dimensions (called by encoder codec at initialization) */
+void enc_set_parameters(int chunk_size, int num_chunks, int samp_per_chunk,
+ char *head_ptr, int head_size, int enc_id)
+{
+ /* set read_pos just in front of current write_pos */
+ read_pos = (write_pos - CHUNK_SIZE) & CHUNK_MASK;
+
+ enc_rd_index = 0; /* reset */
+ enc_wr_index = 0; /* reset */
+ enc_chunk_size = chunk_size; /* max chunk size */
+ enc_num_chunks = num_chunks; /* total number of chunks */
+ enc_samp_per_chunk = samp_per_chunk; /* pcm samples / encoderchunk */
+ enc_head_buffer = head_ptr; /* optional file header data (wav) */
+ enc_head_size = head_size; /* optional file header data (wav) */
+ audio_enc_id = enc_id; /* AFMT_* id */
+}
+
+/* allocate encoder chunk */
+unsigned int *enc_alloc_chunk(void)
+{
+ return (unsigned int*)(enc_buffer + enc_wr_index * enc_chunk_size);
+}
+
+/* free previously allocated encoder chunk */
+void enc_free_chunk(void)
+{
+ unsigned long *enc_chunk;
+
+ enc_chunk = GET_ENC_CHUNK(enc_wr_index);
+ curr_chunk_cnt++;
+/* curr_bit_rate += *enc_chunk * 44100 * 8 / (enc_samp_per_chunk * 1000); */
+ curr_bit_rate += *enc_chunk * 441 * 8 / (enc_samp_per_chunk * 10 );
+ avrg_bit_rate = (curr_bit_rate + curr_chunk_cnt / 2) / curr_chunk_cnt;
+
+ /* advance enc_wr_index to the next chunk */
+ enc_wr_index = (enc_wr_index + 1) % enc_num_chunks;
+
+ /* buffer full: advance enc_rd_index (for prerecording purpose) */
+ if (enc_rd_index == enc_wr_index)
+ {
+ enc_rd_index = (enc_rd_index + 1) % enc_num_chunks;
+ }
+}
+
+/* checks near empty state on wav input buffer */
+int enc_wavbuf_near_empty(void)
+{
+ /* less than 1sec raw data? => unboost encoder */
+ if (((write_pos - read_pos) & CHUNK_MASK) < 44100*4)
+ return 1;
+ else
+ return 0;
+}
+
+/* passes a pointer to next chunk of unprocessed wav data */
+char *enc_get_wav_data(int size)
+{
+ char *ptr;
+ int avail;
+
+ /* limit the requested pcm data size */
+ if(size > MAX_FEED_SIZE)
+ size = MAX_FEED_SIZE;
+
+ avail = (write_pos - read_pos) & CHUNK_MASK;
+
+ if (avail >= size)
+ {
+ ptr = rec_buffer + read_pos;
+ read_pos = (read_pos + size) & CHUNK_MASK;
+
+ /* ptr must point to continous data at wraparound position */
+ if (read_pos < size)
+ memcpy(rec_buffer + NUM_CHUNKS * CHUNK_SIZE,
+ rec_buffer, read_pos);
+
+ wav_queue_empty = false;
+ return ptr;
+ }
+
+ wav_queue_empty = true;
+ return NULL;
+}
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 3dd4c607a2..377c34a628 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -424,6 +424,7 @@ static void battery_status_update(void)
* 1) The USB is connected
* 2) The charger is connected
* 3) We are recording, or recording with pause
+ * 4) The radio is playing
*/
static void handle_auto_poweroff(void)
{
@@ -442,7 +443,7 @@ static void handle_auto_poweroff(void)
if(timeout &&
#ifdef CONFIG_TUNER
- (!radio_powered()) &&
+ (!(get_radio_status() & FMRADIO_PLAYING)) &&
#endif
!usb_inserted() &&
((audio_stat == 0) ||