From 4fc717a4c19a1fe0349977d7b9c86561c5a5cf2d Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 28 Aug 2006 22:38:41 +0000 Subject: 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 --- apps/codecs.c | 25 +- apps/codecs.h | 24 +- apps/codecs/Makefile | 3 + apps/codecs/SOURCES | 8 + apps/codecs/mp3_enc.c | 2860 +++++++++++++++++++++++++++++++++++++ apps/codecs/wav_enc.c | 172 +++ apps/codecs/wavpack_enc.c | 230 +++ apps/filetree.c | 5 +- apps/lang/english.lang | 17 + apps/main_menu.c | 26 +- apps/playback.c | 215 +-- apps/playback.h | 5 +- apps/recorder/radio.c | 380 ++--- apps/recorder/radio.h | 12 +- apps/recorder/recording.c | 578 +++++--- apps/recorder/recording.h | 27 +- apps/settings.c | 29 +- apps/settings.h | 1 + apps/sound_menu.c | 78 +- apps/status.c | 4 +- apps/talk.c | 2 + apps/talk.h | 1 + apps/tree.c | 2 +- firmware/drivers/power.c | 2 +- firmware/export/audio.h | 46 + firmware/export/config-h100.h | 3 + firmware/export/config-h120.h | 3 + firmware/export/config-h300.h | 3 + firmware/export/config-iaudiox5.h | 4 + firmware/export/fmradio.h | 16 + firmware/export/id3.h | 42 +- firmware/export/pcm_record.h | 14 +- firmware/id3.c | 71 +- firmware/mpeg.c | 2 +- firmware/pcm_record.c | 736 +++++----- firmware/powermgmt.c | 3 +- 36 files changed, 4796 insertions(+), 853 deletions(-) create mode 100644 apps/codecs/mp3_enc.c create mode 100644 apps/codecs/wav_enc.c create mode 100644 apps/codecs/wavpack_enc.c 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; chpart2_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; itable_select[0], ix+i, xr+i); + + for( ; itable_select[1], ix+i, xr+i); + + for( ; itable_select[2], ix+i, xr+i); + + /* 2: Write count1 area */ + count1End = bigvalues + (gi->count1 << 2); + for(i=bigvalues; itable_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 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 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; ihlen[(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> 8) & 0xff00ff) | ((t << 8) & 0xff00ff00); + } + } + else + { + /* mix left/right, swap byte order & copy to destination */ + for (i=0; i>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> 16; + input_buffer[2*i + 1] = (short)t; + } + } + else + { + for (i=0; i>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" +<<<<<<< english.lang + + id: VOICE_KBIT_PER_SEC + desc: spoken only, for file extension + user: + + *: "" + + + *: "" + + + *: "kilobits per second" + + +======= id: LANG_RECORD_AGC_PRESET desc: automatic gain control in record settings @@ -9778,3 +9794,4 @@ *: "AGC maximum gain" +>>>>>>> 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 : ""); + + 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 #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: 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 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 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 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) || -- cgit v1.2.3